Skip to main content

diskann_wide/
lifetime.rs

1/*
2 * Copyright (c) Microsoft Corporation.
3 * Licensed under the MIT license.
4 */
5
6//! Tools to pass objects with lifetimes across the function pointer API.
7//!
8//! Useful helpers include
9//!
10//! * [`As`]: Feed through the generic parameter unaltered with no lifetime.
11//! * [`Ref`]: Pass an argument through a shared reference.
12//! * [`Mut`]: Pass an argument through an exclusive reference.
13//!
14//! Common primitives like integers and floating point numbers pass through by value.
15
16use std::marker::PhantomData;
17
18/// A lifetime annotator for the function pointer API of [`crate::Architecture`].
19///
20/// This mainly works around limitations in the Rust compiler's ability to infer the proper
21/// lifetimes of dispatched function pointers.
22pub trait AddLifetime: 'static {
23    /// The type with a lifetime (if any).
24    type Of<'a>;
25}
26
27macro_rules! self_lifetime {
28    ($T:ty) => {
29        impl $crate::lifetime::AddLifetime for $T {
30            type Of<'a> = $T;
31        }
32    };
33    ($($Ts:ty),+ $(,)?) => {
34        $(self_lifetime!($Ts);)+
35    }
36}
37
38self_lifetime!(
39    bool,
40    u8,
41    u16,
42    u32,
43    u64,
44    i8,
45    i16,
46    i32,
47    i64,
48    usize,
49    half::f16,
50    f32,
51    f64,
52    String
53);
54
55/// An [`AddLifetime`] helper that passes `T` by value.
56#[derive(Debug)]
57pub struct As<T> {
58    _marker: PhantomData<T>,
59}
60
61impl<T> As<T> {
62    /// Construct a new instance of [`Self`].
63    pub fn new() -> Self {
64        Self {
65            _marker: PhantomData,
66        }
67    }
68}
69
70impl<T> Default for As<T> {
71    fn default() -> Self {
72        Self::new()
73    }
74}
75
76impl<T> Clone for As<T> {
77    fn clone(&self) -> Self {
78        *self
79    }
80}
81
82impl<T> Copy for As<T> {}
83
84impl<T> AddLifetime for As<T>
85where
86    T: 'static,
87{
88    type Of<'a> = T;
89}
90
91/// An [`AddLifetime`] helper that passes `&T`.
92#[derive(Debug)]
93pub struct Ref<T: ?Sized> {
94    _marker: PhantomData<T>,
95}
96
97impl<T: ?Sized> Ref<T> {
98    /// Construct a new instance of [`Self`].
99    pub fn new() -> Self {
100        Self {
101            _marker: PhantomData,
102        }
103    }
104}
105
106impl<T> Default for Ref<T> {
107    fn default() -> Self {
108        Self::new()
109    }
110}
111
112impl<T: ?Sized> Clone for Ref<T> {
113    fn clone(&self) -> Self {
114        *self
115    }
116}
117
118impl<T: ?Sized> Copy for Ref<T> {}
119
120impl<T> AddLifetime for Ref<T>
121where
122    T: ?Sized + 'static,
123{
124    type Of<'a> = &'a T;
125}
126
127/// An [`AddLifetime`] helper that passes `&mut T`.
128#[derive(Debug)]
129pub struct Mut<T: ?Sized> {
130    _marker: PhantomData<T>,
131}
132
133impl<T: ?Sized> Mut<T> {
134    /// Construct a new instance of [`Self`].
135    pub fn new() -> Self {
136        Self {
137            _marker: PhantomData,
138        }
139    }
140}
141
142impl<T> Default for Mut<T> {
143    fn default() -> Self {
144        Self::new()
145    }
146}
147
148impl<T: ?Sized> Clone for Mut<T> {
149    fn clone(&self) -> Self {
150        *self
151    }
152}
153
154impl<T: ?Sized> Copy for Mut<T> {}
155
156impl<T> AddLifetime for Mut<T>
157where
158    T: ?Sized + 'static,
159{
160    type Of<'a> = &'a mut T;
161}