Bug fixes to flex_string submitted by Harmut Kaiser, Jean-Francois Bastien, and Andrew Barnert
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@836 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
b19393301f
commit
3179302021
3 changed files with 65 additions and 21 deletions
|
@ -131,6 +131,8 @@ private:
|
|||
Align align_;
|
||||
} temp;
|
||||
|
||||
--(*Data().begin()); // Harmut Kaiser fix:
|
||||
// decrement the use count of the remaining object
|
||||
new(buf_) Storage(
|
||||
*new(temp.buf_) Storage(Data()),
|
||||
flex_string_details::Shallow());
|
||||
|
|
|
@ -890,7 +890,8 @@ public:
|
|||
|
||||
size_type find (const value_type* s, size_type pos, size_type n) const
|
||||
{
|
||||
for (; pos <= size(); ++pos)
|
||||
// Mar 13 2007: Changed <= to < below (thanks to Jean-Francois Bastien)
|
||||
for (; pos < size(); ++pos)
|
||||
{
|
||||
if (traits_type::compare(data() + pos, s, n) == 0)
|
||||
{
|
||||
|
@ -1079,13 +1080,10 @@ public:
|
|||
const value_type* s, size_type n2) const
|
||||
{
|
||||
Enforce(pos1 <= size(), static_cast<std::out_of_range*>(0), "");
|
||||
Procust(n1, size() - pos1);
|
||||
const int r = traits_type::compare(data(), s, Min(n1, n2));
|
||||
return
|
||||
r != 0 ? r :
|
||||
n1 > n2 ? 1 :
|
||||
n1 < n2 ? -1 :
|
||||
0;
|
||||
Procust(n1, size() - pos1);
|
||||
// The line below fixed by Jean-Francois Bastien, 04-23-2007. Thanks!
|
||||
const int r = traits_type::compare(pos1 + data(), s, Min(n1, n2));
|
||||
return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
|
||||
}
|
||||
|
||||
int compare(size_type pos1, size_type n1,
|
||||
|
@ -1096,9 +1094,14 @@ public:
|
|||
return compare(pos1, n1, str.data() + pos2, Min(n2, str.size() - pos2));
|
||||
}
|
||||
|
||||
// Code from Jean-Francois Bastien (03/26/2007)
|
||||
int compare(const value_type* s) const
|
||||
{
|
||||
return traits_type::compare(data(), s, Max(length(),traits_type::length(s)));
|
||||
{
|
||||
// Could forward to compare(0, size(), s, traits_type::length(s))
|
||||
// but that does two extra checks
|
||||
const size_type n1(size()), n2(traits_type::length(s));
|
||||
const int r = traits_type::compare(data(), s, Min(n1, n2));
|
||||
return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1260,7 +1263,7 @@ std::basic_istream<typename flex_string<E, T, A, S>::value_type,
|
|||
typename flex_string<E, T, A, S>::traits_type>&
|
||||
operator>>(
|
||||
std::basic_istream<typename flex_string<E, T, A, S>::value_type,
|
||||
typename flex_string<E, T, A, S>::traits_type>& is,
|
||||
typename flex_string<E, T, A, S>::traits_type>& is,
|
||||
flex_string<E, T, A, S>& str);
|
||||
|
||||
template <typename E, class T, class A, class S>
|
||||
|
@ -1268,7 +1271,7 @@ std::basic_ostream<typename flex_string<E, T, A, S>::value_type,
|
|||
typename flex_string<E, T, A, S>::traits_type>&
|
||||
operator<<(
|
||||
std::basic_ostream<typename flex_string<E, T, A, S>::value_type,
|
||||
typename flex_string<E, T, A, S>::traits_type>& os,
|
||||
typename flex_string<E, T, A, S>::traits_type>& os,
|
||||
const flex_string<E, T, A, S>& str)
|
||||
{ return os << str.c_str(); }
|
||||
|
||||
|
|
|
@ -180,15 +180,44 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Fix suggested by Andrew Barnert on 07/03/2007
|
||||
SmallStringOpt& operator=(const SmallStringOpt& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
reserve(rhs.size());
|
||||
resize(0, 0);
|
||||
append(rhs.data(), rhs.data() + rhs.size());
|
||||
if (&rhs == this) return *this;
|
||||
const size_t rhss = rhs.size();
|
||||
// Will we use this' allocated buffer?
|
||||
if (rhss > maxSmallString && capacity() > rhss) {
|
||||
const size_t s = size();
|
||||
if (s >= rhss) {
|
||||
// shrink
|
||||
resize(rhss, 0);
|
||||
std::copy(rhs.begin(), rhs.end(), begin());
|
||||
} else {
|
||||
// grow
|
||||
std::copy(rhs.begin(), rhs.begin() + s, begin());
|
||||
append(rhs.begin() + s, rhs.end());
|
||||
}
|
||||
return *this;
|
||||
} else {
|
||||
// this' buffer is useless
|
||||
if (rhs.Small()) {
|
||||
// Just destroy and copy over (ugly but efficient)
|
||||
// Works because construction of a small string can't fail
|
||||
if (!Small()) this->~SmallStringOpt();
|
||||
new(this) SmallStringOpt(rhs);
|
||||
} else {
|
||||
SmallStringOpt copy(rhs);
|
||||
if (Small()) {
|
||||
// no need to swap, just destructively read copy into this
|
||||
// ugly but efficient again
|
||||
memcpy(this, ©, sizeof(*this));
|
||||
copy.buf_[maxSmallString] = maxSmallString; // clear the copy
|
||||
} else {
|
||||
// Use the swap trick
|
||||
copy.swap(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SmallStringOpt()
|
||||
|
@ -282,7 +311,7 @@ public:
|
|||
else
|
||||
{
|
||||
std::copy(b, e, buf_ + maxSmallString - buf_[maxSmallString]);
|
||||
buf_[maxSmallString] = buf_[maxSmallString] - value_type(sz);
|
||||
buf_[maxSmallString] -= value_type(sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,8 +356,18 @@ public:
|
|||
// Big string resized to small string
|
||||
// 11-17=2001: bug fix in the assertion below
|
||||
assert(capacity() > n);
|
||||
SmallStringOpt newObj(data(), n, get_allocator());
|
||||
newObj.swap(*this);
|
||||
// The following two commented-out lines were fixed by
|
||||
// Jean-Francois Bastien, 07/26/2007
|
||||
//SmallStringOpt newObj(data(), n, get_allocator());
|
||||
// newObj.swap(*this);
|
||||
if (n <= size()) {
|
||||
SmallStringOpt newObj(data(), n, get_allocator());
|
||||
newObj.swap(*this);
|
||||
} else {
|
||||
SmallStringOpt newObj(data(), size(), get_allocator());
|
||||
newObj.resize(n, c); // invoke this function recursively
|
||||
newObj.swap(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue