susumu.yata
null+****@clear*****
Fri Sep 26 15:14:22 JST 2014
susumu.yata 2014-09-26 15:14:22 +0900 (Fri, 26 Sep 2014) New Revision: 3e75df1e44c7cf405ad2b754577ba6ad1cb6d576 https://github.com/groonga/grnxx/commit/3e75df1e44c7cf405ad2b754577ba6ad1cb6d576 Message: Add new String. (#75) Modified files: include/grnxx/types/string.hpp lib/grnxx/types.cpp Modified: include/grnxx/types/string.hpp (+228 -0) =================================================================== --- include/grnxx/types/string.hpp 2014-09-26 15:09:33 +0900 (63fff75) +++ include/grnxx/types/string.hpp 2014-09-26 15:14:22 +0900 (90894c0) @@ -181,6 +181,234 @@ inline bool operator>=(const char *lhs, const StringCRef &rhs) { using Text = StringCRef; +class String { + public: + String() : buf_(), size_(0), capacity_(0) {} + ~String() {} + + String(String &&arg) + : buf_(std::move(arg.buf_)), + size_(arg.size_), + capacity_(arg.capacity_) { + arg.size_ = 0; + arg.capacity_ = 0; + } + + String &operator=(String &&arg) { + buf_ = std::move(arg.buf_); + size_ = arg.size_; + capacity_ = arg.capacity_; + arg.size_ = 0; + arg.capacity_ = 0; + return *this; + } + + operator StringCRef() const { + return ref(); + } + + StringCRef ref(Int offset = 0) const { + return StringCRef(buf_.get() + offset, size_ - offset); + } + StringCRef ref(Int offset, Int size) const { + return StringCRef(buf_.get() + offset, size); + } + + char &operator[](Int i) { + return buf_[i]; + } + const char &operator[](Int i) const { + return buf_[i]; + } + + char &front() { + return buf_[0]; + } + const char &front() const { + return buf_[0]; + } + + char &back() { + return buf_[size_ - 1]; + } + const char &back() const { + return buf_[size_ - 1]; + } + + char *data() { + return buf_.get(); + } + const char *data() const { + return buf_.get(); + } + + Int size() const { + return size_; + } + Int capacity() const { + return capacity_; + } + + bool reserve(Error *error, Int new_size) { + if (new_size <= capacity_) { + return true; + } + return resize_buf(error, new_size); + } + + bool assign(Error *error, const StringCRef &arg) { + if (arg.size() > capacity_) { + if (!resize_buf(error, arg.size())) { + return false; + } + } + std::memcpy(buf_.get(), arg.data(), arg.size()); + size_ = arg.size(); + return true; + } + + bool resize(Error *error, Int new_size) { + if (new_size > capacity_) { + if (!resize_buf(error, new_size)) { + return false; + } + } + size_ = new_size; + return true; + } + bool resize(Error *error, Int new_size, char value) { + if (new_size > capacity_) { + if (!resize_buf(error, new_size)) { + return false; + } + } + if (new_size > size_) { + std::memset(buf_.get() + size_, value, new_size - size_); + } + size_ = new_size; + return true; + } + + void clear() { + size_ = 0; + } + + bool push_back(Error *error, char value) { + if (size_ == capacity_) { + if (!resize_buf(error, size_ + 1)) { + return false; + } + } + buf_[size_] = value; + ++size_; + return true; + } + void pop_back() { + --size_; + } + + bool append(Error *error, const StringCRef &arg) { + if ((size_ + arg.size()) > capacity_) { + if (!resize_buf(error, (size_ + arg.size()))) { + return false; + } + } + std::memcpy(buf_.get() + size_, arg.data(), arg.size()); + size_ += arg.size(); + return true; + } + + void swap(Int i, Int j) { + char temp = buf_[i]; + buf_[i] = buf_[j]; + buf_[j] = temp; + } + + // Compare a strings. + bool operator==(const StringCRef &arg) const { + return ref() == arg; + } + bool operator!=(const StringCRef &arg) const { + return ref() != arg; + } + bool operator<(const StringCRef &arg) const { + return ref() < arg; + } + bool operator>(const StringCRef &arg) const { + return ref() > arg; + } + bool operator<=(const StringCRef &arg) const { + return ref() <= arg; + } + bool operator>=(const StringCRef &arg) const { + return ref() >= arg; + } + + // Compare a string with a zero-terminated string. + bool operator==(const char *arg) const { + return ref() == arg; + } + bool operator!=(const char *arg) const { + return ref() != arg; + } + bool operator<(const char *arg) const { + return ref() < arg; + } + bool operator>(const char *arg) const { + return ref() > arg; + } + bool operator<=(const char *arg) const { + return ref() <= arg; + } + bool operator>=(const char *arg) const { + return ref() >= arg; + } + + // Return true if "*this" starts with "arg". + bool starts_with(const StringCRef &arg) const { + return ref().starts_with(arg); + } + bool starts_with(const char *arg) const { + return ref().starts_with(arg); + } + + // Return true if "*this" ends with "arg". + bool ends_with(const StringCRef &arg) const { + return ref().ends_with(arg); + } + bool ends_with(const char *arg) const { + return ref().ends_with(arg); + } + + private: + unique_ptr<char[]> buf_; + Int size_; + Int capacity_; + + // Assume new_size > capacity_. + bool resize_buf(Error *error, Int new_size); +}; + +// Compare a null-terminated string with a string. +inline bool operator==(const char *lhs, const String &rhs) { + return rhs == lhs; +} +inline bool operator!=(const char *lhs, const String &rhs) { + return rhs != lhs; +} +inline bool operator<(const char *lhs, const String &rhs) { + return rhs > lhs; +} +inline bool operator>(const char *lhs, const String &rhs) { + return rhs < lhs; +} +inline bool operator<=(const char *lhs, const String &rhs) { + return rhs >= lhs; +} +inline bool operator>=(const char *lhs, const String &rhs) { + return rhs <= lhs; +} + } // namespace grnxx #endif // GRNXX_TYPES_STRING_HPP Modified: lib/grnxx/types.cpp (+17 -0) =================================================================== --- lib/grnxx/types.cpp 2014-09-26 15:09:33 +0900 (5661d9e) +++ lib/grnxx/types.cpp 2014-09-26 15:14:22 +0900 (7ceca95) @@ -40,6 +40,23 @@ void GeoPoint::fix(Int *latitude, Int *longitude) { } } +bool String::resize_buf(Error *error, Int new_size) { + Int new_capacity = capacity_ * 2; + if (new_size > new_capacity) { + new_capacity = new_size; + } + Int new_buf_size = new_capacity; + unique_ptr<char[]> new_buf(new (nothrow) char[new_buf_size]); + if (!new_buf) { + GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); + return false; + } + std::memcpy(new_buf.get(), buf_.get(), size_); + buf_ = std::move(new_buf); + capacity_ = new_capacity; + return true; +} + DBOptions::DBOptions() {} TableOptions::TableOptions() {} -------------- next part -------------- HTML����������������������������...Download