Skip to content

Commit

Permalink
Extending sstring
Browse files Browse the repository at this point in the history
This patch adds some of the common functionalities from std:string to
sstring.

It adds length (implement by size() )
It define the constant npos to indicate no possition.
It adds the at (reference and const reference)
It define the find char and find sstring methods
and the substr method

Signed-off-by: Amnon Heiman <[email protected]>

need merge sstring
  • Loading branch information
amnonh committed Mar 8, 2015
1 parent 100a667 commit 29391d9
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
68 changes: 68 additions & 0 deletions core/sstring.hh
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public:
// FIXME: add reverse_iterator and friend
using difference_type = ssize_t; // std::make_signed_t<Size> can be too small
using size_type = Size;
static constexpr size_type npos = static_cast<size_type>(-1);
public:
struct initialized_later {};

Expand Down Expand Up @@ -170,6 +171,71 @@ public:
size_t size() const noexcept {
return is_internal() ? u.internal.size : u.external.size;
}

size_t length() const noexcept {
return size();
}

size_t find(char_type t, size_t pos = 0) const noexcept {
const char_type* it = str() + pos;
const char_type* end = it + size();
while (it < end) {
if (*it == t) {
return it - str();
}
it++;
}
return npos;
}

size_t find(const basic_sstring& s, size_t pos = 0) const noexcept {
const char_type* it = str() + pos;
const char_type* end = it + size();
const char_type* c_str = s.str();
const char_type* c_str_end = s.str() + s.size();

while (it < end) {
auto i = it;
auto j = c_str;
while ( i < end && j < c_str_end && *i == *j) {
i++;
j++;
}
if (j == c_str_end) {
return it - str();
}
it++;
}
return npos;
}

basic_sstring substr(size_t from, size_t len = npos) const {
if (from > size()) {
throw std::out_of_range("sstring::substr out of range");
}
if (len > size() - from) {
len = size() - from;
}
if (len == 0) {
return "";
}
return { str() + from , len };
}

const char_type& at(size_t pos) const {
if (pos >= size()) {
throw std::out_of_range("sstring::at out of range");
}
return *(str() + pos);
}

char_type& at(size_t pos) {
if (pos >= size()) {
throw std::out_of_range("sstring::at out of range");
}
return *(str() + pos);
}

bool empty() const noexcept {
return u.internal.size == 0;
}
Expand Down Expand Up @@ -250,6 +316,8 @@ public:
return std::experimental::string_view(str(), size());
}
};
template <typename char_type, typename Size, Size max_size>
constexpr Size basic_sstring<char_type, Size, max_size>::npos;

template <typename char_type, typename size_type, size_type Max, size_type N>
inline
Expand Down
39 changes: 39 additions & 0 deletions tests/sstring_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,42 @@ BOOST_AUTO_TEST_CASE(test_to_sstring) {
BOOST_AUTO_TEST_CASE(test_add_literal_to_sstring) {
BOOST_REQUIRE_EQUAL("x" + sstring("y"), sstring("xy"));
}

BOOST_AUTO_TEST_CASE(test_find_sstring) {
BOOST_REQUIRE_EQUAL(sstring("abcde").find('b'), 1);
BOOST_REQUIRE_EQUAL(sstring("babcde").find('b',1), 2);
}

BOOST_AUTO_TEST_CASE(test_not_find_sstring) {
BOOST_REQUIRE_EQUAL(sstring("abcde").find('x'), sstring::npos);
}

BOOST_AUTO_TEST_CASE(test_str_find_sstring) {
BOOST_REQUIRE_EQUAL(sstring("abcde").find("bc"), 1);
BOOST_REQUIRE_EQUAL(sstring("abcbcde").find("bc", 2), 3);
}

BOOST_AUTO_TEST_CASE(test_str_not_find_sstring) {
BOOST_REQUIRE_EQUAL(sstring("abcde").find("x"), sstring::npos);
}

BOOST_AUTO_TEST_CASE(test_substr_sstring) {
BOOST_REQUIRE_EQUAL(sstring("abcde").substr(1,2), "bc");
BOOST_REQUIRE_EQUAL(sstring("abc").substr(1,2), "bc");
BOOST_REQUIRE_EQUAL(sstring("abc").substr(1,3), "bc");
BOOST_REQUIRE_EQUAL(sstring("abc").substr(0, 2), "ab");
BOOST_REQUIRE_EQUAL(sstring("abc").substr(3, 2), "");
BOOST_REQUIRE_EQUAL(sstring("abc").substr(1), "bc");
}

BOOST_AUTO_TEST_CASE(test_substr_eor_sstring) {
BOOST_REQUIRE_THROW(sstring("abcde").substr(6,1), std::out_of_range);
}

BOOST_AUTO_TEST_CASE(test_at_sstring) {
BOOST_REQUIRE_EQUAL(sstring("abcde").at(1), 'b');
BOOST_REQUIRE_THROW(sstring("abcde").at(6), std::out_of_range);
sstring s("abcde");
s.at(1) = 'd';
BOOST_REQUIRE_EQUAL(s, "adcde");
}

0 comments on commit 29391d9

Please sign in to comment.