[Groonga-commit] groonga/grnxx [master] Add grnxx::Slice.

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Tue Feb 12 22:44:52 JST 2013


susumu.yata	2013-02-12 22:44:52 +0900 (Tue, 12 Feb 2013)

  New Revision: 0bb9e8394edcb15545cfa8361b4e20b0fad9770d
  https://github.com/groonga/grnxx/commit/0bb9e8394edcb15545cfa8361b4e20b0fad9770d

  Log:
    Add grnxx::Slice.

  Added files:
    lib/slice.hpp
    test/test_slice.cpp
  Modified files:
    lib/Makefile.am
    test/Makefile.am

  Modified: lib/Makefile.am (+1 -0)
===================================================================
--- lib/Makefile.am    2013-02-08 16:11:46 +0900 (fa60014)
+++ lib/Makefile.am    2013-02-12 22:44:52 +0900 (24c43ef)
@@ -39,6 +39,7 @@ libgrnxx_include_HEADERS =	\
 	mutex.hpp		\
 	os.hpp			\
 	recycler.hpp		\
+	slice.hpp		\
 	string.hpp		\
 	string_builder.hpp	\
 	string_format.hpp	\

  Added: lib/slice.hpp (+119 -0) 100644
===================================================================
--- /dev/null
+++ lib/slice.hpp    2013-02-12 22:44:52 +0900 (d897a87)
@@ -0,0 +1,119 @@
+/*
+  Copyright (C) 2013  Brazil, Inc.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#ifndef GRNXX_SLICE_HPP
+#define GRNXX_SLICE_HPP
+
+#include "basic.hpp"
+
+namespace grnxx {
+
+class Slice {
+ public:
+  // Create an empty (zero-size) slice.
+  Slice() : ptr_(nullptr), size_(0) {}
+  // Create a slice that refers to a zero-terminated string.
+  Slice(const char *str) : ptr_(str), size_(std::strlen(str)) {}
+  // Create a slice.
+  Slice(const char *ptr, size_t size) : ptr_(ptr), size_(size) {}
+
+  // Return true iff *this" is not empty.
+  explicit operator bool() const {
+    return size_ != 0;
+  }
+
+  // Make "*this" empty.
+  void clear() {
+    ptr_ = nullptr;
+    size_ = 0;
+  }
+
+  // Create a slice for the first "n" bytes.
+  Slice prefix(size_t size) const {
+    return Slice(ptr_, size);
+  }
+  // Create a slice for the last "n" bytes.
+  Slice suffix(size_t size) const {
+    return Slice(ptr_ + size_ - size, size);
+  }
+  // Create a subslice.
+  Slice subslice(size_t offset, size_t size) const {
+    return Slice(ptr_ + offset, size);
+  }
+
+  // Ignore the first "n" bytes of "*this".
+  void remove_prefix(size_t n) {
+    ptr_ += n;
+    size_ -= n;
+  }
+  // Ignore the last "n" bytes of "*this".
+  void remove_suffix(size_t n) {
+    size_ -= n;
+  }
+
+  // Compare "*this" and "s". Return a negative value if "*this" < "s", zero if
+  // "*this" == "s", or a positive value otherwise (if "*this" > "s").
+  int compare(const Slice &s) const {
+    const size_t min_size = (size_ < s.size_) ? size_ : s.size_;
+    int result = std::memcmp(ptr_, s.ptr_, min_size);
+    if (result != 0) {
+      return result;
+    }
+    return (size_ < s.size_) ? -1 : (size_ > s.size_);
+  }
+
+  // Return true iff "s" is a prefix of "*this".
+  bool starts_with(const Slice &s) const {
+    return (size_ >= s.size_) && (std::memcmp(ptr_, s.ptr_, s.size_) == 0);
+  }
+  // Return true iff "s" is a suffix of "*this".
+  bool ends_with(const Slice &s) const {
+    return (size_ >= s.size_) &&
+           (std::memcmp(ptr_ + size_ - s.size_, s.ptr_, s.size_) == 0);
+  }
+
+  // Return the "n"-th byte of "*this".
+  char operator[](size_t i) const {
+    return ptr_[i];
+  }
+
+  // Return the starting address of "*this".
+  const char *ptr() const {
+    return ptr_;
+  }
+  // Returns the size of "*this".
+  size_t size() const {
+    return size_;
+  }
+
+ private:
+  const char *ptr_;
+  size_t size_;
+};
+
+inline bool operator==(const Slice &lhs, const Slice &rhs) {
+  return (lhs.size() == rhs.size()) &&
+         (std::memcmp(lhs.ptr(), rhs.ptr(), lhs.size()) == 0);
+}
+
+inline bool operator!=(const Slice &lhs, const Slice &rhs) {
+  return !(lhs == rhs);
+}
+
+}  // namespace grnxx
+
+#endif  // GRNXX_SLICE_HPP

  Modified: test/Makefile.am (+4 -0)
===================================================================
--- test/Makefile.am    2013-02-08 16:11:46 +0900 (f996a6d)
+++ test/Makefile.am    2013-02-12 22:44:52 +0900 (ba11422)
@@ -22,6 +22,7 @@ TESTS =				\
 	test_mutex		\
 	test_os			\
 	test_recycler		\
+	test_slice		\
 	test_string		\
 	test_string_builder	\
 	test_string_format	\
@@ -93,6 +94,9 @@ test_os_LDADD = ../lib/libgrnxx.la
 test_recycler_SOURCES = test_recycler.cpp
 test_recycler_LDADD = ../lib/libgrnxx.la
 
+test_slice_SOURCES = test_slice.cpp
+test_slice_LDADD = ../lib/libgrnxx.la
+
 test_string_SOURCES = test_string.cpp
 test_string_LDADD = ../lib/libgrnxx.la
 

  Added: test/test_slice.cpp (+186 -0) 100644
===================================================================
--- /dev/null
+++ test/test_slice.cpp    2013-02-12 22:44:52 +0900 (b3410fb)
@@ -0,0 +1,186 @@
+/*
+  Copyright (C) 2013  Brazil, Inc.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#include <cassert>
+
+#include "logger.hpp"
+#include "slice.hpp"
+
+void test_constructors() {
+  grnxx::Slice slice;
+
+  assert(!slice);
+  assert(!slice.ptr());
+  assert(slice.size() == 0);
+
+  const char *empty_str = "";
+  slice = grnxx::Slice(empty_str);
+
+  assert(!slice);
+  assert(slice.ptr() == empty_str);
+  assert(slice.size() == 0);
+
+  const char *digits = "0123456789";
+  slice = grnxx::Slice(digits);
+
+  assert(slice);
+  assert(slice.ptr() == digits);
+  assert(slice.size() == 10);
+
+  slice = grnxx::Slice(digits + 3, 5);
+
+  assert(slice);
+  assert(slice.ptr() == digits + 3);
+  assert(slice.size() == 5);
+}
+
+void test_prefix() {
+  grnxx::Slice slice("0123456789");
+  grnxx::Slice prefix = slice.prefix(0);
+
+  assert(!prefix);
+  assert(prefix.ptr() == slice.ptr());
+  assert(prefix.size() == 0);
+
+  prefix = slice.prefix(5);
+
+  assert(prefix);
+  assert(prefix.ptr() == slice.ptr());
+  assert(prefix.size() == 5);
+}
+
+void test_suffix() {
+  grnxx::Slice slice("0123456789");
+  grnxx::Slice suffix = slice.suffix(0);
+
+  assert(!suffix);
+  assert(suffix.ptr() == (slice.ptr() + 10));
+  assert(suffix.size() == 0);
+
+  suffix = slice.suffix(5);
+
+  assert(suffix);
+  assert(suffix.ptr() == (slice.ptr() + 5));
+  assert(suffix.size() == 5);
+}
+
+void test_subslice() {
+  grnxx::Slice slice("0123456789");
+  grnxx::Slice subslice = slice.subslice(5, 0);
+
+  assert(!subslice);
+  assert(subslice.ptr() == (slice.ptr() + 5));
+  assert(subslice.size() == 0);
+
+  subslice = slice.subslice(3, 5);
+
+  assert(subslice);
+  assert(subslice.ptr() == (slice.ptr() + 3));
+  assert(subslice.size() == 5);
+}
+
+void test_remove_prefix() {
+  grnxx::Slice slice("0123456789");
+  grnxx::Slice suffix = slice;
+
+  suffix.remove_prefix(0);
+  assert(suffix == slice);
+
+  suffix.remove_prefix(3);
+  assert(suffix == slice.suffix(7));
+
+  suffix.remove_prefix(5);
+  assert(suffix == slice.suffix(2));
+
+  suffix.remove_prefix(2);
+  assert(suffix == slice.suffix(0));
+}
+
+void test_remove_suffix() {
+  grnxx::Slice slice("0123456789");
+  grnxx::Slice prefix = slice;
+
+  prefix.remove_suffix(0);
+  assert(prefix == slice);
+
+  prefix.remove_suffix(3);
+  assert(prefix == slice.prefix(7));
+
+  prefix.remove_suffix(5);
+  assert(prefix == slice.prefix(2));
+
+  prefix.remove_suffix(2);
+  assert(prefix == slice.prefix(0));
+}
+
+void test_compare() {
+  grnxx::Slice abc("abc");
+  grnxx::Slice abcde("abcde");
+  grnxx::Slice cde("cde");
+
+  assert(abc.compare(abc) == 0);
+  assert(abc.compare(abcde) < 0);
+  assert(abc.compare(cde) < 0);
+
+  assert(abcde.compare(abc) > 0);
+  assert(abcde.compare(abcde) == 0);
+  assert(abcde.compare(cde) < 0);
+
+  assert(cde.compare(abc) > 0);
+  assert(cde.compare(abcde) > 0);
+  assert(cde.compare(cde) == 0);
+}
+
+void test_starts_with() {
+  grnxx::Slice slice("cde");
+
+  assert(slice.starts_with(""));
+  assert(slice.starts_with("c"));
+  assert(slice.starts_with("cd"));
+  assert(slice.starts_with("cde"));
+  assert(!slice.starts_with("cdef"));
+  assert(!slice.starts_with("abc"));
+}
+
+void test_ends_with() {
+  grnxx::Slice slice("cde");
+
+  assert(slice.ends_with(""));
+  assert(slice.ends_with("e"));
+  assert(slice.ends_with("de"));
+  assert(slice.ends_with("cde"));
+  assert(!slice.ends_with("bcde"));
+  assert(!slice.ends_with("abc"));
+}
+
+int main() {
+  grnxx::Logger::set_flags(grnxx::LOGGER_WITH_ALL |
+                           grnxx::LOGGER_ENABLE_COUT);
+  grnxx::Logger::set_max_level(grnxx::NOTICE_LOGGER);
+
+  test_constructors();
+  test_prefix();
+  test_suffix();
+  test_subslice();
+  test_remove_prefix();
+  test_remove_suffix();
+  test_compare();
+  test_starts_with();
+  test_ends_with();
+
+  return 0;
+}
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る