diff --git a/include/TINYSTL/string.h b/include/TINYSTL/string.h index 677cff9..2382be6 100644 --- a/include/TINYSTL/string.h +++ b/include/TINYSTL/string.h @@ -38,170 +38,477 @@ namespace tinystl { string(); string(const string& other); string(const char* sz); + string(const char* first, const char* last); string(const char* sz, size_t len); ~string(); string& operator=(const string& other); + string& operator=(char ch); + string& operator=(const char* sz); + + string& operator+=(const string& other); + string& operator+=(char ch); + string& operator+=(const char* sz); const char* c_str() const; + bool empty() const; size_t size() const; + size_t capacity() const; + + typedef char* iterator; + iterator begin(); + iterator end(); + + typedef const char* const_iterator; + const_iterator begin() const; + const_iterator end() const; + + char operator[](size_t pos) const; + char& operator[](size_t pos); + + int compare(const string& other) const; + int compare(const char* sz) const; - void reserve(size_t size); - void resize(size_t size); + void reserve(size_t capacity); + void resize(size_t n); + void resize(size_t n, char ch); + void clear(); + + void assign(char ch); + void assign(const char* sz); + void assign(const char* first, const char* last); + void assign(const string& other); + + void push_back(char ch); + void append(const char* sz); void append(const char* first, const char* last); + void append(const string& other); + void insert(iterator where, char ch); + void insert(iterator where, const char* sz); + void insert(iterator where, const char* first, const char* last); + void insert(iterator where, const string& other); + void erase(iterator first, iterator last); void swap(string& other); private: typedef char* pointer; - pointer m_first; - pointer m_last; - pointer m_capacity; - - static const size_t c_nbuffer = 12; - char m_buffer[12]; + static const size_t c_nbuffer = 16; + static const size_t c_longflag = ((size_t)1) << (sizeof(size_t) * 8 - 1); + size_t m_size; + union { + struct { + pointer m_first; + pointer m_capacity; + }; + char m_buffer[c_nbuffer]; + }; }; inline string::string() - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) + : m_size(0) { - resize(0); + m_buffer[0] = 0; } inline string::string(const string& other) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) + : m_size(0) { - reserve(other.size()); - append(other.m_first, other.m_last); + assign(other); } inline string::string(const char* sz) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) + : m_size(0) { - size_t len = 0; - for (const char* it = sz; *it; ++it) - ++len; + assign(sz); + } - reserve(len); - append(sz, sz + len); + inline string::string(const char* first, const char* last) + : m_size(0) + { + assign(first, last); } inline string::string(const char* sz, size_t len) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) + : m_size(0) { - reserve(len); append(sz, sz + len); } inline string::~string() { - if (m_first != m_buffer) + if (m_size & c_longflag) TINYSTL_ALLOCATOR::static_deallocate(m_first, m_capacity - m_first); } inline string& string::operator=(const string& other) { - string(other).swap(*this); + if (this != &other) + assign(other); + return *this; + } + + inline string& string::operator=(char ch) { + assign(ch); + return *this; + } + + inline string& string::operator=(const char* sz) { + assign(sz); + return *this; + } + + inline string& string::operator+=(const string& other) { + append(other); + return *this; + } + + inline string& string::operator+=(char ch) { + push_back(ch); + return *this; + } + + inline string& string::operator+=(const char* sz) { + append(sz); return *this; } inline const char* string::c_str() const { - return m_first; + if (m_size & c_longflag) + return m_first; + else + return m_buffer; } - inline size_t string::size() const - { - return (size_t)(m_last - m_first); + inline bool string::empty() const { + return size() == 0; } - inline void string::reserve(size_t capacity) { - if (m_first + capacity + 1 <= m_capacity) - return; + inline size_t string::size() const { + return m_size & ~c_longflag; + } - const size_t size = (size_t)(m_last - m_first); + inline size_t string::capacity() const { + if (m_size & c_longflag) + return m_capacity - m_first - 1; + else + return c_nbuffer - 1; + } + + inline string::iterator string::begin() { + if (m_size & c_longflag) + return m_first; + else + return m_buffer; + } + + inline string::iterator string::end() { + if (m_size & c_longflag) + return m_first + (m_size & ~c_longflag); + else + return m_buffer + m_size; + } - pointer newfirst = (pointer)TINYSTL_ALLOCATOR::static_allocate(capacity + 1); - for (pointer it = m_first, newit = newfirst, end = m_last; it != end; ++it, ++newit) + inline string::const_iterator string::begin() const { + if (m_size & c_longflag) + return m_first; + else + return m_buffer; + } + + inline string::const_iterator string::end() const { + if (m_size & c_longflag) + return m_first + (m_size & ~c_longflag); + else + return m_buffer + m_size; + } + + inline char string::operator[](size_t pos) const { + return begin()[pos]; + } + + inline char& string::operator[](size_t pos) { + return begin()[pos]; + } + + inline int string::compare(const string& other) const { + return compare(other.c_str()); + } + + inline int string::compare(const char* sz) const { + const char* it = c_str(); + for (; *it && *sz && (*it == *sz); ++it, ++sz); + return *it - *sz; + } + + inline void string::reserve(size_t cap) { + if (cap <= capacity()) + return; + + pointer newfirst = (pointer)TINYSTL_ALLOCATOR::static_allocate(cap + 1); + for (pointer it = begin(), newit = newfirst, e = end() + 1; it != e; ++it, ++newit) *newit = *it; - if (m_first != m_buffer) + if (m_size & c_longflag) TINYSTL_ALLOCATOR::static_deallocate(m_first, m_capacity - m_first); - + else + m_size |= c_longflag; m_first = newfirst; - m_last = newfirst + size; - m_capacity = m_first + capacity; + m_capacity = m_first + cap + 1; + } + + inline void string::resize(size_t n) { + resize(n, 0); + } + + inline void string::resize(size_t n, char ch) { + if (size() < n) { + reserve(n); + for (pointer it = end(), e = begin() + n; it != e; ++it) + *it = ch; + } + pointer it = begin() + n; + *it = 0; + m_size = n | (m_size & c_longflag); + } + + inline void string::clear() { + resize(0); + } + + inline void string::assign(char ch) { + pointer it = begin(); + *it = ch; + *(it + 1) = 0; + m_size = 1 | (m_size & c_longflag); + } + + inline void string::assign(const char* sz) { + size_t len = 0; + for (const char *it = sz; *it; ++it) + ++len; + + assign(sz, sz + len); } - inline void string::resize(size_t size) { - reserve(size); - for (pointer it = m_last, end = m_first + size + 1; it < end; ++it) - *it = 0; + inline void string::assign(const char* first, const char* last) { + size_t newsize = last - first; + reserve(newsize); - m_last += size; + pointer newit = begin(); + for (const char* it = first; it != last; ++it, ++newit) + *newit = *it; + *newit = 0; + m_size = newsize | (m_size & c_longflag); + } + + inline void string::assign(const string& other) { + assign(other.begin(), other.end()); + } + + inline void string::push_back(char ch) { + if (size() != capacity()) { + pointer it = end(); + *it = ch; + *(it + 1) = 0; + ++m_size; + } else { + append(&ch, &ch + 1); + } + } + + inline void string::append(const char *sz) { + size_t len = 0; + for (const char *it = sz; *it; ++it) + ++len; + append(sz, sz + len); } inline void string::append(const char* first, const char* last) { - const size_t newsize = (size_t)((m_last - m_first) + (last - first) + 1); - if (m_first + newsize > m_capacity) + const size_t newsize = (size_t)(size() + (last - first)); + if (newsize > capacity()) reserve((newsize * 3) / 2); - for (; first != last; ++m_last, ++first) - *m_last = *first; - *m_last = 0; + pointer newit = end(); + for (const char* it = first; it != last; ++it, ++newit) + *newit = *it; + *newit = 0; + m_size = newsize | (m_size & c_longflag); } - inline void string::swap(string& other) { - const pointer tfirst = m_first, tlast = m_last, tcapacity = m_capacity; - m_first = other.m_first, m_last = other.m_last, m_capacity = other.m_capacity; - other.m_first = tfirst, other.m_last = tlast, other.m_capacity = tcapacity; + inline void string::append(const string& other) { + append(other.begin(), other.end()); + } - char tbuffer[c_nbuffer]; + inline void string::insert(iterator where, char ch) { + insert(where, &ch, &ch + 1); + } + + inline void string::insert(iterator where, const char* sz) { + size_t len = 0; + for (const char *it = sz; *it; ++it) + ++len; + insert(where, sz, sz + len); + } + + inline void string::insert(iterator where, const char* first, const char* last) { + if (first == last) + return; + + const size_t w = where - begin(); + const size_t newsize = (size_t)(size() + (last - first)); + if (newsize > capacity()) + reserve((newsize * 3) / 2); - if (m_first == other.m_buffer) - for (pointer it = other.m_buffer, end = m_last, out = tbuffer; it != end; ++it, ++out) - *out = *it; + pointer newit = begin() + newsize; + for (pointer it = end(), e = begin() + w; it >= e; --it, --newit) + *newit = *it; + + newit = begin() + w; + for (const char* it = first; it != last; ++it, ++newit) + *newit = *it; + m_size = newsize | (m_size & c_longflag); + } + + inline void string::insert(iterator where, const string& other) { + insert(where, other.begin(), other.end()); + } + + inline void string::erase(iterator first, iterator last) { + if (first == last) + return; + + const size_t newsize = (size_t)(size() + (first - last)); + pointer newit = first; + for (pointer it = last, e = end(); it != e; ++it, ++newit) + *newit = *it; + *newit = 0; + m_size = newsize | (m_size & c_longflag); + } - if (other.m_first == m_buffer) { - other.m_last = other.m_last - other.m_first + other.m_buffer; - other.m_first = other.m_buffer; - other.m_capacity = other.m_buffer + c_nbuffer; + inline void string::swap(string& other) { + const size_t tsize = m_size; + pointer tfirst, tcapacity; + char tbuffer[c_nbuffer]; - for (pointer it = other.m_first, end = other.m_last, in = m_buffer; it != end; ++it, ++in) - *it = *in; - *other.m_last = 0; + if (tsize & c_longflag) { + tfirst = m_first; + tcapacity = m_capacity; + } else { + for (pointer it = m_buffer, newit = tbuffer, e = m_buffer + tsize + 1; it != e; ++it, ++newit) + *newit = *it; } - if (m_first == other.m_buffer) { - m_last = m_last - m_first + m_buffer; - m_first = m_buffer; - m_capacity = m_buffer + c_nbuffer; + m_size = other.m_size; + if (other.m_size & c_longflag) { + m_first = other.m_first; + m_capacity = other.m_capacity; + } else { + for (pointer it = other.m_buffer, newit = m_buffer, e = other.m_buffer + m_size + 1; it != e; ++it, ++newit) + *newit = *it; + } - for (pointer it = m_first, end = m_last, in = tbuffer; it != end; ++it, ++in) - *it = *in; - *m_last = 0; + other.m_size = tsize; + if (tsize & c_longflag) { + other.m_first = tfirst; + other.m_capacity = tcapacity; + } else { + for (pointer it = tbuffer, newit = other.m_buffer, e = tbuffer + tsize + 1; it != e; ++it, ++newit) + *newit = *it; } } - inline bool operator==(const string& lhs, const string& rhs) { - typedef const char* pointer; + inline string operator+(const string& lhs, const string& rhs) { + string ret; + ret.reserve(lhs.size() + rhs.size()); + ret += lhs; + ret += rhs; + return ret; + } + + inline string operator+(const string& lhs, const char* rhs) { + string ret = lhs; + ret += rhs; + return ret; + } - const size_t lsize = lhs.size(), rsize = rhs.size(); - if (lsize != rsize) + inline string operator+(const char* lhs, const string& rhs) { + string ret = lhs; + ret += rhs; + return ret; + } + + inline bool operator==(const string& lhs, const string& rhs) { + if (lhs.size() != rhs.size()) return false; - pointer lit = lhs.c_str(), rit = rhs.c_str(); - pointer lend = lit + lsize; - while (lit != lend) - if (*lit++ != *rit++) - return false; + return lhs.compare(rhs) == 0; + } + + inline bool operator==(const string& lhs, const char* rhs) { + return lhs.compare(rhs) == 0; + } + + inline bool operator==(const char* lhs, const string& rhs) { + return rhs.compare(lhs) == 0; + } + + inline bool operator!=(const string& lhs, const string& rhs) { + return !(lhs == rhs); + } + + inline bool operator!=(const string& lhs, const char* rhs) { + return !(lhs == rhs); + } + + inline bool operator!=(const char* lhs, const string& rhs) { + return !(lhs == rhs); + } + + inline bool operator<(const string& lhs, const string& rhs) { + return lhs.compare(rhs) < 0; + } + + inline bool operator<(const string& lhs, const char* rhs) { + return lhs.compare(rhs) < 0; + } + + inline bool operator<(const char* lhs, const string& rhs) { + return rhs.compare(lhs) > 0; + } + + inline bool operator>(const string& lhs, const string& rhs) { + return rhs < lhs; + } + + inline bool operator>(const string& lhs, const char* rhs) { + return rhs < lhs; + } + + inline bool operator>(const char* lhs, const string& rhs) { + return rhs < lhs; + } + + inline bool operator<=(const string& lhs, const string& rhs) { + return !(rhs < lhs); + } + + inline bool operator<=(const string& lhs, const char* rhs) { + return !(rhs < lhs); + } + + inline bool operator<=(const char* lhs, const string& rhs) { + return !(rhs < lhs); + } + + inline bool operator>=(const string& lhs, const string& rhs) { + return !(lhs < rhs); + } + + inline bool operator>=(const string& lhs, const char* rhs) { + return !(lhs < rhs); + } - return true; + inline bool operator>=(const char* lhs, const string& rhs) { + return !(lhs < rhs); } static inline size_t hash(const string& value) { diff --git a/test/string_assign.cpp b/test/string_assign.cpp new file mode 100644 index 0000000..13ca126 --- /dev/null +++ b/test/string_assign.cpp @@ -0,0 +1,123 @@ +/*- + * Copyright 2012-2015 Matthew Endsley + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +TEST(test_empty) { + tinystl::string s; + CHECK(s.empty()); + CHECK(s.capacity() == 15); + CHECK(s.begin() == s.end()); + CHECK(strlen(s.c_str()) == 0); + CHECK(s == ""); +} + +TEST(test_small) { + tinystl::string s1(""); + CHECK(s1.empty()); + CHECK(s1.capacity() == 15); + CHECK(s1.begin() == s1.end()); + CHECK(strlen(s1.c_str()) == 0); + CHECK(s1 == ""); + + tinystl::string s2("hello"); + CHECK(s2.size() == 5); + CHECK(s2.capacity() == 15); + CHECK(s2.begin() + 5 == s2.end()); + CHECK(strlen(s2.c_str()) == 5); + CHECK(s2 == "hello"); + + tinystl::string s3("exactly 15 char"); + CHECK(s3.size() == 15); + CHECK(s3.capacity() == 15); + CHECK(s3.begin() + 15 == s3.end()); + CHECK(strlen(s3.c_str()) == 15); + CHECK(s3 == "exactly 15 char"); +} + +TEST(test_long) { + const char* origin = "very long string larger than large string limit"; + size_t len = strlen(origin); + tinystl::string s(origin); + CHECK(s.size() == len); + CHECK(s.capacity() == len); + CHECK(s.begin() + len == s.end()); + CHECK(strlen(s.c_str()) == len); + CHECK(s == origin); +} + +TEST(test_assign) { + tinystl::string s; + const char* originshort = "short"; + size_t lenshort = strlen(originshort); + s = originshort; + CHECK(s.size() == lenshort); + CHECK(s.capacity() == 15); + CHECK(s.begin() + lenshort == s.end()); + CHECK(strlen(s.c_str()) == lenshort); + CHECK(s == originshort); + + const char* originlong = "long long long long long long long long long long long long"; + size_t lenlong = strlen(originlong); + s = originlong; + CHECK(s.size() == lenlong); + CHECK(s.capacity() == lenlong); + CHECK(s.begin() + lenlong == s.end()); + CHECK(strlen(s.c_str()) == lenlong); + CHECK(s == originlong); + + s = originshort; + CHECK(s.size() == lenshort); + CHECK(s.capacity() == lenlong); + CHECK(s.begin() + lenshort == s.end()); + CHECK(strlen(s.c_str()) == lenshort); + CHECK(s == originshort); +} + +TEST(test_swap) { + tinystl::string ss1("short"); + tinystl::string ss2("another"); + tinystl::string sl1("long string for testing purposes"); + tinystl::string sl2("another long string for testing purposes"); + + ss1.swap(ss2); + CHECK(ss1 == "another"); + CHECK(ss2 == "short"); + + sl1.swap(sl2); + CHECK(sl1 == "another long string for testing purposes"); + CHECK(sl2 == "long string for testing purposes"); + + ss1.swap(sl2); + CHECK(ss1 == "long string for testing purposes"); + CHECK(sl2 == "another"); + + sl1.swap(ss2); + CHECK(sl1 == "short"); + CHECK(ss2 == "another long string for testing purposes"); +} \ No newline at end of file diff --git a/test/string_compare.cpp b/test/string_compare.cpp new file mode 100644 index 0000000..891fe1a --- /dev/null +++ b/test/string_compare.cpp @@ -0,0 +1,70 @@ +/*- + * Copyright 2012-2015 Matthew Endsley + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +TEST(test_equal) { + tinystl::string s("hello"); + CHECK(s == tinystl::string("hello")); + CHECK(s == "hello"); + CHECK("hello" == s); + CHECK(s != tinystl::string("hello world")); + CHECK(s != "hello world"); + CHECK("hello world" != s); +} + +TEST(test_ltgt) { + tinystl::string s("hello"); + CHECK(!(s < "hello")); + CHECK(s < "helloo"); + CHECK(s < "hello0"); + CHECK(s > "he1"); + CHECK(s > "hell"); + CHECK(s > "a"); + CHECK(s < "z"); + CHECK(s > "aaaaaaaa"); + CHECK(s < "zzzzzzzz"); + CHECK(s > "hella"); + CHECK(s < "hellz"); + CHECK(s < "hellz"); +} + +TEST(test_lege) { + tinystl::string s("hello"); + CHECK(s <= "hello"); + CHECK(s >= "hello"); + CHECK(s <= "helloo"); + CHECK(s <= "hello0"); + CHECK(s >= "he1"); + CHECK(s >= "hell"); + CHECK(s >= "a"); + CHECK(s <= "z"); + CHECK(s >= "aaaaaaaa"); + CHECK(s <= "zzzzzzzz"); + CHECK(s >= "hella"); + CHECK(s <= "hellz"); + CHECK(s <= "hellz"); +} \ No newline at end of file diff --git a/test/string_modify.cpp b/test/string_modify.cpp new file mode 100644 index 0000000..4057345 --- /dev/null +++ b/test/string_modify.cpp @@ -0,0 +1,71 @@ +/*- + * Copyright 2012-2015 Matthew Endsley + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +TEST(test_append) { + tinystl::string s; + s += "hello"; + s += ' '; + s += "world"; + CHECK(s == "hello world"); + s += " and this is a very long string"; + CHECK(s == "hello world and this is a very long string"); +} + +TEST(test_add) { + CHECK(tinystl::string("hello") + tinystl::string(" world") == "hello world"); + CHECK(tinystl::string("hello") + " world" == "hello world"); + CHECK(tinystl::string("hello") + " " + "world" == "hello world"); + CHECK("hello" + tinystl::string(" ") + "world" == "hello world"); +} + +TEST(test_insert) { + tinystl::string s("world"); + s.insert(s.end(), '!'); + CHECK(s == "world!"); + s.insert(s.begin(), "hello"); + CHECK(s == "helloworld!"); + s.insert(s.begin() + 5, " "); + CHECK(s == "hello world!"); + s.insert(s.end() - 1, ", prepend a huge string to check"); + CHECK(s == "hello world, prepend a huge string to check!"); +} + +TEST(test_erase) { + tinystl::string s("hello"); + s.erase(s.begin(), s.end()); + CHECK(s.empty()); + s = "hello"; + s.erase(s.end() - 1, s.end()); + CHECK(s == "hell"); + s = "hello world and this is a very long string"; + s.erase(s.begin(), s.begin() + 4); + CHECK(s == "o world and this is a very long string"); + s.erase(s.begin(), s.end()); + CHECK(s.empty()); +} \ No newline at end of file diff --git a/test/string_resize.cpp b/test/string_resize.cpp new file mode 100644 index 0000000..8a1344f --- /dev/null +++ b/test/string_resize.cpp @@ -0,0 +1,61 @@ +/*- + * Copyright 2012-2015 Matthew Endsley + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +TEST(test_reserve) { + tinystl::string s; + s.reserve(0); + CHECK(s.capacity() == 15); + s.reserve(10); + s = "short"; + CHECK(s.capacity() == 15); + CHECK(s == "short"); + s.reserve(15); + CHECK(s.capacity() == 15); + CHECK(s == "short"); + s.reserve(100); + CHECK(s.capacity() == 100); + CHECK(s == "short"); + s.reserve(101); + CHECK(s.capacity() == 101); + CHECK(s == "short"); +} + +TEST(test_resize) { + tinystl::string s; + s.resize(1, ' '); + CHECK(s == " "); + s.resize(16, '+'); + CHECK(s == " +++++++++++++++"); + s.clear(); + s.resize(16, '@'); + CHECK(s == "@@@@@@@@@@@@@@@@"); + s.resize(12, '-'); + CHECK(s == "@@@@@@@@@@@@"); +} \ No newline at end of file