Skip to content

Commit 7dfb3f4

Browse files
committed
Apply lifetimebound to the Vec API
1 parent 1d49b05 commit 7dfb3f4

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

subspace/containers/vec.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "subspace/iter/from_iterator.h"
2727
#include "subspace/iter/into_iterator.h"
2828
#include "subspace/macros/compiler.h"
29+
#include "subspace/macros/lifetimebound.h"
2930
#include "subspace/mem/move.h"
3031
#include "subspace/mem/relocate.h"
3132
#include "subspace/mem/replace.h"
@@ -93,6 +94,8 @@ class Vec {
9394
/// This is highly unsafe, due to the number of invariants that aren’t
9495
/// checked:
9596
///
97+
/// * `ptr` must be heap allocated through malloc() (TODO: Want our own global
98+
/// allocator API).
9699
/// * `T` needs to have an alignment no more than what `ptr` was allocated
97100
/// with.
98101
/// * The size of `T` times the `capacity` (ie. the allocated size in bytes)
@@ -372,7 +375,7 @@ class Vec {
372375
}
373376

374377
/// Returns a const reference to the element at index `i`.
375-
constexpr Option<const T&> get(usize i) const& noexcept {
378+
constexpr Option<const T&> get(usize i) const& noexcept sus_lifetimebound {
376379
check(!is_moved_from());
377380
if (i >= len_) [[unlikely]]
378381
return Option<const T&>::none();
@@ -381,7 +384,7 @@ class Vec {
381384
constexpr Option<const T&> get(usize i) && = delete;
382385

383386
/// Returns a mutable reference to the element at index `i`.
384-
constexpr Option<T&> get_mut(usize i) & noexcept {
387+
constexpr Option<T&> get_mut(usize i) & noexcept sus_lifetimebound {
385388
check(!is_moved_from());
386389
if (i >= len_) [[unlikely]]
387390
return Option<T&>::none();
@@ -399,7 +402,8 @@ class Vec {
399402
/// Additionally, the Vec must not be in a moved-from state or the pointer
400403
/// will be invalid and Undefined Behaviour results.
401404
constexpr inline const T& get_unchecked(::sus::marker::UnsafeFnMarker,
402-
usize i) const& noexcept {
405+
usize i) const& noexcept
406+
sus_lifetimebound {
403407
return storage_[i.primitive_value];
404408
}
405409
constexpr inline const T& get_unchecked(::sus::marker::UnsafeFnMarker,
@@ -411,7 +415,7 @@ class Vec {
411415
/// The index `i` must be inside the bounds of the array or Undefined
412416
/// Behaviour results.
413417
constexpr inline T& get_unchecked_mut(::sus::marker::UnsafeFnMarker,
414-
usize i) & noexcept {
418+
usize i) & noexcept sus_lifetimebound {
415419
return storage_[i.primitive_value];
416420
}
417421

@@ -420,14 +424,15 @@ class Vec {
420424
template <::sus::num::SignedPrimitiveInteger I>
421425
constexpr inline const T& operator[](I) const = delete;
422426

423-
constexpr inline const T& operator[](usize i) const& noexcept {
427+
constexpr inline const T& operator[](usize i) const& noexcept
428+
sus_lifetimebound {
424429
check(!is_moved_from());
425430
check(i < len_);
426431
return get_unchecked(::sus::marker::unsafe_fn, i);
427432
}
428433
constexpr inline const T& operator[](usize i) && = delete;
429434

430-
constexpr inline T& operator[](usize i) & noexcept {
435+
constexpr inline T& operator[](usize i) & noexcept sus_lifetimebound {
431436
check(!is_moved_from());
432437
check(i < len_);
433438
return get_unchecked_mut(::sus::marker::unsafe_fn, i);
@@ -459,7 +464,7 @@ class Vec {
459464
///
460465
/// # Panics
461466
/// Panics if the vector's capacity is zero.
462-
inline const T* as_ptr() const& noexcept {
467+
inline const T* as_ptr() const& noexcept sus_lifetimebound {
463468
check(!is_moved_from());
464469
check(is_alloced());
465470
return storage_;
@@ -470,15 +475,15 @@ class Vec {
470475
///
471476
/// # Panics
472477
/// Panics if the vector's capacity is zero.
473-
inline T* as_mut_ptr() & noexcept {
478+
inline T* as_mut_ptr() & noexcept sus_lifetimebound {
474479
check(!is_moved_from());
475480
check(is_alloced());
476481
return storage_;
477482
}
478483

479484
// Returns a slice that references all the elements of the vector as const
480485
// references.
481-
constexpr Slice<const T> as_slice() const& noexcept {
486+
constexpr Slice<const T> as_slice() const& noexcept sus_lifetimebound {
482487
check(!is_moved_from());
483488
// SAFETY: The `len_` is the number of elements in the Vec, and the pointer
484489
// is to the start of the Vec, so this Slice covers a valid range.
@@ -489,7 +494,7 @@ class Vec {
489494

490495
// Returns a slice that references all the elements of the vector as mutable
491496
// references.
492-
constexpr Slice<T> as_mut_slice() & noexcept {
497+
constexpr Slice<T> as_mut_slice() & noexcept sus_lifetimebound {
493498
check(!is_moved_from());
494499
// SAFETY: The `len_` is the number of elements in the Vec, and the pointer
495500
// is to the start of the Vec, so this Slice covers a valid range.
@@ -499,7 +504,7 @@ class Vec {
499504
/// Returns an iterator over all the elements in the array, visited in the
500505
/// same order they appear in the array. The iterator gives const access to
501506
/// each element.
502-
constexpr SliceIter<const T&> iter() const& noexcept {
507+
constexpr SliceIter<const T&> iter() const& noexcept sus_lifetimebound {
503508
check(!is_moved_from());
504509
return SliceIter<const T&>::with(storage_, len_);
505510
}
@@ -508,7 +513,7 @@ class Vec {
508513
/// Returns an iterator over all the elements in the array, visited in the
509514
/// same order they appear in the array. The iterator gives mutable access to
510515
/// each element.
511-
constexpr SliceIterMut<T&> iter_mut() & noexcept {
516+
constexpr SliceIterMut<T&> iter_mut() & noexcept sus_lifetimebound {
512517
check(!is_moved_from());
513518
return SliceIterMut<T&>::with(storage_, len_);
514519
}

0 commit comments

Comments
 (0)