Remove back() and Take(); add GrowBuffer().

This commit is contained in:
Victor Zverovich
2012-12-10 18:08:04 -08:00
parent 198ebe9cf6
commit 14e0f87d50
2 changed files with 43 additions and 61 deletions

View File

@@ -113,8 +113,7 @@ void fmt::Formatter::FormatInt(T value, unsigned flags, int width, char type) {
++size; ++size;
} while ((n /= 10) != 0); } while ((n /= 10) != 0);
width = std::max(width, size); width = std::max(width, size);
buffer_.resize(buffer_.size() + width); p = GrowBuffer(width) + width - 1;
p = &buffer_.back();
n = abs_value; n = abs_value;
do { do {
*p-- = '0' + (n % 10); *p-- = '0' + (n % 10);
@@ -129,8 +128,7 @@ void fmt::Formatter::FormatInt(T value, unsigned flags, int width, char type) {
++size; ++size;
} while ((n >>= 4) != 0); } while ((n >>= 4) != 0);
width = std::max(width, size); width = std::max(width, size);
buffer_.resize(buffer_.size() + width); p = GrowBuffer(width) + width - 1;
p = &buffer_.back();
n = abs_value; n = abs_value;
const char *digits = type == 'x' ? "0123456789abcdef" : "0123456789ABCDEF"; const char *digits = type == 'x' ? "0123456789abcdef" : "0123456789ABCDEF";
do { do {
@@ -148,8 +146,7 @@ void fmt::Formatter::FormatInt(T value, unsigned flags, int width, char type) {
++size; ++size;
} while ((n >>= 3) != 0); } while ((n >>= 3) != 0);
width = std::max(width, size); width = std::max(width, size);
buffer_.resize(buffer_.size() + width); p = GrowBuffer(width) + width - 1;
p = &buffer_.back();
n = abs_value; n = abs_value;
do { do {
*p-- = '0' + (n & 7); *p-- = '0' + (n & 7);
@@ -219,7 +216,7 @@ void fmt::Formatter::FormatDouble(
snprintf(&buffer_[offset], size, format, width, precision, value); snprintf(&buffer_[offset], size, format, width, precision, value);
} }
if (n >= 0 && offset + n < buffer_.capacity()) { if (n >= 0 && offset + n < buffer_.capacity()) {
buffer_.resize(offset + n); GrowBuffer(n);
return; return;
} }
buffer_.reserve(n >= 0 ? offset + n + 1 : 2 * buffer_.capacity()); buffer_.reserve(n >= 0 ? offset + n + 1 : 2 * buffer_.capacity());
@@ -330,9 +327,7 @@ void fmt::Formatter::Format() {
case CHAR: { case CHAR: {
if (type && type != 'c') if (type && type != 'c')
ReportUnknownType(type, "char"); ReportUnknownType(type, "char");
std::size_t offset = buffer_.size(); char *out = GrowBuffer(std::max(width, 1));
buffer_.resize(offset + std::max(width, 1));
char *out = &buffer_[offset];
*out++ = arg.int_value; *out++ = arg.int_value;
if (width > 1) if (width > 1)
std::fill_n(out, width - 1, ' '); std::fill_n(out, width - 1, ' ');
@@ -345,12 +340,10 @@ void fmt::Formatter::Format() {
size_t size = arg.size; size_t size = arg.size;
if (size == 0 && *str) if (size == 0 && *str)
size = std::strlen(str); size = std::strlen(str);
size_t offset = buffer_.size(); char *out = GrowBuffer(std::max<size_t>(width, size));
buffer_.resize(offset + std::max<size_t>(width, size)); out = std::copy(str, str + size, out);
char *out = &buffer_[offset];
std::copy(str, str + size, out);
if (width > size) if (width > size)
std::fill_n(out + size, width - size, ' '); std::fill_n(out, width - size, ' ');
break; break;
} }
case POINTER: case POINTER:

View File

@@ -34,14 +34,7 @@ class Buffer {
T *ptr_; T *ptr_;
T data_[SIZE]; T data_[SIZE];
void Grow(std::size_t size) { void Grow(std::size_t size);
capacity_ = std::max(size, capacity_ + capacity_ / 2);
T *p = new T[capacity_];
std::copy(ptr_, ptr_ + size_, p);
if (ptr_ != data_)
delete [] ptr_;
ptr_ = p;
}
// Do not implement! // Do not implement!
Buffer(const Buffer &); Buffer(const Buffer &);
@@ -56,15 +49,15 @@ class Buffer {
std::size_t size() const { return size_; } std::size_t size() const { return size_; }
std::size_t capacity() const { return capacity_; } std::size_t capacity() const { return capacity_; }
void resize(std::size_t size) { void resize(std::size_t new_size) {
if (size > capacity_) if (new_size > capacity_)
Grow(size); Grow(new_size);
size_ = size; size_ = new_size;
} }
void reserve(std::size_t capacity) { void reserve(std::size_t capacity) {
if (capacity < capacity_) if (capacity > capacity_)
Grow(capacity - capacity_); Grow(capacity);
} }
void push_back(const T &value) { void push_back(const T &value) {
@@ -73,36 +66,33 @@ class Buffer {
ptr_[size_++] = value; ptr_[size_++] = value;
} }
void append(const T *begin, const T *end) { void append(const T *begin, const T *end);
std::ptrdiff_t size = end - begin;
if (size_ + size > capacity_)
Grow(size);
std::copy(begin, end, ptr_ + size_);
size_ += size;
}
T &operator[](std::size_t index) { return ptr_[index]; } T &operator[](std::size_t index) { return ptr_[index]; }
const T &operator[](std::size_t index) const { return ptr_[index]; } const T &operator[](std::size_t index) const { return ptr_[index]; }
const T &back() const { return ptr_[size_ - 1]; }
T &back() { return ptr_[size_ - 1]; }
void clear() { size_ = 0; } void clear() { size_ = 0; }
void Take(Buffer &other) {
if (ptr_ != data_)
delete [] ptr_;
size_ = other.size_;
if (other.ptr_ != data_) {
ptr_ = other.ptr_;
other.ptr_ = 0;
} else {
ptr_ = data_;
std::copy(other.ptr_, other.ptr_ + size_, data_);
}
}
}; };
template <typename T, std::size_t SIZE>
void Buffer<T, SIZE>::Grow(std::size_t size) {
capacity_ = std::max(size, capacity_ + capacity_ / 2);
T *p = new T[capacity_];
std::copy(ptr_, ptr_ + size_, p);
if (ptr_ != data_)
delete [] ptr_;
ptr_ = p;
}
template <typename T, std::size_t SIZE>
void Buffer<T, SIZE>::append(const T *begin, const T *end) {
std::ptrdiff_t num_elements = end - begin;
if (size_ + num_elements > capacity_)
Grow(num_elements);
std::copy(begin, end, ptr_ + size_);
size_ += num_elements;
}
// A sprintf-like formatter that automatically allocates enough storage to // A sprintf-like formatter that automatically allocates enough storage to
// fit all the output. // fit all the output.
class Formatter { class Formatter {
@@ -181,9 +171,12 @@ class Formatter {
void Format(); void Format();
void Take(Formatter &f) { // Grows the buffer by n characters and returns a pointer to the newly
buffer_.Take(f.buffer_); // allocated area.
args_.Take(f.args_); char *GrowBuffer(std::size_t n) {
std::size_t size = buffer_.size();
buffer_.resize(size + n);
return &buffer_[size];
} }
public: public:
@@ -332,9 +325,7 @@ void Formatter::FormatCustomArg(const void *arg, int width) {
std::ostringstream os; std::ostringstream os;
os << value; os << value;
std::string str(os.str()); std::string str(os.str());
std::size_t offset = buffer_.size(); char *out = GrowBuffer(std::max<std::size_t>(width, str.size()));
buffer_.resize(offset + std::max<std::size_t>(width, str.size()));
char *out = &buffer_[offset];
std::copy(str.begin(), str.end(), out); std::copy(str.begin(), str.end(), out);
if (width > str.size()) if (width > str.size())
std::fill_n(out + str.size(), width - str.size(), ' '); std::fill_n(out + str.size(), width - str.size(), ' ');
@@ -366,9 +357,7 @@ class FullFormat : public ArgFormatter {
ArgFormatter::operator=(formatter_(format)); ArgFormatter::operator=(formatter_(format));
} }
FullFormat(const FullFormat& other) : ArgFormatter(other) { FullFormat(const FullFormat& other) : ArgFormatter(other) {}
formatter_.Take(other.formatter_);
}
~FullFormat() { ~FullFormat() {
FinishFormatting(); FinishFormatting();