glium::implement_buffer_content!
[−]
[src]
macro_rules! implement_buffer_content { (__as_item $i:item) => {$i}; (__impl $struct_name:ident [$($gs:tt)*]) => { implement_buffer_content! { __as_item unsafe impl<$($gs)*> $crate::buffer::Content for $struct_name<$($gs)*> { type Owned = Box<$struct_name<$($gs)*>>; #[inline] fn read<F, E>(size: usize, f: F) -> ::std::result::Result<Box<$struct_name<$($gs)*>>, E> where F: FnOnce(&mut $struct_name<$($gs)*>) -> ::std::result::Result<(), E> { use std::mem; assert!(<$struct_name as $crate::buffer::Content>::is_size_suitable(size)); let mut storage: Vec<u8> = Vec::with_capacity(size); unsafe { storage.set_len(size) }; let storage = storage.into_boxed_slice(); let mut storage: Box<$struct_name<$($gs)*>> = unsafe { mem::transmute(storage) }; try!(f(&mut storage)); Ok(storage) } #[inline] fn get_elements_size() -> usize { use std::mem; let fake_ptr: &$struct_name = unsafe { mem::transmute((0usize, 0usize)) }; mem::size_of_val(fake_ptr) } #[inline] fn to_void_ptr(&self) -> *const () { use std::mem; let (ptr, _): (*const (), usize) = unsafe { mem::transmute(self) }; ptr } #[inline] fn ref_from_ptr(ptr: *mut (), size: usize) -> Option<*mut $struct_name<$($gs)*>> { use std::mem; let fake_ptr: &$struct_name = unsafe { mem::transmute((0usize, 0usize)) }; let min_size = mem::size_of_val(fake_ptr); let fake_ptr: &$struct_name = unsafe { mem::transmute((0usize, 1usize)) }; let step = mem::size_of_val(fake_ptr) - min_size; if size < min_size { return None; } let variadic = size - min_size; if variadic % step != 0 { return None; } Some(unsafe { mem::transmute((ptr, (variadic / step) as usize)) }) } #[inline] fn is_size_suitable(size: usize) -> bool { use std::mem; let fake_ptr: &$struct_name = unsafe { mem::transmute((0usize, 0usize)) }; let min_size = mem::size_of_val(fake_ptr); let fake_ptr: &$struct_name = unsafe { mem::transmute((0usize, 1usize)) }; let step = mem::size_of_val(fake_ptr) - min_size; size > min_size && (size - min_size) % step == 0 } } } }; ($struct_name:ident,) => ( implement_buffer_content!($struct_name); ); ($struct_name:ident) => ( implement_buffer_content!(__impl $struct_name []); ); ($struct_name:ident <$t1:tt>) => ( implement_buffer_content!(__impl $struct_name [$t1]); ); }
Implements the glium::buffer::Content
trait for the given type.
Contrary to the other similar macros, this one doesn't require you pass the list of parameters.
Only use this macro on structs. Using it with anything else will result in a segfault.
Example
struct Data { data: [u32] } implement_buffer_content!(Data);