[Groonga-commit] groonga/grnxx at 3e75df1 [master] Add new String. (#75)

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index