namespace internal {
+enum class OwnershipBehavior {
+ DELETE_POINTER,
+ BORROW_POINTER,
+};
+
template <typename T>
class OwnedPtrDeleter {
public:
- OwnedPtrDeleter() {}
+ OwnedPtrDeleter()
+ : refs_(),
+ finalizer_(&OwnedPtrDeleter<T>::HandleDeletePointer) {}
+
~OwnedPtrDeleter() {}
- OwnedPtrDeleter(OwnedPtrDeleter&& other) : refs_(std::move(other.refs_)) {
+ explicit OwnedPtrDeleter(OwnershipBehavior behavior)
+ : refs_(),
+ finalizer_(behavior == OwnershipBehavior::BORROW_POINTER
+ ? &OwnedPtrDeleter<T>::HandleBorrowPointer
+ : &OwnedPtrDeleter<T>::HandleDeletePointer) {
+ }
+
+ OwnedPtrDeleter(OwnedPtrDeleter&& other)
+ : refs_(std::move(other.refs_)),
+ finalizer_(other.finalizer_) {
}
void operator=(const OwnedPtrDeleter& o) {
refs_ = o.refs_;
+ finalizer_ = o.finalizer_;
}
void operator()(T* t) const {
for (auto& ref : refs_) {
ref->MarkDeleted();
}
- delete t;
+ (this->finalizer_)(t);
}
protected:
refs_.remove(ref);
}
+ static void HandleDeletePointer(T* t) {
+ delete t;
+ }
+
+ static void HandleBorrowPointer(T* t) {}
+
private:
+ void (*finalizer_)(T*);
std::forward_list<ref<T>*> refs_;
};
-void RaiseUseAfterFree(const char* error) __attribute__((noreturn));
+void RaiseUseAfterFree() __attribute__((noreturn));
} // namespace internal
private:
void CheckDeleted() const {
if (IsDeleted()) {
- internal::RaiseUseAfterFree("attempt to access deleted pointer");
+ internal::RaiseUseAfterFree();
}
}
};
template <typename T>
-class member {
+class member : public T {
public:
- template <typename... Args>
- explicit member(Args&&... args)
- : t_(new T(std::forward<Args>(args)...)) {
- }
+ using T::T;
ref<T> operator&() {
- return t_.get();
- }
-
- T* operator->() {
- return t_.operator->();
- }
-
- const T* operator->() const {
- return t_.operator->();
+ return ptr_.get();
}
private:
- owned<T> t_;
+ owned<T> ptr_ = owned<T>(this,
+ internal::OwnedPtrDeleter<T>(
+ internal::OwnershipBehavior::BORROW_POINTER));
};
#else
using ref = T*;
template <typename T>
-class member : public T {
- public:
- using T::T;
-
- T* operator->() {
- return this;
- }
-
- const T* operator->() const {
- return this;
- }
-};
+using member = T;
#endif