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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
//! Memory usage model.
//!
//! # Residents
//!
//! A memory `Resident` abstracts over the usage of a memory `Lease`, which
//! itself abstracts over the allocation and ownership semantics of a raw,
//! unsized memory block.
//!
//! The most commonly used `Resident` implementations include:
//! - __[`Box`]__: stores a single value in a raw memory block.
//! - __[`Buf`]__: stores a resizeable array of values in a raw memory block.
//! - __[`String`]__: stores a resizeable Unicode string in a raw memory block.
//!
//! `Lease` implementations that compose a `Resident` include:
//! - __[`Raw`]__: the exclusive owner of a relocatable, raw memory block,
//!   with resident metadata stored with the pointer.
//! - __[`Ptr`]__: the exclusive owner of a relocatable, raw memory block,
//!   with resident metadata stored within the allocation.
//! - __[`Mut`]__: a mutably dereferenceable strong owner of an unrelocatable,
//!   reference counted memory block.
//! - __[`Ref`]__: an immutably dereferenceable strong owner of an unrelocatable,
//!   reference counted memory block.
//! - __[`Hard`]__: an undereferenceable strong owner of a relocatable, reference
//!   counted memory block.
//! - __[`Soft`]__: an undereferenceable weak owner of a relocatable, reference
//!   counted memory block.
//!
//! [`Box`]: resident::Box
//! [`Buf`]: resident::Buf
//! [`String`]: resident::String
//!
//! [`Raw`]: lease::Raw
//! [`Ptr`]: lease::Ptr
//! [`Mut`]: lease::Mut
//! [`Ref`]: lease::Ref
//! [`Hard`]: lease::Hard
//! [`Soft`]: lease::Soft

use core::cmp::Ordering;
use core::fmt;
use core::hash::Hasher;
use crate::block::{Layout, LayoutError};
use crate::alloc::{Hold, HoldError};
use crate::lease::Lease;

mod r#box;
mod buf;
mod string;

pub use self::r#box::Box;
pub use self::buf::{Buf, BufHeader, BufLease, BufIter, BufDrain};
pub use self::string::{String, StringLease};

/// A type that can reside in a raw, unsized memory block. A memory `Resident`
/// abstracts over the usage of a memory `Lease`, which itself abstracts over
/// the allocation and ownership semantics of a raw, unsized memory block.
///
/// # Requirements
///
/// `Resident` implementation don't store data internally; they proxy all data
/// accesses through a passed-in `Lease`, which acts as the de facto `self`
/// argument for all `Resident` methods. A memory `Lease` grants its `Resident`
/// temporary access to a data pointer, of type `Data`, which may be a fat,
/// unsized pointer. A `Lease` also provides its `Resident` access to a sized
/// metadata pointer, of type `Meta`.
///
/// A `Lease` manages the lifetime, placement, and ownership semantics of its
/// data and metadata pointers. A `Lease` may alias or relocate those pointers
/// at any time, so long as it doesn't violate Rust's borrowing semantics.
///
/// A `Lease` delegates to its `Resident` to determine the size and alignment
/// of any leased memory blocks; a `Lease` cannot assume that the size of its
/// memory block equals the size of its `Resident`'s `*Data`.
///
/// For example, a `Box` uses the size of its pointed-to `data`, possibly via
/// a dynamically sized fat pointer, as the size of its memory block. Whereas
/// a `Buf` determines its memory block size by multiplying the static size
/// of its `Data` type by a capacity value stored in the `Lease`'s associated
/// metadata. Abstracting over these size and usage patterns is the primary
/// reason for `Resident`'s existence.
pub trait Resident {
    /// The type of pointed-to data stored in leased memory blocks. The size of
    /// leased memory blocks must be a positive multiple of the `Data` size.
    type Data: ?Sized;

    /// The type of metadata stored with leased memory blocks. `Meta` data must
    /// contain sufficient information to resolve the size of any resided-in
    /// memory `Lease`.
    type Meta;

    /// Returns the size in bytes of the `Resident` with the given `data` and `meta` data.
    unsafe fn resident_size(data: *mut Self::Data, meta: *mut Self::Meta) -> usize;

    /// Drops the `Resident` with the given `data` and `meta` data.
    unsafe fn resident_drop(data: *mut Self::Data, meta: *mut Self::Meta);
}

/// A type that can initialize a new memory `Lease` with a `Resident` value.
pub trait ResidentFromValue<L: Lease, T, M = ()>: Resident {
    /// Returns the memory layout for a resident with the given `data` and `meta` data.
    fn new_resident_layout(data: &T, meta: &M) -> Layout;

    /// Converts a `raw` pointer into a `Data` pointer for a resident with the
    /// given `data` and `meta` data.
    fn new_resident_ptr(raw: *mut u8, data: &T, meta: &M) -> *mut Self::Data;

    /// Initializes the `lease` with a resident from the given `data` and `meta` data.
    fn new_resident(lease: &mut L, data: T, meta: M);
}

/// A type that can initialize a new memory `Lease` with a `Resident` clone of a value.
pub trait ResidentFromClone<L: Lease, T: ?Sized, M = ()>: Resident {
    /// Returns the memory layout for a resident with a clone of the given `data` and `meta` data.
    fn new_resident_layout(data: &T, meta: &M) -> Layout;

    /// Converts a `raw` pointer into a `Data` pointer for a resident with a
    /// clone of the given `data` and `meta` data.
    fn new_resident_ptr(raw: *mut u8, data: &T, meta: &M) -> *mut Self::Data;

    /// Initializes the `lease` with a resident from a clone of the given `data` and `meta` data.
    fn new_resident(lease: &mut L, data: &T, meta: M);
}

/// A type that can initialize a new memory `Lease` with an unchecked `Resident` clone of a value.
pub trait ResidentFromCloneUnchecked<L: Lease, T: ?Sized, M = ()>: Resident {
    /// Returns the memory layout for a resident with a clone of the given `data` and `meta` data.
    fn new_resident_layout(data: &T, meta: &M) -> Layout;

    /// Converts a `raw` pointer into a `Data` pointer for a resident with a
    /// clone of the given `data` and `meta` data.
    fn new_resident_ptr(raw: *mut u8, data: &T, meta: &M) -> *mut Self::Data;

    /// Initializes the `lease` with a resident from a clone of the given `data` and `meta` data.
    fn new_resident(lease: &mut L, data: &T, meta: M);
}

/// A type that can initialize a new memory `Lease` with a `Resident` copy of a value.
pub trait ResidentFromCopy<L: Lease, T: ?Sized, M = ()>: Resident {
    /// Returns the memory layout for a resident with a copy of the given `data` and `meta` data.
    fn new_resident_layout(data: &T, meta: &M) -> Layout;

    /// Converts a `raw` pointer into a `Data` pointer for a resident with a
    /// copy of the given `data` and `meta` data.
    fn new_resident_ptr(raw: *mut u8, data: &T, meta: &M) -> *mut Self::Data;

    /// Initializes the `lease` with a resident from a copy of the given `data` and `meta` data.
    fn new_resident(lease: &mut L, data: &T, meta: M);
}

/// A type that can initialize a new memory `Lease` with an unchecked `Resident` copy of a value.
pub trait ResidentFromCopyUnchecked<L: Lease, T: ?Sized, M = ()>: Resident {
    /// Returns the memory layout for a resident with a copy of the given `data` and `meta` data.
    fn new_resident_layout(data: &T, meta: &M) -> Layout;

    /// Converts a `raw` pointer into a `Data` pointer for a resident with a
    /// copy of the given `data` and `meta` data.
    fn new_resident_ptr(raw: *mut u8, data: &T, meta: &M) -> *mut Self::Data;

    /// Initializes the `lease` with a resident from a copy of the given `data` and `meta` data.
    fn new_resident(lease: &mut L, data: &T, meta: M);
}

/// A type that can initialize a new memory `Lease` with an empty `Resident`.
pub trait ResidentFromEmpty<L: Lease, M = ()>: Resident {
    /// Returns the memory layout for an empty resident with the given `meta` data.
    fn new_resident_layout(meta: &M) -> Layout;

    /// Converts a `raw` pointer into a `Data` pointer for an empty resident
    /// with the given `meta` data.
    fn new_resident_ptr(raw: *mut u8, meta: &M) -> *mut Self::Data;

    /// Initializes the `lease` with an empty resident from the given `meta` data.
    fn new_resident(lease: &mut L, meta: M);
}

/// A type that can initialize a new memory `Lease` with a preallocated capacity,
/// and an empty `Resident`.
pub trait ResidentWithCapacity<L: Lease, M = ()>: Resident {
    /// Returns the memory layout for an empty resident with the given
    /// pre-allocated capacity and `meta` data.
    fn new_resident_layout(cap: usize, meta: &M) -> Result<Layout, LayoutError>;

    /// Converts a `raw` pointer into a `Data` pointer for an empty resident
    /// with the given preallocated capacity and `meta` data.
    fn new_resident_ptr(raw: *mut u8, cap: usize, meta: &M) -> *mut Self::Data;

    /// Initializes the `lease` with an empty resident from the given
    /// pre-allocated capacity and `meta` data.
    fn new_resident(lease: &mut L, cap: usize, meta: M);
}

/// An unwrappable `Resident` of a raw memory `Lease`.
pub trait ResidentUnwrap<L: Lease>: Resident {
    /// The type the resident unwraps to.
    type Target;

    /// Returns the unwrapped value for the resident of the given `lease`,
    /// leaving the `lease` in an uninitialized state.
    fn resident_unwrap(lease: &L) -> Self::Target;
}

/// An immutably dereferenceable `Resident` of a raw memory `Lease`.
pub trait ResidentDeref<L: Lease>: Resident {
    /// The type the resident dereferences to.
    type Target: ?Sized;

    /// Immutably dereferences the resident of the `lease`.
    fn resident_deref(lease: &L) -> &Self::Target;
}

/// A mutably dereferenceable resident of a raw memory `Lease`.
pub trait ResidentDerefMut<L: Lease>: ResidentDeref<L> {
    /// Mutably dereferences the resident of the `lease`.
    fn resident_deref_mut(lease: &mut L) -> &mut Self::Target;
}

/// An immutably referenceable `Resident` of a raw memory `Lease`.
pub trait ResidentAsRef<L: Lease, T: ?Sized>: Resident {
    /// Returns the resident of the `lease` as an immutable reference to type `T`.
    fn resident_as_ref(lease: &L) -> &T;
}

/// A mutably referenceable `Resident` of a raw memory `Lease`.
pub trait ResidentAsMut<L: Lease, T: ?Sized>: Resident {
    /// Returns the resident of the `lease` as a mutable reference to type `T`.
    fn resident_as_mut(lease: &mut L) -> &mut T;
}

/// An immutably indexed `Resident of a raw memory `Lease`.
pub trait ResidentIndex<L: Lease, Idx>: Resident {
    /// The type of values indexed by the resident for the parameterized `Idx` type.
    type Output: ?Sized;

    /// Returns an immutable reference to the value at the given `index` of the
    /// resident of the `lease`.
    fn resident_index(lease: &L, index: Idx) -> &Self::Output;
}

/// A mutably indexed `Resident of a raw memory `Lease`.
pub trait ResidentIndexMut<L: Lease, Idx>: ResidentIndex<L, Idx> {
    /// Returns a mutable reference to the value at the given `index` of the
    /// resident of the `lease`.
    fn resident_index_mut(lease: &mut L, index: Idx) -> &mut Self::Output;
}

/// A `+` operable `Resident` of a raw memory `Lease`.
pub trait ResidentAdd<L: Lease, Rhs = Self>: Resident {
    /// The resulting type of applying the `+` operator.
    type Output;

    /// Returns the addition of `rhs` to the resident of the `lease`.
    fn resident_add(lease: L, rhs: Rhs) -> Self::Output;
}

/// A `+=` operable `Resident` of a raw memory `Lease`.
pub trait ResidentAddAssign<L: Lease, Rhs = Self>: Resident {
    /// Adds `rhs` to the resident of the `lease`.
    fn resident_add_assign(lease: &mut L, rhs: Rhs);
}

/// A consuming iterable `Resident` of a raw memory `Lease`.
pub trait ResidentIntoIterator<L: Lease>: Resident {
    /// The type of element to iterator over.
    type Item;

    /// The type of iterator to return.
    type IntoIter: Iterator<Item=Self::Item>;

    /// Returns a new `Iterator` that consumes the elements of the `lease`.
    fn resident_into_iter(lease: L) -> Self::IntoIter;
}

/// An immutably iterable `Resident` of a raw memory `Lease`.
pub trait ResidentIntoRefIterator<'a, L: Lease>: Resident {
    /// The type of element to iterator over.
    type Item;

    /// The type of iterator to return.
    type IntoIter: Iterator<Item=Self::Item>;

    /// Returns a new `Iterator` that consumes the elements of the `lease`.
    fn resident_into_iter(lease: &'a L) -> Self::IntoIter;
}

/// A mutably iterable `Resident` of a raw memory `Lease`.
pub trait ResidentIntoMutIterator<'a, L: Lease>: Resident {
    /// The type of element to iterator over.
    type Item;

    /// The type of iterator to return.
    type IntoIter: Iterator<Item=Self::Item>;

    /// Returns a new `Iterator` that consumes the elements of the `lease`.
    fn resident_into_iter(lease: &'a mut L) -> Self::IntoIter;
}

/// A partially comparable `Resident` of a raw memory `Lease`.
pub trait ResidentPartialEq<L: Lease, T: ?Sized = L>: Resident {
    /// Returns `true` if the resident of the `lease` equals some `other` value.
    fn resident_eq(lease: &L, other: &T) -> bool;

    /// Returns `false` if the resident of the `lease` equals some `other` value.
    #[inline]
    fn resident_ne(lease: &L, other: &T) -> bool {
        !Self::resident_eq(lease, other)
    }
}

/// A comparable `Resident` of a raw memory `Lease`.
pub trait ResidentEq<L: Lease>: ResidentPartialEq<L> {
}

/// A partially ordered `Resident` of a raw memory `Lease`.
pub trait ResidentPartialOrd<L: Lease, T: ?Sized = L>: ResidentPartialEq<L, T> {
    /// Returns the ordering of the resident of the `lease` relative to some `other` value, if comparable.
    fn resident_partial_cmp(lease: &L, other: &T) -> Option<Ordering>;

    /// Returns `true` if the resident of the `lease` orders before some `other` value.
    #[inline]
    fn resident_lt(lease: &L, other: &T) -> bool {
        match Self::resident_partial_cmp(lease, other) {
            Some(Ordering::Less) => true,
            _ => false,
        }
    }

    /// Returns `true` if the resident of the `lease` orders before or the same as some `other` value.
    #[inline]
    fn resident_le(lease: &L, other: &T) -> bool {
        match Self::resident_partial_cmp(lease, other) {
            Some(Ordering::Less) | Some(Ordering::Equal) => true,
            _ => false,
        }
    }

    /// Returns `true` if the resident of the `lease` orders the same as or after some `other` value.
    #[inline]
    fn resident_ge(lease: &L, other: &T) -> bool {
        match Self::resident_partial_cmp(lease, other) {
            Some(Ordering::Greater) | Some(Ordering::Equal) => true,
            _ => false,
        }
    }

    /// Returns `true` if the resident of the `lease` orders after some `other` value.
    #[inline]
    fn resident_gt(lease: &L, other: &T) -> bool {
        match Self::resident_partial_cmp(lease, other) {
            Some(Ordering::Greater) => true,
            _ => false,
        }
    }
}

/// A totally ordered `Resident` of a raw memory `Lease`.
pub trait ResidentOrd<L: Lease>: ResidentEq<L> + ResidentPartialOrd<L> {
    /// Returns the relative ordering of the residents occupying the given leases.
    fn resident_cmp(lease: &L, other: &L) -> Ordering;

    #[inline]
    fn resident_lt(lease: &L, other: &L) -> bool {
        match Self::resident_cmp(lease, other) {
            Ordering::Less => true,
            _ => false,
        }
    }

    #[inline]
    fn resident_le(lease: &L, other: &L) -> bool {
        match Self::resident_cmp(lease, other) {
            Ordering::Less | Ordering::Equal => true,
            _ => false,
        }
    }

    #[inline]
    fn resident_ge(lease: &L, other: &L) -> bool {
        match Self::resident_cmp(lease, other) {
            Ordering::Greater | Ordering::Equal => true,
            _ => false,
        }
    }

    #[inline]
    fn resident_gt(lease: &L, other: &L) -> bool {
        match Self::resident_cmp(lease, other) {
            Ordering::Greater => true,
            _ => false,
        }
    }
}

/// A hashable `Resident` of a raw memory `Lease`.
pub trait ResidentHash<L: Lease>: Resident {
    /// Hashes the resident of the `lease`.
    fn resident_hash<H: Hasher>(lease: &L, state: &mut H);
}

/// A display-format-able `Resident` of a raw memory `Lease`.
pub trait ResidentDisplay<L: Lease>: Resident {
    /// Formats the resident of the `lease` for display.
    fn resident_fmt(lease: &L, f: &mut fmt::Formatter) -> fmt::Result;
}

/// A debug-format-able `Resident` of a raw memory `Lease`.
pub trait ResidentDebug<L: Lease>: Resident {
    /// Formats the resident of the `lease` for debugging.
    fn resident_fmt(lease: &L, f: &mut fmt::Formatter) -> fmt::Result;
}

/// A cloneable `Resident` of a raw memory `Lease`.
pub trait ResidentClone<L1: Lease, L2: Lease>: Resident {
    /// Returns the preferred memory layout of a clone destination for the
    /// resident of the `lease`.
    fn new_resident_layout(lease: &L1) -> Layout;

    /// Clones the resident of the `src` lease into the `dst` lease.
    fn resident_clone(src: &L1, dst: &mut L2) -> Result<(), HoldError>;
}

/// A relocatable `Resident` of a raw memory `Lease`.
pub trait ResidentStow<'b, L1: Lease, L2: Lease>: Resident {
    /// Returns the preferred memory layout of a move destination for the
    /// resident of the `lease`.
    fn new_resident_layout(lease: &L1) -> Layout;

    /// Relocates the resident from the `src` lease to the `dst` lease.
    /// Leaves the `src` lase in its original state on failure.
    unsafe fn resident_stow(src: &mut L1, dst: &mut L2, hold: &Hold<'b>) -> Result<(), HoldError>;

    /// Reverts the most recent `resident_stow` operation by relocating the
    /// resident of the `dst` lease back to the `src` lease.
    unsafe fn resident_unstow(src: &mut L1, dst: &mut L2);
}