[Groonga-commit] groonga/grnxx at 8457be5 [master] Enable String.

Zurück zum Archiv-Index

susumu.yata null+****@clear*****
Tue Dec 16 10:39:46 JST 2014


susumu.yata	2014-10-30 18:49:12 +0900 (Thu, 30 Oct 2014)

  New Revision: 8457be5a2e351ddfc399bdc98669e0e27c48290b
  https://github.com/groonga/grnxx/commit/8457be5a2e351ddfc399bdc98669e0e27c48290b

  Message:
    Enable String.

  Added files:
    lib/grnxx/string.cpp
  Modified files:
    include/grnxx/string.hpp
    lib/grnxx/Makefile.am
    test/test_string.cpp

  Modified: include/grnxx/string.hpp (+239 -239)
===================================================================
--- include/grnxx/string.hpp    2014-10-30 18:43:20 +0900 (c595f3a)
+++ include/grnxx/string.hpp    2014-10-30 18:49:12 +0900 (0ef00a5)
@@ -3,6 +3,9 @@
 
 #include <cstring>
 
+#include "grnxx/error.hpp"
+#include "grnxx/memory.hpp"
+
 namespace grnxx {
 
 // Reference to a byte string.
@@ -188,245 +191,242 @@ inline bool operator>=(const char *lhs, const StringCRef &rhs) {
   return rhs <= lhs;
 }
 
-//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(size_t offset = 0) const {
-//    return StringCRef(buf_.get() + offset, size_ - offset);
-//  }
-//  StringCRef ref(size_t offset, size_t size) const {
-//    return StringCRef(buf_.get() + offset, size);
-//  }
-
-//  char &operator[](size_t i) {
-//    return buf_[i];
-//  }
-//  const char &operator[](size_t 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();
-//  }
-
-//  size_t size() const {
-//    return size_;
-//  }
-//  size_t capacity() const {
-//    return capacity_;
-//  }
-
-//  bool reserve(Error *error, size_t 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 assign(Error *error, const char *data, size_t size) {
-//    return assign(error, StringCRef(data, size));
-//  }
-
-//  bool resize(Error *error, size_t new_size) {
-//    if (new_size > capacity_) {
-//      if (!resize_buf(error, new_size)) {
-//        return false;
-//      }
-//    }
-//    size_ = new_size;
-//    return true;
-//  }
-//  bool resize(Error *error, size_t 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 ((arg.data() >= buf_.get()) && (arg.data() < (buf_.get() + size_))) {
-//        // Note that "arg" will be deleted in resize_buf() if "arg" is a part
-//        // of "*this".
-//        return append_overlap(error, arg);
-//      } else if (!resize_buf(error, (size_ + arg.size()))) {
-//        return false;
-//      }
-//    }
-//    std::memcpy(buf_.get() + size_, arg.data(), arg.size());
-//    size_ += arg.size();
-//    return true;
-//  }
-//  bool append(Error *error, const char *data, size_t size) {
-//    return append(error, StringCRef(data, size));
-//  }
-
-//  void swap(size_t i, size_t 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_;
-//  size_t size_;
-//  size_t capacity_;
-
-//  // Assume new_size > capacity_.
-//  bool resize_buf(Error *error, size_t new_size);
-//  // Resize the internal buffer and append a part of "*this".
-//  bool append_overlap(Error *error, const StringCRef &arg);
-//};
-
-//// 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;
-//}
+class String {
+ public:
+  constexpr String() : buf_(nullptr), size_(0), capacity_(0) {}
+  ~String();
+
+  String(const String &) = delete;
+  String& operator=(const String &) = delete;
+
+  String(String &&rhs)
+      : buf_(rhs.buf_),
+        size_(rhs.size_),
+        capacity_(rhs.capacity_) {
+    rhs.buf_ = nullptr;
+    rhs.size_ = 0;
+    rhs.capacity_ = 0;
+  }
+  String &operator=(String &&rhs) {
+    buf_ = rhs.buf_;
+    size_ = rhs.size_;
+    capacity_ = rhs.capacity_;
+    rhs.buf_ = nullptr;
+    rhs.size_ = 0;
+    rhs.capacity_ = 0;
+    return *this;
+  }
+
+  operator StringCRef() const {
+    return cref();
+  }
+
+  StringCRef cref(size_t offset = 0) const {
+    return StringCRef(buf_ + offset, size_ - offset);
+  }
+  StringCRef cref(size_t offset, size_t size) const {
+    return StringCRef(buf_ + offset, size);
+  }
+
+  char &operator[](size_t i) {
+    return buf_[i];
+  }
+  const char &operator[](size_t 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_;
+  }
+  const char *data() const {
+    return buf_;
+  }
+  size_t size() const {
+    return size_;
+  }
+  size_t capacity() const {
+    return capacity_;
+  }
+
+  bool reserve(Error *error, size_t new_size) {
+    if (new_size <= capacity_) {
+      return true;
+    }
+    return resize_buf(error, new_size);
+  }
+
+  bool assign(Error *error, const StringCRef &rhs) {
+    if (rhs.size() > capacity_) {
+      if (!resize_buf(error, rhs.size())) {
+        return false;
+      }
+    }
+    std::memcpy(buf_, rhs.data(), rhs.size());
+    size_ = rhs.size();
+    return true;
+  }
+  bool assign(Error *error, const char *data, size_t size) {
+    return assign(error, StringCRef(data, size));
+  }
+
+  bool resize(Error *error, size_t new_size) {
+    if (new_size > capacity_) {
+      if (!resize_buf(error, new_size)) {
+        return false;
+      }
+    }
+    size_ = new_size;
+    return true;
+  }
+  bool resize(Error *error, size_t new_size, char value) {
+    if (new_size > capacity_) {
+      if (!resize_buf(error, new_size)) {
+        return false;
+      }
+    }
+    if (new_size > size_) {
+      std::memset(buf_ + 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 &rhs) {
+    if ((size_ + rhs.size()) > capacity_) {
+      // NOTE: If "rhs" is a part of "*this", "rhs" is destoyed in
+      //       resize_buf(), so append_overlap() is required.
+      if ((rhs.data() >= buf_) && (rhs.data() < (buf_ + size_))) {
+        return append_overlap(error, rhs);
+      } else if (!resize_buf(error, (size_ + rhs.size()))) {
+        return false;
+      }
+    }
+    std::memcpy(buf_ + size_, rhs.data(), rhs.size());
+    size_ += rhs.size();
+    return true;
+  }
+  bool append(Error *error, const char *data, size_t size) {
+    return append(error, StringCRef(data, size));
+  }
+
+  // Compare a strings.
+  bool operator==(const StringCRef &rhs) const {
+    return cref() == rhs;
+  }
+  bool operator!=(const StringCRef &rhs) const {
+    return cref() != rhs;
+  }
+  bool operator<(const StringCRef &rhs) const {
+    return cref() < rhs;
+  }
+  bool operator>(const StringCRef &rhs) const {
+    return cref() > rhs;
+  }
+  bool operator<=(const StringCRef &rhs) const {
+    return cref() <= rhs;
+  }
+  bool operator>=(const StringCRef &rhs) const {
+    return cref() >= rhs;
+  }
+
+  // Compare a string with a zero-terminated string.
+  bool operator==(const char *rhs) const {
+    return cref() == rhs;
+  }
+  bool operator!=(const char *rhs) const {
+    return cref() != rhs;
+  }
+  bool operator<(const char *rhs) const {
+    return cref() < rhs;
+  }
+  bool operator>(const char *rhs) const {
+    return cref() > rhs;
+  }
+  bool operator<=(const char *rhs) const {
+    return cref() <= rhs;
+  }
+  bool operator>=(const char *rhs) const {
+    return cref() >= rhs;
+  }
+
+  // Return true if "*this" starts with "rhs".
+  bool starts_with(const StringCRef &rhs) const {
+    return cref().starts_with(rhs);
+  }
+  bool starts_with(const char *rhs) const {
+    return cref().starts_with(rhs);
+  }
+
+  // Return true if "*this" ends with "rhs".
+  bool ends_with(const StringCRef &rhs) const {
+    return cref().ends_with(rhs);
+  }
+  bool ends_with(const char *rhs) const {
+    return cref().ends_with(rhs);
+  }
+
+ private:
+  char *buf_;
+  size_t size_;
+  size_t capacity_;
+
+  // Assume new_size > capacity_.
+  bool resize_buf(Error *error, size_t new_size);
+  // Resize the internal buffer and append a part of "*this".
+  bool append_overlap(Error *error, const StringCRef &rhs);
+};
+
+// 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
 

  Modified: lib/grnxx/Makefile.am (+2 -1)
===================================================================
--- lib/grnxx/Makefile.am    2014-10-30 18:43:20 +0900 (61326f3)
+++ lib/grnxx/Makefile.am    2014-10-30 18:49:12 +0900 (97d412a)
@@ -10,7 +10,8 @@ libgrnxx_la_LDFLAGS = @AM_LTLDFLAGS@
 
 libgrnxx_la_SOURCES =			\
 	error.cpp			\
-	library.cpp
+	library.cpp			\
+	string.cpp
 
 #	array.cpp			\
 #	cursor.cpp			\

  Added: lib/grnxx/string.cpp (+48 -0) 100644
===================================================================
--- /dev/null
+++ lib/grnxx/string.cpp    2014-10-30 18:49:12 +0900 (e1f70da)
@@ -0,0 +1,48 @@
+#include "grnxx/string.hpp"
+
+#include <cstdlib>
+
+namespace grnxx {
+
+String::~String() {
+  std::free(buf_);
+}
+
+bool String::resize_buf(Error *error, size_t new_size) {
+  size_t new_capacity = capacity_ * 2;
+  if (new_size > new_capacity) {
+    new_capacity = new_size;
+  }
+  char *new_buf = static_cast<char *>(std::malloc(new_capacity));
+  if (!new_buf) {
+    GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed");
+    return false;
+  }
+  std::memcpy(new_buf, buf_, size_);
+  std::free(buf_);
+  buf_ = new_buf;
+  capacity_ = new_capacity;
+  return true;
+}
+
+bool String::append_overlap(Error *error, const StringCRef &rhs) {
+  size_t new_capacity = capacity_ * 2;
+  size_t new_size = size_ + rhs.size();
+  if (new_size > new_capacity) {
+    new_capacity = new_size;
+  }
+  char *new_buf = static_cast<char *>(std::malloc(new_capacity));
+  if (!new_buf) {
+    GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed");
+    return false;
+  }
+  std::memcpy(new_buf, buf_, size_);
+  std::memcpy(new_buf + size_, rhs.data(), rhs.size());
+  std::free(buf_);
+  buf_ = new_buf;
+  size_ = new_size;
+  capacity_ = new_capacity;
+  return true;
+}
+
+}  // namespace grnxx

  Modified: test/test_string.cpp (+86 -86)
===================================================================
--- test/test_string.cpp    2014-10-30 18:43:20 +0900 (7bf0a99)
+++ test/test_string.cpp    2014-10-30 18:49:12 +0900 (7c1e090)
@@ -90,94 +90,94 @@ void test_string_cref() {
   }
 }
 
-//void test_string() {
-//  constexpr size_t NUM_STRINGS = 1024;
-
-//  grnxx::Error error;
-
-//  std::vector<std::string> strings(NUM_STRINGS);
-//  std::vector<grnxx::StringCRef> refs(NUM_STRINGS);
-//  std::vector<grnxx::String> bodies(NUM_STRINGS);
-//  for (size_t i = 0; i < NUM_STRINGS; ++i) {
-//    std::stringstream stream;
-//    stream << i;
-//    strings[i] = stream.str();
-//    refs[i] = grnxx::StringCRef(strings[i].data(), strings[i].size());
-//    assert(bodies[i].assign(&error, refs[i]));
-//  }
-
-//  for (size_t i = 0; i < NUM_STRINGS; ++i) {
-//    assert(bodies[i].size() == static_cast<size_t>(strings[i].size()));
-//    for (size_t j = 0; j < bodies[i].size(); ++j) {
-//      assert(bodies[i][j] == strings[i][j]);
-//    }
-
-//    for (size_t j = 0; j < NUM_STRINGS; ++j) {
-//      assert((bodies[i] == bodies[j]) == (strings[i] == strings[j]));
-//      assert((bodies[i] != bodies[j]) == (strings[i] != strings[j]));
-//      assert((bodies[i] < bodies[j]) == (strings[i] < strings[j]));
-//      assert((bodies[i] > bodies[j]) == (strings[i] > strings[j]));
-//      assert((bodies[i] <= bodies[j]) == (strings[i] <= strings[j]));
-//      assert((bodies[i] >= bodies[j]) == (strings[i] >= strings[j]));
-
-//      assert((bodies[i] == refs[j]) == (strings[i] == strings[j]));
-//      assert((bodies[i] != refs[j]) == (strings[i] != strings[j]));
-//      assert((bodies[i] < refs[j]) == (strings[i] < strings[j]));
-//      assert((bodies[i] > refs[j]) == (strings[i] > strings[j]));
-//      assert((bodies[i] <= refs[j]) == (strings[i] <= strings[j]));
-//      assert((bodies[i] >= refs[j]) == (strings[i] >= strings[j]));
-
-//      assert((bodies[i] == strings[j].c_str()) == (strings[i] == strings[j]));
-//      assert((bodies[i] != strings[j].c_str()) == (strings[i] != strings[j]));
-//      assert((bodies[i] < strings[j].c_str()) == (strings[i] < strings[j]));
-//      assert((bodies[i] > strings[j].c_str()) == (strings[i] > strings[j]));
-//      assert((bodies[i] <= strings[j].c_str()) == (strings[i] <= strings[j]));
-//      assert((bodies[i] >= strings[j].c_str()) == (strings[i] >= strings[j]));
-
-//      assert((refs[i] == bodies[j]) == (strings[i] == strings[j]));
-//      assert((refs[i] != bodies[j]) == (strings[i] != strings[j]));
-//      assert((refs[i] < bodies[j]) == (strings[i] < strings[j]));
-//      assert((refs[i] > bodies[j]) == (strings[i] > strings[j]));
-//      assert((refs[i] <= bodies[j]) == (strings[i] <= strings[j]));
-//      assert((refs[i] >= bodies[j]) == (strings[i] >= strings[j]));
-
-//      assert((strings[i].c_str() == bodies[j]) == (strings[i] == strings[j]));
-//      assert((strings[i].c_str() != bodies[j]) == (strings[i] != strings[j]));
-//      assert((strings[i].c_str() < bodies[j]) == (strings[i] < strings[j]));
-//      assert((strings[i].c_str() > bodies[j]) == (strings[i] > strings[j]));
-//      assert((strings[i].c_str() <= bodies[j]) == (strings[i] <= strings[j]));
-//      assert((strings[i].c_str() >= bodies[j]) == (strings[i] >= strings[j]));
-
-//      assert(bodies[i].starts_with(bodies[j]) ==
-//             string_starts_with(strings[i], strings[j]));
-//      assert(bodies[i].starts_with(strings[j].c_str()) ==
-//             string_starts_with(strings[i], strings[j]));
-//      assert(bodies[i].ends_with(bodies[j]) ==
-//             string_ends_with(strings[i], strings[j]));
-//      assert(bodies[i].ends_with(strings[j].c_str()) ==
-//             string_ends_with(strings[i], strings[j]));
-//    }
-//  }
-
-//  for (size_t i = 0; i < NUM_STRINGS; ++i) {
-//    std::stringstream stream;
-//    stream << (i / 2.0);
-//    std::string extra_string = stream.str();
-//    strings[i].append(extra_string);
-//    assert(bodies[i].append(&error, extra_string.data(), extra_string.size()));
-//    assert(bodies[i] ==
-//           grnxx::StringCRef(strings[i].data(), strings[i].size()));
-//  }
-
-//  for (size_t i = 0; i < NUM_STRINGS; ++i) {
-//    strings[i].append(strings[i]);
-//    assert(bodies[i].append(&error, bodies[i]));
-//    assert(std::string(bodies[i].data(), bodies[i].size()) == strings[i]);
-//  }
-//}
+void test_string() {
+  constexpr size_t NUM_STRINGS = 1024;
+
+  grnxx::Error error;
+
+  std::vector<std::string> strings(NUM_STRINGS);
+  std::vector<grnxx::StringCRef> refs(NUM_STRINGS);
+  std::vector<grnxx::String> bodies(NUM_STRINGS);
+  for (size_t i = 0; i < NUM_STRINGS; ++i) {
+    std::stringstream stream;
+    stream << i;
+    strings[i] = stream.str();
+    refs[i] = grnxx::StringCRef(strings[i].data(), strings[i].size());
+    assert(bodies[i].assign(&error, refs[i]));
+  }
+
+  for (size_t i = 0; i < NUM_STRINGS; ++i) {
+    assert(bodies[i].size() == static_cast<size_t>(strings[i].size()));
+    for (size_t j = 0; j < bodies[i].size(); ++j) {
+      assert(bodies[i][j] == strings[i][j]);
+    }
+
+    for (size_t j = 0; j < NUM_STRINGS; ++j) {
+      assert((bodies[i] == bodies[j]) == (strings[i] == strings[j]));
+      assert((bodies[i] != bodies[j]) == (strings[i] != strings[j]));
+      assert((bodies[i] < bodies[j]) == (strings[i] < strings[j]));
+      assert((bodies[i] > bodies[j]) == (strings[i] > strings[j]));
+      assert((bodies[i] <= bodies[j]) == (strings[i] <= strings[j]));
+      assert((bodies[i] >= bodies[j]) == (strings[i] >= strings[j]));
+
+      assert((bodies[i] == refs[j]) == (strings[i] == strings[j]));
+      assert((bodies[i] != refs[j]) == (strings[i] != strings[j]));
+      assert((bodies[i] < refs[j]) == (strings[i] < strings[j]));
+      assert((bodies[i] > refs[j]) == (strings[i] > strings[j]));
+      assert((bodies[i] <= refs[j]) == (strings[i] <= strings[j]));
+      assert((bodies[i] >= refs[j]) == (strings[i] >= strings[j]));
+
+      assert((bodies[i] == strings[j].c_str()) == (strings[i] == strings[j]));
+      assert((bodies[i] != strings[j].c_str()) == (strings[i] != strings[j]));
+      assert((bodies[i] < strings[j].c_str()) == (strings[i] < strings[j]));
+      assert((bodies[i] > strings[j].c_str()) == (strings[i] > strings[j]));
+      assert((bodies[i] <= strings[j].c_str()) == (strings[i] <= strings[j]));
+      assert((bodies[i] >= strings[j].c_str()) == (strings[i] >= strings[j]));
+
+      assert((refs[i] == bodies[j]) == (strings[i] == strings[j]));
+      assert((refs[i] != bodies[j]) == (strings[i] != strings[j]));
+      assert((refs[i] < bodies[j]) == (strings[i] < strings[j]));
+      assert((refs[i] > bodies[j]) == (strings[i] > strings[j]));
+      assert((refs[i] <= bodies[j]) == (strings[i] <= strings[j]));
+      assert((refs[i] >= bodies[j]) == (strings[i] >= strings[j]));
+
+      assert((strings[i].c_str() == bodies[j]) == (strings[i] == strings[j]));
+      assert((strings[i].c_str() != bodies[j]) == (strings[i] != strings[j]));
+      assert((strings[i].c_str() < bodies[j]) == (strings[i] < strings[j]));
+      assert((strings[i].c_str() > bodies[j]) == (strings[i] > strings[j]));
+      assert((strings[i].c_str() <= bodies[j]) == (strings[i] <= strings[j]));
+      assert((strings[i].c_str() >= bodies[j]) == (strings[i] >= strings[j]));
+
+      assert(bodies[i].starts_with(bodies[j]) ==
+             string_starts_with(strings[i], strings[j]));
+      assert(bodies[i].starts_with(strings[j].c_str()) ==
+             string_starts_with(strings[i], strings[j]));
+      assert(bodies[i].ends_with(bodies[j]) ==
+             string_ends_with(strings[i], strings[j]));
+      assert(bodies[i].ends_with(strings[j].c_str()) ==
+             string_ends_with(strings[i], strings[j]));
+    }
+  }
+
+  for (size_t i = 0; i < NUM_STRINGS; ++i) {
+    std::stringstream stream;
+    stream << (i / 2.0);
+    std::string extra_string = stream.str();
+    strings[i].append(extra_string);
+    assert(bodies[i].append(&error, extra_string.data(), extra_string.size()));
+    assert(bodies[i] ==
+           grnxx::StringCRef(strings[i].data(), strings[i].size()));
+  }
+
+  for (size_t i = 0; i < NUM_STRINGS; ++i) {
+    strings[i].append(strings[i]);
+    assert(bodies[i].append(&error, bodies[i]));
+    assert(std::string(bodies[i].data(), bodies[i].size()) == strings[i]);
+  }
+}
 
 int main() {
   test_string_cref();
-//  test_string();
+  test_string();
   return 0;
 }
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index