Celeritas 0.7+07fbe3c
Loading...
Searching...
No Matches
Public Member Functions | Friends | List of all members
celeritas::OpaqueId< TagT, IndexT > Class Template Reference

Type-safe "optional" index for accessing an array or collection of data. More...

#include <OpaqueId.hh>

Public Types

Type aliases
using tag_type = TagT
 
using value_type = IndexT
 
using index_type = IndexT
 
using difference_type = std::make_signed_t< IndexT >
 
using size_type = value_type
 

Public Member Functions

constexpr OpaqueId (nullid_t)
 Construct implicitly from a null type.
 
constexpr OpaqueId ()
 Default to null state.
 
constexpr OpaqueId (value_type index)
 Construct explicitly with a stored value (validity not checked)
 
constexpr operator bool () const noexcept
 Whether this ID is in a valid (assigned) state.
 
constexpr value_type operator* () const noexcept
 Unchecked dereference: caller must ensure the ID is valid.
 
constexpr value_type value () const noexcept(ndebug)
 Get the value, asserting non-null in debug builds.
 
constexpr value_type constdata () const noexcept
 Access the underlying data for cached loading on device.
 
Pointer-like operators
constexpr OpaqueIdoperator++ () noexcept(ndebug)
 
constexpr OpaqueId operator++ (int) noexcept(ndebug)
 
constexpr OpaqueIdoperator-- () noexcept(ndebug)
 
constexpr OpaqueId operator-- (int) noexcept(ndebug)
 
Deprecated access
Deprecated:
Remove in v1.0
constexpr value_type get () const noexcept(ndebug)
 Get the ID's value: use value() instead.
 
constexpr value_type unchecked_get () const noexcept
 Get the value without checking: use operator* instead.
 

Friends

std::ostream & operator<< (std::ostream &os, OpaqueId v)
 Output an opaque ID's value or a placeholder if unavailable.
 
Pointer-like arithmetic

Get the distance between two opaque IDs

difference_type operator- (OpaqueId self, OpaqueId other)
 Increment an opaque ID by an offset, checking against underflow.
 
template<class J >
auto operator+ (OpaqueId id, J offset) -> std::enable_if_t< std::is_integral_v< J >, OpaqueId >
 Increment an opaque ID by an offset, checking against underflow.
 
template<class J >
auto operator+ (J offset, OpaqueId id) -> std::enable_if_t< std::is_integral_v< J >, OpaqueId >
 Increment an opaque ID by an offset (symmetric)
 
template<class J >
auto operator- (OpaqueId id, J offset) -> std::enable_if_t< std::is_integral_v< J >, OpaqueId >
 Decrement an opaque ID by an offset.
 
Compare two OpaqueId of the same type
constexpr friend bool operator== (OpaqueId lhs, OpaqueId rhs) noexcept
 
constexpr friend bool operator!= (OpaqueId lhs, OpaqueId rhs) noexcept
 
constexpr friend bool operator< (OpaqueId lhs, OpaqueId rhs) noexcept
 
constexpr friend bool operator> (OpaqueId lhs, OpaqueId rhs) noexcept
 
constexpr friend bool operator<= (OpaqueId lhs, OpaqueId rhs) noexcept
 
constexpr friend bool operator>= (OpaqueId lhs, OpaqueId rhs) noexcept
 
Compare with nullid
constexpr friend bool operator== (OpaqueId id, nullid_t) noexcept
 
constexpr friend bool operator== (nullid_t, OpaqueId id) noexcept
 
constexpr friend bool operator!= (OpaqueId id, nullid_t) noexcept
 
constexpr friend bool operator!= (nullid_t, OpaqueId id) noexcept
 
Compare with unsigned int

This allows size checking for containers

template<class J >
constexpr friend auto operator< (OpaqueId lhs, J rhs) noexcept -> std::enable_if_t< std::is_unsigned_v< J >, bool >
 
template<class J >
constexpr friend auto operator<= (OpaqueId lhs, J rhs) noexcept -> std::enable_if_t< std::is_unsigned_v< J >, bool >
 

Detailed Description

template<class TagT, class IndexT = ::celeritas::size_type>
class celeritas::OpaqueId< TagT, IndexT >

Type-safe "optional" index for accessing an array or collection of data.

Template Parameters
TagTType of an item at the index corresponding to this ID
IndexTUnsigned integer acting as the stored value

Indexing into arrays with integers, rather than storing pointers, is key to easy and safe data management across host/device boundaries. Pointers in C++ can act as a reference to an array or element of data, and they also have a type, which not only gives the stride width in bytes but also prevents accidental aliasing.

The OpaqueId class is an attempt to model integer indexing (device-friendly) with pointer semantics (type-safe). Annotating index offsets with a type gives the offsets a semantic meaning, and it gives the developer compile-time type safety. As an example, it prevents index arguments in a function call from being provided out of order.

The typical usage of an OpaqueId should be as std::optional<IndexT>. The default-constructed value, nullid, cannot be used to index into an array, nor does it represent a valid element. An OpaqueId object evaluates to true if it has a value (OpaqueId{3}), or false if it does not (OpaqueId{}). The invalid state is usually referred to in the codebase as a "null ID". Analogous to std::optional, nullid can be used for comparison, assignment, and construction.

Construction
  • Default: result is nullid
  • Implicitly from nullid
  • Explicitly from a compatible unsigned integer
  • Via id_cast for safe construction from general (or differently sized) integers
Usage
  • Check for nullity with bool or by comparing with nullid
  • Check for validity as a container index with id < vec.size()
  • Access value with operator* : vec[*id]
  • Access data with Collection::operator[]
  • Loop over consecutive IDs with range
  • Pre- and post- increment and decrement
  • Subtract two IDs to get a difference

The OpaqueId is hashable, sortable, and printable. It can be loaded via cached device memory using ldg .

Note
A valid ID will always compare less than a null ID: you can use std::partition and erase to remove null IDs from a vector.
Comparators are defined as inline friend functions to allow ADL-assisted conversion, including from LdgWrapper.
Related helper functions and types
  • nullid is an instance of nullid_t that compares to any OpaqueId as its "null" value.
  • is_opaque_id_v allows checking for generic types
  • MakeSize_t is a descriptive type alias to get the unsigned integer value_type of an opaque ID, used for container capacities.
  • id_cast safely converts integers to OpaqueId.
About the TagT template parameter
If this class is used for indexing into an array, then TagT argument should usually be the value type of the array:
FooRecord operator[](OpaqueId<FooRecord>);
Type-safe "optional" index for accessing an array or collection of data.
Definition OpaqueId.hh:123
Otherwise, the convention is to use an anonymous tag:
using FooId = OpaqueId<struct Foo_>;

The documentation for this class was generated from the following file: