diff --git a/TinySTL/Detail/Ref.h b/TinySTL/Detail/Ref.h index 18b0de53e56326fd079beb956ef7517374ef7dd7..3d5f8a8078d4ea7591bb382e2ddafcb15c91be29 100644 --- a/TinySTL/Detail/Ref.h +++ b/TinySTL/Detail/Ref.h @@ -2,27 +2,44 @@ #define _REF_H_ #include +#include +#include namespace TinySTL{ namespace Detail{ + template + struct _default_delete{ + void operator ()(T* ptr){ if (ptr) delete ptr; } + }; + template struct ref_t{ + using deleter_type = std::function < void(T*) >; + std::atomic ncount_; T *data_; - - explicit ref_t(T *p = nullptr): ncount_(0), data_(p){ + deleter_type deleter_; + + explicit ref_t(T *p = nullptr, deleter_type pfunc = deleter_type(_default_delete())) + : ncount_(0), data_(p), deleter_(pfunc){ if (data_) ncount_ = 1; } ref_t(const ref_t&) = delete; ref_t& operator = (const ref_t&) = delete; + ~ref_t(){ + --ncount_; + if (ncount_ == 0) + deleter_(data_); + } + size_t count()const{ return ncount_.load(); } T *get_data()const{ return data_; } - ref_t& operator ++(){ - ++ncount_; - return *this; + ref_t& operator ++(){ + ++ncount_; + return *this; } ref_t operator ++(int){ auto t = *this; diff --git a/TinySTL/Test/RefTest.cpp b/TinySTL/Test/RefTest.cpp index d009526a66dfdef13530b0119cb8356fa82a2551..bd246259c2271d614037310c1fb4b45f78a46a20 100644 --- a/TinySTL/Test/RefTest.cpp +++ b/TinySTL/Test/RefTest.cpp @@ -7,8 +7,8 @@ namespace TinySTL{ assert(r1.count() == 0); assert(r1.get_data() == nullptr); - int n = 0; - ref_t r2(&n); + int *p = new int(0); + ref_t r2(p); assert(r2.count() == 1); assert(r2.get_data() != nullptr);