summaryrefslogtreecommitdiff
path: root/shared/zbase.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:16 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:16 +0200
commitbd6336c629841c6db3a6ca53a936d629d34db53b (patch)
tree3721ef997864108df175ce677a8a7d4342a6f1d2 /shared/zbase.h
parent4.0 (diff)
downloadFreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.tar.gz
FreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.tar.bz2
FreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.zip
4.1
Diffstat (limited to 'shared/zbase.h')
-rw-r--r--shared/zbase.h903
1 files changed, 0 insertions, 903 deletions
diff --git a/shared/zbase.h b/shared/zbase.h
deleted file mode 100644
index 5f404887..00000000
--- a/shared/zbase.h
+++ /dev/null
@@ -1,903 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * 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
-
-#include <cassert>
-#include <vector>
-#include <sstream>
-#include <algorithm>
-#include <string_tools.h>
-#include <boost/detail/atomic_count.hpp>
-
-/*
-Allocator Policy:
------------------
- void* allocate(size_t size) //throw (std::bad_alloc)
- void deallocate(void* ptr)
- size_t calcCapacity(size_t length)
-*/
-class AllocatorOptimalSpeed //exponential growth + min size
-{
-public:
- //::operator new/ ::operator 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, length + length / 2); }
-};
-
-
-class AllocatorOptimalMemory //no wasted memory, but more reallocations required when manipulating string
-{
-public:
- 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; }
-};
-
-/*
-Storage Policy:
----------------
-template <typename T, //Character Type
- class AP> //Allocator Policy
-
- T* create(size_t size)
- T* create(size_t size, size_t minCapacity)
- T* clone(T* ptr)
- void destroy(T* ptr)
- bool canWrite(const T* ptr, size_t minCapacity) //needs to be checked before writing to "ptr"
- size_t length(const T* ptr)
- void setLength(T* ptr, size_t newLength)
-*/
-
-template < typename T, //Character Type
- class AP > //Allocator Policy
-class StorageDeepCopy : public AP
-{
-protected:
- ~StorageDeepCopy() {}
-
- static T* create(size_t size) { return create(size, size); }
- static T* create(size_t size, size_t minCapacity)
- {
- const size_t newCapacity = AP::calcCapacity(minCapacity);
- assert(newCapacity >= minCapacity);
- assert(minCapacity >= size);
-
- Descriptor* const newDescr = static_cast<Descriptor*>(AP::allocate(sizeof(Descriptor) + (newCapacity + 1) * sizeof(T)));
-
- newDescr->length = size;
- newDescr->capacity = newCapacity;
-
- return reinterpret_cast<T*>(newDescr + 1);
- }
-
- static T* clone(T* ptr)
- {
- T* newData = create(length(ptr));
- std::copy(ptr, ptr + length(ptr) + 1, newData);
- return newData;
- }
-
- static void destroy(T* ptr) { AP::deallocate(descr(ptr)); }
-
- //this needs to be checked before writing to "ptr"
- static bool canWrite(const T* ptr, size_t minCapacity) { return minCapacity <= descr(ptr)->capacity; }
- static size_t length(const T* ptr) { return descr(ptr)->length; }
-
- static void setLength(T* ptr, size_t newLength)
- {
- assert(canWrite(ptr, newLength));
- descr(ptr)->length = newLength;
- }
-
-private:
- struct Descriptor
- {
- size_t length;
- size_t capacity; //allocated size without null-termination
- };
-
- static Descriptor* descr( T* ptr) { return reinterpret_cast< Descriptor*>(ptr) - 1; }
- static const Descriptor* descr(const T* ptr) { return reinterpret_cast<const Descriptor*>(ptr) - 1; }
-};
-
-
-template < typename T, //Character Type
- class AP > //Allocator Policy
-class StorageRefCountThreadSafe : public AP
-{
-protected:
- ~StorageRefCountThreadSafe() {}
-
- static T* create(size_t size)
- {
- return create(size, size);
- }
-
- static T* create(size_t size, size_t minCapacity)
- {
- const size_t newCapacity = AP::calcCapacity(minCapacity);
- assert(newCapacity >= minCapacity);
- assert(minCapacity >= size);
-
- Descriptor* const newDescr = static_cast<Descriptor*>(AP::allocate(sizeof(Descriptor) + (newCapacity + 1) * sizeof(T)));
- new (newDescr) Descriptor(1, size, newCapacity);
-
- return reinterpret_cast<T*>(newDescr + 1);
- }
-
- static T* clone(T* ptr)
- {
- assert(descr(ptr)->refCount > 0);
- ++descr(ptr)->refCount;
- return ptr;
- }
-
- 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"
- {
- assert(descr(ptr)->refCount > 0);
- return descr(ptr)->refCount == 1 && minCapacity <= descr(ptr)->capacity;
- }
-
- static size_t length(const T* ptr)
- {
- return descr(ptr)->length;
- }
-
- static void setLength(T* ptr, size_t newLength)
- {
- assert(canWrite(ptr, newLength));
- descr(ptr)->length = newLength;
- }
-
-private:
- struct Descriptor
- {
- 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< Descriptor*>(ptr) - 1; }
- static const Descriptor* descr(const T* ptr) { return reinterpret_cast<const Descriptor*>(ptr) - 1; }
-};
-
-
-//perf note: interstingly StorageDeepCopy and StorageRefCountThreadSafe show same performance in FFS comparison
-
-template < class T, //Character Type
- template <class, class> class SP = StorageRefCountThreadSafe, //Storage Policy
- class AP = AllocatorOptimalSpeed > //Allocator Policy
-class Zbase : public SP<T, AP>
-{
-public:
- Zbase();
- 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 <class S> explicit Zbase(const S& other, typename S::value_type = 0);
- ~Zbase();
-
- //operator const T* () const; //NO implicit conversion to a C-string!! Many problems... one of them: if we forget to provide operator overloads, it'll just work with a T*...
-
- //STL accessors
- typedef T* iterator;
- typedef const T* const_iterator;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
- const T* begin() const;
- const T* end() const;
- T* begin();
- T* end();
-
- //wxString-like functions
- bool StartsWith(const Zbase& prefix ) const { return zen::startsWith(*this, prefix ); }
- bool StartsWith(const T* prefix ) const { return zen::startsWith(*this, prefix ); }
- bool StartsWith( T prefix ) const { return zen::startsWith(*this, prefix ); }
- bool EndsWith (const Zbase& postfix) const { return zen::endsWith (*this, postfix); }
- bool EndsWith (const T* postfix) const { return zen::endsWith (*this, postfix); }
- bool EndsWith ( T postfix) const { return zen::endsWith (*this, postfix); }
- void Truncate(size_t newLen) { return zen::truncate(*this, newLen); }
- Zbase& Replace(const Zbase& old, const Zbase& replacement, bool replaceAll = true) { zen::replace(*this, old, replacement, replaceAll); return *this; }
- Zbase AfterLast( T ch) const { return zen::afterLast (*this, ch); } //returns the whole string if "ch" not found
- Zbase BeforeLast( T ch) const { return zen::beforeLast (*this, ch); } //returns empty string if "ch" not found
- Zbase AfterFirst( T ch) const { return zen::afterFirst (*this, ch); } //returns empty string if "ch" not found
- Zbase BeforeFirst(T ch) const { return zen::beforeFirst(*this, ch); } //returns the whole string if "ch" not found
- void Trim(bool fromLeft = true, bool fromRight = true) { zen::trim(*this, fromLeft, fromRight); }
- std::vector<Zbase> Split(T delimiter) const { return zen::split(*this, delimiter); }
- std::vector<Zbase> Split(const Zbase& delimiter) const { return zen::split(*this, delimiter); }
-
- //number conversion
- template <class N> static Zbase fromNumber(N number) { return zen::toString<Zbase>(number); }
- template <class N> N toNumber() const { return zen::toNumber<N>(*this); }
-
- //std::string functions
- size_t length() const;
- size_t size() const;
- const T* c_str() const; //C-string format with NULL-termination
- const T* data() const; //internal representation, NULL-termination not guaranteed
- const T operator[](size_t pos) const;
- Zbase substr(size_t pos = 0, size_t len = npos) const;
- bool empty() const;
- void clear();
- size_t find(const Zbase& str, size_t pos = 0) const; //
- size_t find(const T* str, size_t pos = 0) const; //returns "npos" if not found
- size_t find(T ch, size_t pos = 0) const; //
- size_t rfind(T ch, size_t pos = npos) const; //
- size_t rfind(const T* str, size_t pos = npos) const; //
- Zbase& replace(size_t pos1, size_t n1, const Zbase& str);
- void reserve(size_t minCapacity);
- Zbase& assign(const T* source, size_t len);
- void resize(size_t newSize, T fillChar = 0);
- void swap(Zbase& other);
- 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);
- Zbase& operator+=(const T* other);
- Zbase& operator+=(T ch);
-
- static const size_t npos = static_cast<size_t>(-1);
-
-private:
- Zbase(int); //detect usage errors
- Zbase& operator=(int); //
-
- T* rawStr;
-};
-
-template <class T, template <class, class> class SP, class AP> bool operator==(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> bool operator==(const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> bool operator==(const T* lhs, const Zbase<T, SP, AP>& rhs);
-
-template <class T, template <class, class> class SP, class AP> bool operator!=(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> bool operator!=(const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> bool operator!=(const T* lhs, const Zbase<T, SP, AP>& rhs);
-
-template <class T, template <class, class> class SP, class AP> bool operator< (const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> bool operator< (const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> bool operator< (const T* lhs, const Zbase<T, SP, AP>& rhs);
-
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const T* lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+( T lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, T rhs);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//################################# inline implementation ########################################
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>::Zbase()
-{
- //resist the temptation to avoid this allocation by referening a static global: NO performance advantage, MT issues!
- rawStr = this->create(0);
- rawStr[0] = 0;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>::Zbase(T source)
-{
- rawStr = this->create(1);
- rawStr[0] = source;
- rawStr[1] = 0;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>::Zbase(const T* source)
-{
- const size_t sourceLen = zen::cStringLength(source);
- rawStr = this->create(sourceLen);
- std::copy(source, source + sourceLen + 1, rawStr); //include null-termination
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>::Zbase(const T* source, size_t sourceLen)
-{
- rawStr = this->create(sourceLen);
- std::copy(source, source + sourceLen, rawStr);
- rawStr[sourceLen] = 0;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>::Zbase(const Zbase<T, SP, AP>& source)
-{
- rawStr = this->clone(source.rawStr);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>::Zbase(Zbase<T, SP, AP> && 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 T, template <class, class> class SP, class AP>
-template <class S>
-inline
-Zbase<T, SP, AP>::Zbase(const S& other, typename S::value_type)
-{
- const size_t sourceLen = other.size();
- rawStr = this->create(sourceLen);
- std::copy(other.c_str(), other.c_str() + sourceLen, rawStr);
- rawStr[sourceLen] = 0;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>::~Zbase()
-{
- this->destroy(rawStr);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-size_t Zbase<T, SP, AP>::find(const Zbase& str, size_t pos) const
-{
- assert(pos <= length());
- const T* thisEnd = end(); //respect embedded 0
- const T* iter = std::search(begin() + pos, thisEnd,
- str.begin(), str.end());
- return iter == thisEnd ? npos : iter - begin();
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-size_t Zbase<T, SP, AP>::find(const T* str, size_t pos) const
-{
- assert(pos <= length());
- const T* thisEnd = end(); //respect embedded 0
- const T* iter = std::search(begin() + pos, thisEnd,
- str, str + zen::cStringLength(str));
- return iter == thisEnd ? npos : iter - begin();
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-size_t Zbase<T, SP, AP>::find(T ch, size_t pos) const
-{
- assert(pos <= length());
- const T* thisEnd = end();
- const T* iter = std::find(begin() + pos, thisEnd, ch); //respect embedded 0
- return iter == thisEnd ? npos : iter - begin();
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-size_t Zbase<T, SP, AP>::rfind(T ch, size_t pos) const
-{
- assert(pos == npos || pos <= length());
-
- const size_t thisLen = length();
- if (thisLen == 0) return npos;
- pos = std::min(thisLen - 1, pos); //handle "npos" and "pos == length()" implicitly
-
- while (rawStr[pos] != ch) //pos points to last char of the string
- {
- if (pos == 0)
- return npos;
- --pos;
- }
- return pos;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-size_t Zbase<T, SP, AP>::rfind(const T* str, size_t pos) const
-{
- assert(pos == npos || pos <= length());
-
- const size_t strLen = zen::cStringLength(str);
- const T* currEnd = pos == npos ? end() : begin() + std::min(pos + strLen, length());
-
- const T* iter = std::find_end(begin(), currEnd,
- str, str + strLen);
- return iter == currEnd ? npos : iter - begin();
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::replace(size_t pos1, size_t n1, const Zbase& str)
-{
- assert(str.data() < rawStr || rawStr + length() < str.data()); //str mustn't point to data in this string
- assert(pos1 + n1 <= length());
-
- const size_t n2 = str.length();
-
- const size_t oldLen = length();
- if (oldLen == 0)
- return *this = str;
-
- const size_t newLen = oldLen - n1 + n2;
-
- if (canWrite(rawStr, newLen))
- {
- if (n1 < n2) //move remainder right -> std::copy_backward
- {
- std::copy_backward(rawStr + pos1 + n1, rawStr + oldLen + 1, rawStr + newLen + 1); //include null-termination
- setLength(rawStr, newLen);
- }
- else if (n1 > n2) //shift left -> std::copy
- {
- std::copy(rawStr + pos1 + n1, rawStr + oldLen + 1, rawStr + pos1 + n2); //include null-termination
- setLength(rawStr, newLen);
- }
-
- std::copy(str.data(), str.data() + n2, rawStr + pos1);
- }
- else
- {
- //copy directly into new string
- T* const newStr = this->create(newLen);
-
- std::copy(rawStr, rawStr + pos1, newStr);
- std::copy(str.data(), str.data() + n2, newStr + pos1);
- std::copy(rawStr + pos1 + n1, rawStr + oldLen + 1, newStr + pos1 + n2); //include null-termination
-
- destroy(rawStr);
- rawStr = newStr;
- }
- return *this;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-void Zbase<T, SP, AP>::resize(size_t newSize, T fillChar)
-{
- if (canWrite(rawStr, newSize))
- {
- if (length() < newSize)
- std::fill(rawStr + length(), rawStr + newSize, fillChar);
- rawStr[newSize] = 0;
- setLength(rawStr, newSize); //keep after call to length()
- }
- else
- {
- T* newStr = this->create(newSize);
- newStr[newSize] = 0;
-
- if (length() < newSize)
- {
- std::copy(rawStr, rawStr + length(), newStr);
- std::fill(newStr + length(), newStr + newSize, fillChar);
- }
- else
- std::copy(rawStr, rawStr + newSize, newStr);
-
- destroy(rawStr);
- rawStr = newStr;
- }
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator==(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs)
-{
- return lhs.length() == rhs.length() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); //respect embedded 0
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator==(const Zbase<T, SP, AP>& lhs, const T* rhs)
-{
- return lhs.length() == zen::cStringLength(rhs) && std::equal(lhs.begin(), lhs.end(), rhs); //respect embedded 0
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator==(const T* lhs, const Zbase<T, SP, AP>& rhs)
-{
- return operator==(rhs, lhs);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator!=(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs)
-{
- return !operator==(lhs, rhs);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator!=(const Zbase<T, SP, AP>& lhs, const T* rhs)
-{
- return !operator==(lhs, rhs);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator!=(const T* lhs, const Zbase<T, SP, AP>& rhs)
-{
- return !operator==(lhs, rhs);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator<(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs)
-{
- return std::lexicographical_compare(lhs.begin(), lhs.end(), //respect embedded 0
- rhs.begin(), rhs.end());
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator<(const Zbase<T, SP, AP>& lhs, const T* rhs)
-{
- return std::lexicographical_compare(lhs.begin(), lhs.end(), //respect embedded 0
- rhs, rhs + zen::cStringLength(rhs));
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool operator<(const T* lhs, const Zbase<T, SP, AP>& rhs)
-{
- return std::lexicographical_compare(lhs, lhs + zen::cStringLength(lhs), //respect embedded 0
- rhs.begin(), rhs.end());
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-size_t Zbase<T, SP, AP>::length() const
-{
- return SP<T, AP>::length(rawStr);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-size_t Zbase<T, SP, AP>::size() const
-{
- return length();
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const T* Zbase<T, SP, AP>::c_str() const
-{
- return rawStr;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const T* Zbase<T, SP, AP>::data() const
-{
- return rawStr;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const T Zbase<T, SP, AP>::operator[](size_t pos) const
-{
- assert(pos < length());
- return rawStr[pos];
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const T* Zbase<T, SP, AP>::begin() const
-{
- return rawStr;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const T* Zbase<T, SP, AP>::end() const
-{
- return rawStr + length();
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-T* Zbase<T, SP, AP>::begin()
-{
- reserve(length());
- return rawStr;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-T* Zbase<T, SP, AP>::end()
-{
- return begin() + length();
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-void Zbase<T, SP, AP>::push_back(T val)
-{
- operator+=(val);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-bool Zbase<T, SP, AP>::empty() const
-{
- return length() == 0;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-void Zbase<T, SP, AP>::clear()
-{
- if (!empty())
- {
- if (canWrite(rawStr, 0))
- {
- rawStr[0] = 0; //keep allocated memory
- setLength(rawStr, 0); //
- }
- else
- *this = Zbase();
- }
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs)
-{
- return Zbase<T, SP, AP>(lhs) += rhs;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const T* rhs)
-{
- return Zbase<T, SP, AP>(lhs) += rhs;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const Zbase<T, SP, AP> operator+(const T* lhs, const Zbase<T, SP, AP>& rhs)
-{
- return Zbase<T, SP, AP>(lhs) += rhs;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const Zbase<T, SP, AP> operator+(T lhs, const Zbase<T, SP, AP>& rhs)
-{
- return (Zbase<T, SP, AP>() += lhs) += rhs;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, T rhs)
-{
- return Zbase<T, SP, AP>(lhs) += rhs;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-void Zbase<T, SP, AP>::swap(Zbase<T, SP, AP>& other)
-{
- std::swap(rawStr, other.rawStr);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP> Zbase<T, SP, AP>::substr(size_t pos, size_t len) const
-{
- assert(pos + (len == npos ? 0 : len) <= length());
- return Zbase(rawStr + pos, len == npos ? length() - pos : len);
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-void Zbase<T, SP, AP>::reserve(size_t minCapacity) //make unshared and check capacity
-{
- if (!canWrite(rawStr, minCapacity))
- {
- //allocate a new string
- T* newStr = create(length(), std::max(minCapacity, length())); //reserve() must NEVER shrink the string: logical const!
- std::copy(rawStr, rawStr + length() + 1, newStr); //include NULL-termination
-
- destroy(rawStr);
- rawStr = newStr;
- }
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::assign(const T* source, size_t len)
-{
- if (canWrite(rawStr, len))
- {
- std::copy(source, source + len, rawStr);
- rawStr[len] = 0; //include null-termination
- setLength(rawStr, len);
- }
- else
- *this = Zbase(source, len);
-
- return *this;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(const Zbase<T, SP, AP>& source)
-{
- Zbase(source).swap(*this);
- return *this;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(Zbase<T, SP, AP> && tmp)
-{
- swap(tmp);
- return *this;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(const T* source)
-{
- return assign(source, zen::cStringLength(source));
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator=(T source)
-{
- if (canWrite(rawStr, 1))
- {
- rawStr[0] = source;
- rawStr[1] = 0; //include null-termination
- setLength(rawStr, 1);
- }
- else
- *this = Zbase(source);
-
- return *this;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator+=(const Zbase<T, SP, AP>& other)
-{
- const size_t thisLen = length();
- const size_t otherLen = other.length();
- reserve(thisLen + otherLen); //make unshared and check capacity
-
- std::copy(other.rawStr, other.rawStr + otherLen + 1, rawStr + thisLen); //include null-termination
- setLength(rawStr, thisLen + otherLen);
- return *this;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator+=(const T* other)
-{
- const size_t thisLen = length();
- const size_t otherLen = zen::cStringLength(other);
- reserve(thisLen + otherLen); //make unshared and check capacity
-
- std::copy(other, other + otherLen + 1, rawStr + thisLen); //include null-termination
- setLength(rawStr, thisLen + otherLen);
- return *this;
-}
-
-
-template <class T, template <class, class> class SP, class AP>
-inline
-Zbase<T, SP, AP>& Zbase<T, SP, AP>::operator+=(T ch)
-{
- const size_t thisLen = length();
- reserve(thisLen + 1); //make unshared and check capacity
- rawStr[thisLen] = ch;
- rawStr[thisLen + 1] = 0;
- setLength(rawStr, thisLen + 1);
- return *this;
-}
-
-#endif //Z_BASE_H_INCLUDED
bgstack15