From 2dc50176b766730efa3a49fda2bfca00aead27ac Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Fri, 30 Sep 2016 15:41:29 +0200 Subject: [PATCH] Support for make_shared --- tstl/include/shared_ptr.hpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tstl/include/shared_ptr.hpp b/tstl/include/shared_ptr.hpp index 14cf6347..00e23b28 100644 --- a/tstl/include/shared_ptr.hpp +++ b/tstl/include/shared_ptr.hpp @@ -19,12 +19,14 @@ namespace std { * * TODO */ -template > +template struct shared_ptr { using pointer_type = T*; ///< The pointer type using reference_type = T&; ///< The reference type using element_type = T; ///< The element type + struct control_block_t; + constexpr shared_ptr() : ptr(), control_block() {} constexpr explicit shared_ptr(decltype(nullptr)) : ptr(), control_block() {} @@ -41,6 +43,10 @@ struct shared_ptr { control_block->counter = 1; } + shared_ptr(T* ptr, control_block_t* control_block, int) : ptr(ptr), control_block(control_block) { + control_block->counter = 1; + } + shared_ptr(const shared_ptr& rhs) : ptr(rhs.ptr), control_block(rhs.control_block) { __sync_fetch_and_add(&control_block->counter, 1); } @@ -99,7 +105,6 @@ struct shared_ptr { return get(); } -private: struct control_block_t { volatile size_t counter; @@ -122,10 +127,30 @@ private: } }; + template + struct inplace_control_block_impl : control_block_t { + U ptr; + + template + inplace_control_block_impl(Args&&... args) : ptr(std::forward(args)...){} + + virtual void destroy(){ + // Nothing to do + } + }; + +private: pointer_type ptr; control_block_t* control_block; }; +template +std::shared_ptr make_shared(Args&&... args){ + auto cb = new typename std::shared_ptr::template inplace_control_block_impl(std::forward(args)...); + + return std::shared_ptr{&cb->ptr, cb, 0}; +} + } //end of namespace std #endif