Skip to main content

rumtk_core/
mem.rs

1/*
2 *     rumtk attempts to implement HL7 and medical protocols for interoperability in medicine.
3 *     This toolkit aims to be reliable, simple, performant, and standards compliant.
4 *     Copyright (C) 2026  Luis M. Santos, M.D. <lsantos@medicalmasses.com>
5 *     Copyright (C) 2026  MedicalMasses L.L.C. <contact@medicalmasses.com>
6 *
7 *     This program is free software: you can redistribute it and/or modify
8 *     it under the terms of the GNU General Public License as published by
9 *     the Free Software Foundation, either version 3 of the License, or
10 *     (at your option) any later version.
11 *
12 *     This program is distributed in the hope that it will be useful,
13 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *     GNU General Public License for more details.
16 *
17 *     You should have received a copy of the GNU General Public License
18 *     along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 */
20use crate::base::RUMVec;
21use crate::cpu::CPU_SIMD_64_SIZE;
22use crate::strings::RUMString;
23/////////////////If using MiMalloc//////////////////////////////
24#[cfg(all(feature = "mimalloc", feature = "default"))]
25use mimalloc::MiMalloc;
26
27#[cfg(all(feature = "mimalloc", feature = "default"))]
28#[global_allocator]
29static GLOBAL: MiMalloc = MiMalloc;
30
31////////////////////////Traits//////////////////////////////////
32pub trait AsPtr {
33    #[inline(always)]
34    fn as_ptr(&self) -> *const u8 {
35        self as *const _ as *const u8
36    }
37    #[inline(always)]
38    fn as_mut_ptr(&mut self) -> *mut u8 {
39        self as *mut _ as *mut u8
40    }
41}
42
43impl AsPtr for [u8] { }
44impl AsPtr for &[u8] { }
45impl AsPtr for RUMVec<u8> { }
46impl AsPtr for &RUMVec<u8> { }
47impl AsPtr for RUMString { }
48
49pub trait SizedType {
50    #[inline(always)]
51    fn size(&self) -> usize;
52}
53
54impl SizedType for [u8] { fn size(&self) -> usize { self.len() } }
55impl SizedType for &[u8] { fn size(&self) -> usize { self.len() } }
56impl SizedType for RUMVec<u8> { fn size(&self) -> usize { self.len() } }
57impl SizedType for &RUMVec<u8> { fn size(&self) -> usize { self.len() } }
58impl SizedType for RUMString { fn size(&self) -> usize { self.len() } }
59
60pub trait AsSlice: AsPtr + SizedType {
61    #[inline(always)]
62    fn as_slice(&self) -> &[u8] { as_slice(self.as_ptr(),  self.size()) }
63    #[inline(always)]
64    fn as_slice_mut(&mut self) -> &mut [u8] {  as_slice_mut(self.as_mut_ptr(),  self.size()) }
65
66    #[inline(always)]
67    fn contains(&self, x: &u8) -> bool {
68        self.as_slice().contains(x)
69    }
70}
71
72impl AsSlice for [u8] { }
73impl AsSlice for &[u8] { }
74impl AsSlice for RUMVec<u8> { }
75impl AsSlice for &RUMVec<u8> { }
76impl AsSlice for RUMString { }
77
78#[inline]
79pub fn as_slice<'a>(src: *const u8, size: usize) -> &'a [u8] {
80    unsafe { std::slice::from_raw_parts(src, size) }
81}
82
83#[inline]
84pub fn as_slice_mut<'a>(src: *mut u8, size: usize) -> &'a mut [u8] {
85    unsafe { std::slice::from_raw_parts_mut(src, size) }
86}
87
88#[macro_export]
89macro_rules! rumtk_mem_quick_array_init {
90    ( $typ:ty, $size:expr ) => {{
91        const DATA_SLICE_LEN: usize = $size * size_of::<$typ>();
92        let arr: [$typ; $size] = unsafe { mem::transmute([0u8; DATA_SLICE_LEN]) };
93        arr
94    }}
95}
96
97/////////////////////////////Copy///////////////////////////////////
98#[inline]
99pub fn copy_simd_slice<'a, const LANE_SIZE: usize>(src: &[u8], mut dst: &'a mut [u8]) -> &'a mut [u8] {
100    let (prefix, middle, postfix) = src.as_simd::<LANE_SIZE>();
101    let prefix_len = prefix.len();
102    let postfix_len = postfix.len();
103
104    dst[..prefix_len].copy_from_slice(prefix);
105    dst = &mut dst[prefix_len..];
106
107    for chunk in middle.into_iter() {
108        chunk.copy_to_slice(&mut dst[..LANE_SIZE]);
109        dst = &mut dst[LANE_SIZE..];
110    }
111
112    dst[..postfix_len].copy_from_slice(postfix);
113    dst
114}
115
116#[inline]
117pub fn copy_from_slice<'a>(src: &[u8], dst: &'a mut [u8]) -> &'a mut [u8] {
118    debug_assert!(src.len() <= dst.len(), "Destination memory slice is smaller than source! This is a bug near the call site of copy_from_slice!");
119    copy_simd_slice::<CPU_SIMD_64_SIZE>(
120        src,
121        dst,
122    )
123}