open_cl_low_level/
cl_pointer.rs1use std::fmt;
2use std::marker::PhantomData;
3
4use crate::ffi::cl_bool;
5use crate::strings;
6
7#[repr(C)]
12pub struct ClPointer<T: Copy> {
13 count: usize,
14 ptr: *mut T,
15 phantom: PhantomData<T>,
16 is_consumed: bool,
17}
18
19impl ClPointer<u8> {
21 pub unsafe fn into_string(self) -> String {
22 strings::to_utf8_string(self.into_vec())
23 }
24}
25
26impl From<ClPointer<u8>> for String {
27 fn from(p: ClPointer<u8>) -> String {
28 strings::to_utf8_string(unsafe { p.into_vec() })
29 }
30}
31
32impl From<ClPointer<cl_bool>> for bool {
33 fn from(p: ClPointer<cl_bool>) -> bool {
34 match unsafe { p.into_one() } {
35 0 => false,
36 1 => true,
37 invalid_cl_bool => panic!("cl_bool was neither 0 nor 1: {:?}", invalid_cl_bool),
38 }
39 }
40}
41
42impl<T: Copy> ClPointer<T> {
43 pub unsafe fn new(count: usize, ptr: *mut T) -> ClPointer<T> {
44 ClPointer {
45 count,
46 ptr,
47 phantom: PhantomData,
48 is_consumed: false,
49 }
50 }
51
52 pub unsafe fn from_vec(mut v: Vec<T>) -> ClPointer<T> {
53 let ptr = v.as_mut_ptr();
54 let count = v.len();
55 std::mem::forget(v);
56 ClPointer::new(count, ptr)
57 }
58
59 pub unsafe fn new_empty() -> ClPointer<T> {
60 let mut v = vec![];
61 let ptr = v.as_mut_ptr();
62 std::mem::forget(v);
63 ClPointer::new(0, ptr)
64 }
65
66 pub fn is_empty(&self) -> bool {
67 self.count == 0
68 }
69
70 pub fn is_null(&self) -> bool {
71 self.ptr.is_null()
72 }
73
74 #[inline]
75 pub unsafe fn into_one(self) -> T {
76 self.ptr_cannot_be_null();
77 self.count_must_be_one();
78 let owned_ptr = self.ptr.to_owned();
79 std::mem::forget(self);
80 *owned_ptr
81 }
82
83 #[inline]
84 pub unsafe fn into_vec(self) -> Vec<T> {
85 self.ptr_cannot_be_null();
86 let many = Vec::from_raw_parts(self.ptr, self.count, self.count);
87 std::mem::forget(self);
88 many
89 }
90
91 #[inline]
92 fn ptr_cannot_be_null(&self) {
93 if self.ptr.is_null() {
94 panic!("Consumed cl_pointer was a null pointer {:?}", self);
95 }
96 }
97
98 #[inline]
99 fn count_must_be_one(&self) {
100 match self.count {
101 1 => (),
102 0 => {
103 panic!("cl_pointer was not 1 count: {:?}", self);
104 }
105 _ => {
106 panic!("cl_pointer was not 1 count: {:?}", self);
107 }
108 }
109 }
110}
111
112impl<T: Copy> Drop for ClPointer<T> {
113 fn drop(&mut self) {
114 panic_once!("An unconsumed ClPointer was allowed to drop. This would lead to a memory leak. All ClPointers must be consumed. {:?}", self);
115 }
116}
117
118impl<T: Copy> fmt::Debug for ClPointer<T> {
119 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120 write!(
121 f,
122 "ClPointer<[ptr: {:?}, count: {:?}, size_of_t: {:?}, is_consumed: {:?}]>",
123 self.ptr,
124 self.count,
125 std::mem::size_of::<T>(),
126 self.is_consumed
127 )
128 }
129}