From 7f23ee90fd545995a29e2175f15e8b97e59ca67a Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:13:13 +0200 Subject: 3.20 --- shared/zbase.h | 68 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 29 deletions(-) (limited to 'shared/zbase.h') diff --git a/shared/zbase.h b/shared/zbase.h index 6d9ac578..55bc0d96 100644 --- a/shared/zbase.h +++ b/shared/zbase.h @@ -3,7 +3,7 @@ // * GNU General Public License: http://www.gnu.org/licenses/gpl.html * // * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** -// + #ifndef Z_BASE_H_INCLUDED #define Z_BASE_H_INCLUDED @@ -12,6 +12,7 @@ #include #include #include +#include /* Allocator Policy: @@ -101,24 +102,17 @@ private: size_t capacity; //allocated size without null-termination }; - static Descriptor* descr(T* ptr) - { - return reinterpret_cast(ptr) - 1; - } - - static const Descriptor* descr(const T* ptr) - { - return reinterpret_cast(ptr) - 1; - } + static Descriptor* descr( T* ptr) { return reinterpret_cast< Descriptor*>(ptr) - 1; } + static const Descriptor* descr(const T* ptr) { return reinterpret_cast(ptr) - 1; } }; template //Allocator Policy -class StorageRefCount : public AP +class StorageRefCountThreadSafe : public AP { protected: - ~StorageRefCount() {} + ~StorageRefCountThreadSafe() {} static T* create(size_t size) { @@ -132,10 +126,7 @@ protected: assert(minCapacity >= size); Descriptor* const newDescr = static_cast(AP::allocate(sizeof(Descriptor) + (newCapacity + 1) * sizeof(T))); - - newDescr->refCount = 1; - newDescr->length = size; - newDescr->capacity = newCapacity; + new (newDescr) Descriptor(1, size, newCapacity); return reinterpret_cast(newDescr + 1); } @@ -150,7 +141,10 @@ protected: static void destroy(T* ptr) { if (--descr(ptr)->refCount == 0) + { + descr(ptr)->~Descriptor(); AP::deallocate(descr(ptr)); + } } static bool canWrite(const T* ptr, size_t minCapacity) //needs to be checked before writing to "ptr" @@ -173,26 +167,23 @@ protected: private: struct Descriptor { - size_t refCount; + Descriptor(long rc, size_t len, size_t cap) : refCount(rc), length(len), capacity(cap) {} + + boost::detail::atomic_count refCount; //practically no perf loss: ~0.2%! (FFS comparison) size_t length; size_t capacity; //allocated size without null-termination }; - static Descriptor* descr(T* ptr) - { - return reinterpret_cast(ptr) - 1; - } - - static const Descriptor* descr(const T* ptr) - { - return reinterpret_cast(ptr) - 1; - } + static Descriptor* descr( T* ptr) { return reinterpret_cast< Descriptor*>(ptr) - 1; } + static const Descriptor* descr(const T* ptr) { return reinterpret_cast(ptr) - 1; } }; -template class SP = StorageRefCount, //Storage Policy - class AP = AllocatorOptimalSpeed> //Allocator Policy +//perf note: interstingly StorageDeepCopy and StorageRefCountThreadSafe show same performance in FFS comparison + +template class SP = StorageRefCountThreadSafe, //Storage Policy + class AP = AllocatorOptimalSpeed> //Allocator Policy class Zbase : public SP { public: @@ -200,6 +191,7 @@ public: Zbase(const T* source); //implicit conversion from a C-string Zbase(const T* source, size_t length); Zbase(const Zbase& source); + Zbase(Zbase&& tmp); explicit Zbase(T source); //dangerous if implicit: T buffer[]; Zbase name = buffer; ups... //allow explicit construction from different string type, prevent ambiguity via SFINAE template explicit Zbase(const S& other, typename S::value_type = 0); @@ -261,6 +253,7 @@ public: void push_back(T val); //STL access Zbase& operator=(const Zbase& source); + Zbase& operator=(Zbase&& tmp); Zbase& operator=(const T* source); Zbase& operator=(T source); Zbase& operator+=(const Zbase& other); @@ -379,6 +372,14 @@ Zbase::Zbase(const Zbase& source) } +template class SP, class AP> +inline +Zbase::Zbase(Zbase&& tmp) +{ + rawStr = this->clone(tmp.rawStr); //for a ref-counting string there probably isn't a faster way, even with r-value references +} + + template class SP, class AP> template inline @@ -825,6 +826,15 @@ Zbase& Zbase::operator=(const Zbase& source) } +template class SP, class AP> +inline +Zbase& Zbase::operator=(Zbase&& tmp) +{ + swap(tmp); + return *this; +} + + template class SP, class AP> inline Zbase& Zbase::operator=(const T* source) -- cgit