1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
#![feature(const_fn, const_transmute)]

use std::ops::Deref;

/// FFI-safe slices.
pub mod slice;
/// FFI-safe string slices.
pub mod str;
/// FFI-safe vectors.
pub mod vec;

/// Utility struct to "freeze" a `T`. Immutable access is allowed but mutable access is not.
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Frozen<T>(T);

display!(Frozen<;T>); debug!(Frozen<;T>);

impl<T> Deref for Frozen<T> {
	type Target = T;

	fn deref(&self) -> &T {
		&self.0
	}
}

impl<T> Frozen<T> {
	/// Wrap a value, making it immutable.
	pub const fn new(x: T) -> Self {
		Self(x)
	}

	/// Bypasses immutability and gets the inner `T`. Don't do this please.
	pub unsafe fn into_inner(self) -> T {
		self.0
	}

	/// Bypasses immutability and gets a mutable reference. Don't do this please.
	pub const unsafe fn get_mut(&mut self) -> &mut T {
		std::mem::transmute(self)
	}
}

#[macro_export]
macro_rules! display {
	($s:ident $(< $($lyarg:lifetime),* ; $($tyarg:ident),* >)?) => {
		impl $(< $($lyarg,)* $($tyarg : ::std::fmt::Display),* >)? ::std::fmt::Display for $s $(< $($lyarg,)* $($tyarg),* >)? {
			fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
				::std::fmt::Display::fmt(&**self, f)
			}
		}
	};
}

#[macro_export]
macro_rules! debug {
	($s:ident $(< $($lyarg:lifetime),* ; $($tyarg:ident),* >)?) => {
		impl $(< $($lyarg,)* $($tyarg : ::std::fmt::Debug),* >)? ::std::fmt::Debug for $s $(< $($lyarg,)* $($tyarg),* >)? {
			fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
				::std::fmt::Debug::fmt(&**self, f)
			}
		}
	};
}

#[macro_export]
macro_rules! from {
	($s:ident $(< $($lyarg:lifetime),* ; $($tyarg:ident),* >)? => $s2:ty; $f:ident) => {
		impl $(< $($lyarg,)* $($tyarg),* >)? ::std::convert::From<$s $(< $($lyarg,)* $($tyarg),* >)?> for $s2 {
			fn from(x: $s $(< $($lyarg,)* $($tyarg),* >)?) -> Self {
				x . $f ()
			}
		}
	};
}

#[macro_export]
macro_rules! copyclone {
	($s:ident $(< $($lyarg:lifetime),* ; $($tyarg:ident),* >)?) => {
		impl $(< $($lyarg,)* $($tyarg),* >)? ::std::marker::Copy for $s $(< $($lyarg,)* $($tyarg),* >)? {}
		impl $(< $($lyarg,)* $($tyarg),* >)? ::std::clone::Clone for $s $(< $($lyarg,)* $($tyarg),* >)? {
			fn clone(&self) -> Self {
				*self
			}
		}
	}
}

#[macro_export]
macro_rules! rawparts {
	($s:ident $(< $($lyarg:lifetime),* ; $($tyarg:ident),* >)? ; $($aname:ident : $aty:ty),* $(; $($tt:tt)*)?) => {
		impl $(< $($lyarg,)* $($tyarg),* >)? $s $(< $($lyarg,)* $($tyarg),* >)? {
			pub unsafe fn from_raw_parts($($aname : $aty),*) -> Self {
				Self {
					$($aname,)*
					$($($tt)*)?
				}
			}

			pub fn into_raw_parts(self) -> ($($aty),*) {
				($(self . $aname),*)
			}
		}
	};
}