Advertisement
Guest User

Untitled

a guest
Jul 7th, 2018
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.57 KB | None | 0 0
  1. use core::array::FixedSizeArray;
  2. use core::marker::Unsize;
  3. use core::ops::CoerceUnsized;
  4. use std::ptr;
  5. use std::mem;
  6. use std::ops::{Deref, DerefMut};
  7.  
  8. pub struct Direct<T, B: FixedSizeArray<u8>> {
  9. ptr: *mut T,
  10. buffer: B
  11. }
  12. impl<T, B: FixedSizeArray<u8>> Direct<T, B> {
  13. pub fn new(elem: T) -> Self {
  14. unsafe {
  15. let mut direct = Direct::<T, B> {
  16. ptr: ptr::null_mut(),
  17. buffer: mem::uninitialized()
  18. };
  19. if mem::size_of::<T>() > direct.buffer.as_slice().len() {
  20. // it can't fit, so store it on the heap
  21. direct.ptr = Box::into_raw(Box::new(elem));
  22. } else {
  23. // it can fit, so move it into the buffer
  24. ptr::write(&mut direct.buffer.as_mut_slice()[0] as *mut u8 as *mut T, elem);
  25. }
  26. direct
  27. }
  28. }
  29. }
  30. impl<T, B: FixedSizeArray<u8>> Deref for Direct<T, B> {
  31. type Target = T;
  32.  
  33. fn deref(&self) -> &<Self as Deref>::Target {
  34. unsafe {
  35. if self.ptr.is_null() {
  36. &*(&self.buffer.as_slice()[0] as *const u8 as *const T)
  37. } else {
  38. &*self.ptr
  39. }
  40. }
  41. }
  42. }
  43. impl<T, B: FixedSizeArray<u8>> DerefMut for Direct<T, B> {
  44. fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
  45. unsafe {
  46. if self.ptr.is_null() {
  47. &mut*(&mut self.buffer.as_mut_slice()[0] as *mut u8 as *mut T)
  48. } else {
  49. &mut*self.ptr
  50. }
  51. }
  52. }
  53. }
  54. impl<T, B: FixedSizeArray<u8>> Drop for Direct<T, B> {
  55. fn drop(&mut self) {
  56. unsafe {
  57. if self.ptr.is_null() {
  58. ptr::drop_in_place(&mut self.buffer.as_mut_slice()[0] as *mut u8 as *mut T);
  59. } else {
  60. mem::drop(Box::from_raw(self.ptr))
  61. }
  62. }
  63. }
  64. }
  65.  
  66. #[cfg(test)]
  67. pub mod tests {
  68. use super::*;
  69.  
  70. #[test]
  71. pub fn fat_ptr_large_test() {
  72. let mut arr = [0u8; 100];
  73. for i in 0..100 {
  74. arr[i] = i as u8;
  75. }
  76. let direct: Direct<[u8; 100], [u8; 20]> = Direct::new(arr.clone());
  77. for i in 0..100 {
  78. assert_eq!(arr[i], direct[i]);
  79. }
  80. }
  81.  
  82. #[test]
  83. pub fn fat_ptr_small_test() {
  84. let mut arr = [0u8; 20];
  85. for i in 0..20 {
  86. arr[i] = i as u8;
  87. }
  88. let direct: Direct<[u8; 20], [u8; 100]> = Direct::new(arr.clone());
  89. for i in 0..20 {
  90. assert_eq!(arr[i], direct[i]);
  91. }
  92. }
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement