diff options
author | Nicolas Catania <niko@google.com> | 2010-02-08 23:13:32 -0800 |
---|---|---|
committer | Nicolas Catania <niko@google.com> | 2010-02-11 11:06:28 -0800 |
commit | 0cc3ee31c3cddd2bb5322398d17c388975e96d64 (patch) | |
tree | 08fcd38daf190d1ee67d705520c9692e0ec0afe9 | |
parent | be8a5178d184c6ebfe11ba5ff3b37b5ca7a4bb60 (diff) | |
download | astl-0cc3ee31c3cddd2bb5322398d17c388975e96d64.tar.gz |
Added string::append method that takes iterators as args.
Provided 2 specialization when the iterators comes from another
string (e.g begin(), end(), some search results...)
There is a test showing how iterators on a list of char can
be used to insert the list's content to a string.
-rw-r--r-- | include/string | 35 | ||||
-rw-r--r-- | src/string.cpp | 16 | ||||
-rw-r--r-- | tests/test_string.cpp | 37 |
3 files changed, 88 insertions, 0 deletions
diff --git a/include/string b/include/string index 428d1db..9f9d146 100644 --- a/include/string +++ b/include/string @@ -30,6 +30,7 @@ #ifndef ANDROID_ASTL_STRING__ #define ANDROID_ASTL_STRING__ +#include <algorithm> #include <cstddef> #include <iterator> #include <char_traits.h> @@ -161,6 +162,9 @@ class string string& append(const value_type *str, size_type pos, size_type n); string& append(const string& str); + template<typename _InputIterator> + string& append(_InputIterator first, _InputIterator last); + // Comparison. // @return 0 if this==other, < 0 if this < other and > 0 if this > other. // Don't assume the values are -1, 0, 1 @@ -325,6 +329,37 @@ void swap(string& lhs, string& rhs); // I/O ostream& operator<<(ostream& os, const string& str); + +// Specialization of append(iterator, iterator) using string iterators +// (const and non const). +template<> +string& string::append<__wrapper_iterator<const char *,string> >( + __wrapper_iterator<const char *,string> first, + __wrapper_iterator<const char *,string> last); +template<> +string& string::append<__wrapper_iterator<char *,string> >( + __wrapper_iterator<char *,string> first, + __wrapper_iterator<char *,string> last); + +// append(iterator,iterator) default implementation. +template<typename _InputIterator> +string& string::append(_InputIterator first, _InputIterator last) { + size_type dist = std::distance(first, last); + size_type new_len = mLength + dist; + if (new_len <= mLength) { + return *this; // 0 / overflow + } + reserve(new_len); + if (new_len > mCapacity) { + return *this; // memory allocation failed. + } + std::copy(first, last, mData + mLength); + mLength = new_len; + mData[mLength] = '\0'; + return *this; +} + + } // namespace std #endif // ANDROID_ASTL_STRING__ diff --git a/src/string.cpp b/src/string.cpp index 5c04c8e..930e77d 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -337,6 +337,22 @@ string& string::append(const string& str) return *this; } +// Specialization to append from other strings' iterators. +template<> +string& string::append<__wrapper_iterator<const char *,string> >( + __wrapper_iterator<const char *,string> first, + __wrapper_iterator<const char *,string> last) { + Append(&*first, std::distance(first, last)); + return *this; +} +template<> +string& string::append<__wrapper_iterator<char *,string> >( + __wrapper_iterator<char *,string> first, + __wrapper_iterator<char *,string> last) { + Append(&*first, std::distance(first, last)); + return *this; +} + void string::push_back(const char c) { // Check we don't overflow. diff --git a/tests/test_string.cpp b/tests/test_string.cpp index 0a9c1cc..f5c3d1a 100644 --- a/tests/test_string.cpp +++ b/tests/test_string.cpp @@ -34,6 +34,7 @@ #include <climits> #include <cstring> #include <algorithm> +#include <list> #include "common.h" @@ -386,6 +387,42 @@ bool testAppend() str12.append(dummy, kMaxSizeT); EXPECT_TRUE(str12 == "original"); + // Append iterator. + { + string str1("once upon "); + const string str2("a time"); + + str1.append(str2.begin(), str2.end()); + EXPECT_TRUE(str1.size() == 16); + EXPECT_TRUE(str1 == "once upon a time"); + } + { + string str1("once upon "); + string str2("a time"); + + str1.append(str2.begin(), str2.begin()); + EXPECT_TRUE(str1.size() == 10); + EXPECT_TRUE(str1 == "once upon "); + } + { + string str1; + string str2("hello"); + + str1.append(str2.begin(), str2.end()); + EXPECT_TRUE(str1.size() == 5); + EXPECT_TRUE(str1 == "hello"); + } + { + string str1("hello "); + std::list<char> list1; + list1.push_back('w'); + list1.push_back('o'); + list1.push_back('r'); + list1.push_back('l'); + list1.push_back('d'); + str1.append(list1.begin(), list1.end()); + EXPECT_TRUE(str1 == "hello world"); + } return true; } |