24 #ifndef PXR_BASE_TF_POINTER_AND_BITS_H 25 #define PXR_BASE_TF_POINTER_AND_BITS_H 31 #include <type_traits> 34 PXR_NAMESPACE_OPEN_SCOPE
37 constexpr
bool Tf_IsPow2(uintptr_t val) {
38 return val && !(val & (val - 1));
58 template <
typename U,
bool = false>
60 static constexpr uintptr_t value =
alignof(U);
63 struct _AlignOf<U, true> {
64 static constexpr uintptr_t value =
alignof(
void*);
70 static constexpr uintptr_t _GetAlign() noexcept {
71 return _AlignOf<T, std::is_abstract<T>::value>::value;
74 static constexpr
bool _SupportsAtLeastOneBit() noexcept {
75 return _GetAlign() > 1 && Tf_IsPow2(_GetAlign());
82 static_assert(_SupportsAtLeastOneBit(),
83 "T's alignment does not support any bits");
88 : _ptrAndBits(_Combine(p, bits))
90 static_assert(_SupportsAtLeastOneBit(),
91 "T's alignment does not support any bits");
94 constexpr uintptr_t GetMaxValue()
const {
95 return _GetAlign() - 1;
98 constexpr uintptr_t GetNumBitsValues()
const {
119 template <
class Integral>
120 constexpr Integral
BitsAs() const noexcept {
122 ARCH_PRAGMA_FORCING_TO_BOOL
123 return static_cast<Integral>(_GetBits());
128 template <
class Integral>
130 _SetBits(static_cast<uintptr_t>(val));
134 void Set(T *ptr) noexcept {
139 template <
class Integral>
140 void Set(T *ptr, Integral val) noexcept {
141 _ptrAndBits = _Combine(ptr, val);
145 constexpr T *
Get() const noexcept {
155 return _AsInt(_ptrAndBits);
164 constexpr uintptr_t _GetBitMask() const noexcept {
165 return GetMaxValue();
169 constexpr T *_Combine(T *p, uintptr_t bits)
const noexcept {
170 return _AsPtr(_AsInt(p) | (bits & _GetBitMask()));
175 constexpr uintptr_t _AsInt(T *p)
const noexcept {
181 constexpr T *_AsPtr(uintptr_t i)
const noexcept {
186 constexpr T *_GetPtr() const noexcept {
187 return _AsPtr(_AsInt(_ptrAndBits) & ~_GetBitMask());
191 void _SetPtr(T *p) noexcept {
192 _ptrAndBits = _Combine(p, _GetBits());
196 constexpr uintptr_t _GetBits() const noexcept {
197 return _AsInt(_ptrAndBits) & _GetBitMask();
201 void _SetBits(uintptr_t bits) noexcept {
202 _ptrAndBits = _Combine(_GetPtr(), bits);
209 PXR_NAMESPACE_CLOSE_SCOPE
211 #endif // PXR_BASE_TF_POINTER_AND_BITS_H Pragmas for controlling compiler-specific behaviors.
constexpr T * Get() const noexcept
Retrieve the pointer.
constexpr T * operator->() const noexcept
Indirection.
constexpr uintptr_t GetLiteral() const noexcept
Retrieve the raw underlying value.
void SetBits(Integral val) noexcept
Set the stored bits. No static range checking is performed.
constexpr TfPointerAndBits(T *p, uintptr_t bits=0) noexcept
Constructor. Set the pointer to p, and the bits to bits.
This class stores a T * and a small integer in the space of a T *.
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
void Swap(TfPointerAndBits &other) noexcept
Swap this PointerAndBits with other.
TfPointerAndBits & operator=(T *ptr) noexcept
Assignment. Leaves bits unmodified.
constexpr T & operator *() const noexcept
Dereference.
constexpr Integral BitsAs() const noexcept
Retrieve the stored bits as the integral type Integral.
void Set(T *ptr) noexcept
Set the pointer value to ptr.
void Set(T *ptr, Integral val) noexcept
Set the pointer value to ptr and the bits to val.
constexpr TfPointerAndBits() noexcept
Constructor.