diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2018-06-30 12:43:08 +0200 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2018-06-30 12:43:08 +0200 |
commit | a98326eb2954ac1e79f5eac28dbeab3ec15e047f (patch) | |
tree | bb16257a1894b488e365851273735ec13a9442ef /zen/string_base.h | |
parent | 10.0 (diff) | |
download | FreeFileSync-a98326eb2954ac1e79f5eac28dbeab3ec15e047f.tar.gz FreeFileSync-a98326eb2954ac1e79f5eac28dbeab3ec15e047f.tar.bz2 FreeFileSync-a98326eb2954ac1e79f5eac28dbeab3ec15e047f.zip |
10.1
Diffstat (limited to 'zen/string_base.h')
-rwxr-xr-x | zen/string_base.h | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/zen/string_base.h b/zen/string_base.h index 2d043d4f..9632eba4 100755 --- a/zen/string_base.h +++ b/zen/string_base.h @@ -27,9 +27,9 @@ Allocator Policy: class AllocatorOptimalSpeed //exponential growth + min size { protected: - //::operator new/ ::operator delete show same performance characterisics like malloc()/free()! - static void* allocate(size_t size) { return ::malloc(size); } //throw std::bad_alloc - static void deallocate(void* ptr) { ::free(ptr); } + //::operator new/delete show same performance characterisics like malloc()/free()! + static void* allocate(size_t size) { return ::operator new (size); } //throw std::bad_alloc + static void deallocate(void* ptr) { ::operator delete (ptr); } static size_t calcCapacity(size_t length) { return std::max<size_t>(16, std::max(length + length / 2, length)); } //- size_t might overflow! => better catch here than return a too small size covering up the real error: a way too large length! //- any growth rate should not exceed golden ratio: 1.618033989 @@ -39,8 +39,8 @@ protected: class AllocatorOptimalMemory //no wasted memory, but more reallocations required when manipulating string { protected: - static void* allocate(size_t size) { return ::malloc(size); } //throw std::bad_alloc - static void deallocate(void* ptr) { ::free(ptr); } + static void* allocate(size_t size) { return ::operator new (size); } //throw std::bad_alloc + static void deallocate(void* ptr) { ::operator delete (ptr); } static size_t calcCapacity(size_t length) { return length; } }; @@ -114,7 +114,7 @@ private: capacity(static_cast<uint32_t>(cap)) {} uint32_t length; - uint32_t capacity; //allocated size without null-termination + const uint32_t capacity; //allocated size without null-termination }; static Descriptor* descr( Char* ptr) { return reinterpret_cast< Descriptor*>(ptr) - 1; } @@ -187,11 +187,15 @@ private: { Descriptor(size_t len, size_t cap) : length (static_cast<uint32_t>(len)), - capacity(static_cast<uint32_t>(cap)) { static_assert(ATOMIC_INT_LOCK_FREE == 2, ""); } //2: "The atomic type is always lock-free" + capacity(static_cast<uint32_t>(cap)) + { + static_assert(ATOMIC_INT_LOCK_FREE == 2); //2: "The atomic type is always lock-free" + //static_assert(decltype(refCount)::is_always_lock_free); //C++17 variant (not yet supported on GCC 6.3) + } std::atomic<unsigned int> refCount { 1 }; //std:atomic is uninitialized by default! uint32_t length; - uint32_t capacity; //allocated size without null-termination + const uint32_t capacity; //allocated size without null-termination }; static Descriptor* descr( Char* ptr) { return reinterpret_cast< Descriptor*>(ptr) - 1; } @@ -234,8 +238,10 @@ public: iterator begin(); iterator end (); + const_iterator begin () const { return rawStr_; } const_iterator end () const { return rawStr_ + length(); } + const_iterator cbegin() const { return begin(); } const_iterator cend () const { return end (); } @@ -357,7 +363,7 @@ Zbase<Char, SP>::Zbase(Zbase<Char, SP>&& tmp) noexcept template <class Char, template <class> class SP> inline Zbase<Char, SP>::~Zbase() { - static_assert(noexcept(this->~Zbase()), ""); //has exception spec of compiler-generated destructor by default + static_assert(noexcept(this->~Zbase())); //has exception spec of compiler-generated destructor by default this->destroy(rawStr_); //rawStr_ may be nullptr; see move constructor! } |