Path: blob/master/thirdparty/embree/common/sys/ref.h
10279 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "atomic.h"67namespace embree8{9struct NullTy {10};1112extern MAYBE_UNUSED NullTy null;1314class RefCount15{16public:17RefCount(int val = 0) : refCounter(val) {}18virtual ~RefCount() {};1920virtual RefCount* refInc() { refCounter.fetch_add(1); return this; }21virtual void refDec() { if (refCounter.fetch_add(-1) == 1) delete this; }22private:23std::atomic<size_t> refCounter;24};2526////////////////////////////////////////////////////////////////////////////////27/// Reference to single object28////////////////////////////////////////////////////////////////////////////////2930template<typename Type>31class Ref32{33public:34Type* ptr;3536////////////////////////////////////////////////////////////////////////////////37/// Constructors, Assignment & Cast Operators38////////////////////////////////////////////////////////////////////////////////3940__forceinline Ref() : ptr(nullptr) {}41__forceinline Ref(NullTy) : ptr(nullptr) {}42__forceinline Ref(const Ref& input) : ptr(input.ptr) { if (ptr) ptr->refInc(); }43__forceinline Ref(Ref&& input) : ptr(input.ptr) { input.ptr = nullptr; }4445__forceinline Ref(Type* const input) : ptr(input)46{47if (ptr)48ptr->refInc();49}5051__forceinline ~Ref()52{53if (ptr)54ptr->refDec();55}5657__forceinline Ref& operator =(const Ref& input)58{59if (input.ptr)60input.ptr->refInc();61if (ptr)62ptr->refDec();63ptr = input.ptr;64return *this;65}6667__forceinline Ref& operator =(Ref&& input)68{69if (ptr)70ptr->refDec();71ptr = input.ptr;72input.ptr = nullptr;73return *this;74}7576__forceinline Ref& operator =(Type* const input)77{78if (input)79input->refInc();80if (ptr)81ptr->refDec();82ptr = input;83return *this;84}8586__forceinline Ref& operator =(NullTy)87{88if (ptr)89ptr->refDec();90ptr = nullptr;91return *this;92}9394__forceinline operator bool() const { return ptr != nullptr; }9596__forceinline const Type& operator *() const { return *ptr; }97__forceinline Type& operator *() { return *ptr; }98__forceinline const Type* operator ->() const { return ptr; }99__forceinline Type* operator ->() { return ptr; }100101template<typename TypeOut>102__forceinline Ref<TypeOut> cast() { return Ref<TypeOut>(static_cast<TypeOut*>(ptr)); }103template<typename TypeOut>104__forceinline const Ref<TypeOut> cast() const { return Ref<TypeOut>(static_cast<TypeOut*>(ptr)); }105106template<typename TypeOut>107__forceinline Ref<TypeOut> dynamicCast() { return Ref<TypeOut>(dynamic_cast<TypeOut*>(ptr)); }108template<typename TypeOut>109__forceinline const Ref<TypeOut> dynamicCast() const { return Ref<TypeOut>(dynamic_cast<TypeOut*>(ptr)); }110};111112template<typename Type> __forceinline bool operator < (const Ref<Type>& a, const Ref<Type>& b) { return a.ptr < b.ptr; }113114template<typename Type> __forceinline bool operator ==(const Ref<Type>& a, NullTy ) { return a.ptr == nullptr; }115template<typename Type> __forceinline bool operator ==(NullTy , const Ref<Type>& b) { return nullptr == b.ptr; }116template<typename Type> __forceinline bool operator ==(const Ref<Type>& a, const Ref<Type>& b) { return a.ptr == b.ptr; }117118template<typename Type> __forceinline bool operator !=(const Ref<Type>& a, NullTy ) { return a.ptr != nullptr; }119template<typename Type> __forceinline bool operator !=(NullTy , const Ref<Type>& b) { return nullptr != b.ptr; }120template<typename Type> __forceinline bool operator !=(const Ref<Type>& a, const Ref<Type>& b) { return a.ptr != b.ptr; }121}122123124