aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Catania <niko@google.com>2010-02-08 23:13:32 -0800
committerNicolas Catania <niko@google.com>2010-02-11 11:06:28 -0800
commit0cc3ee31c3cddd2bb5322398d17c388975e96d64 (patch)
tree08fcd38daf190d1ee67d705520c9692e0ec0afe9
parentbe8a5178d184c6ebfe11ba5ff3b37b5ca7a4bb60 (diff)
downloadastl-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/string35
-rw-r--r--src/string.cpp16
-rw-r--r--tests/test_string.cpp37
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;
}