aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Catania <niko@google.com>2010-01-20 18:26:31 -0800
committerNicolas Catania <niko@google.com>2010-01-20 21:52:57 -0800
commit48d768f7d32790ee7f6691367dc543fda1f1181c (patch)
tree5234caf3c91fc79ee632518ba559330e40b3b04c
parent91ea6c037471a1acd97b03c3097223777906f748 (diff)
downloadastl-48d768f7d32790ee7f6691367dc543fda1f1181c.tar.gz
Added iterator support to the vector class.
In iterator, implemented the iterator diff operator. Minor renaming of some parameters in the iterator functions. More tests to exercise the iterator arithmetic.
-rw-r--r--include/iterator40
-rw-r--r--include/vector17
-rw-r--r--tests/test_vector.cpp25
3 files changed, 60 insertions, 22 deletions
diff --git a/include/iterator b/include/iterator
index b983a1c..3dee58f 100644
--- a/include/iterator
+++ b/include/iterator
@@ -165,27 +165,43 @@ class __wrapper_iterator
// Forward iterator requirements
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
-operator==(const __wrapper_iterator<_IteratorL, _Container>& __lhs,
- const __wrapper_iterator<_IteratorR, _Container>& __rhs)
-{ return __lhs.base() == __rhs.base(); }
+operator==(const __wrapper_iterator<_IteratorL, _Container>& lhs,
+ const __wrapper_iterator<_IteratorR, _Container>& rhs)
+{ return lhs.base() == rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
-operator==(const __wrapper_iterator<_Iterator, _Container>& __lhs,
- const __wrapper_iterator<_Iterator, _Container>& __rhs)
-{ return __lhs.base() == __rhs.base(); }
+operator==(const __wrapper_iterator<_Iterator, _Container>& lhs,
+ const __wrapper_iterator<_Iterator, _Container>& rhs)
+{ return lhs.base() == rhs.base(); }
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
-operator!=(const __wrapper_iterator<_IteratorL, _Container>& __lhs,
- const __wrapper_iterator<_IteratorR, _Container>& __rhs)
-{ return __lhs.base() != __rhs.base(); }
+operator!=(const __wrapper_iterator<_IteratorL, _Container>& lhs,
+ const __wrapper_iterator<_IteratorR, _Container>& rhs)
+{ return lhs.base() != rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
-operator!=(const __wrapper_iterator<_Iterator, _Container>& __lhs,
- const __wrapper_iterator<_Iterator, _Container>& __rhs)
-{ return __lhs.base() != __rhs.base(); }
+operator!=(const __wrapper_iterator<_Iterator, _Container>& lhs,
+ const __wrapper_iterator<_Iterator, _Container>& rhs)
+{ return lhs.base() != rhs.base(); }
+
+// operator+ so we support 100 + iterator<>.
+template<typename _Iterator, typename _Container>
+inline __wrapper_iterator<_Iterator, _Container>
+operator+(typename __wrapper_iterator<_Iterator, _Container>::difference_type n,
+ const __wrapper_iterator<_Iterator, _Container>& i)
+{ return __wrapper_iterator<_Iterator, _Container>(i.base() + n); }
+
+// operator- : diff is supported on iterators.
+
+template<typename _Iterator, typename _Container>
+inline typename __wrapper_iterator<_Iterator, _Container>::difference_type
+operator-(const __wrapper_iterator<_Iterator, _Container>& lhs,
+ const __wrapper_iterator<_Iterator, _Container>& rhs)
+{ return lhs.base() - rhs.base(); }
+
} // namespace std
diff --git a/include/vector b/include/vector
index 978d4d1..b5f363a 100644
--- a/include/vector
+++ b/include/vector
@@ -34,6 +34,7 @@
#include <cstdlib>
#include <cstring>
#include <algorithm>
+#include <iterator>
#include <memory>
#include <type_traits.h>
@@ -58,6 +59,8 @@ namespace std {
template<typename _T>
class vector
{
+ typedef vector<_T> vector_type;
+
public:
typedef _T value_type;
typedef _T* pointer;
@@ -65,8 +68,8 @@ class vector
typedef _T& reference;
typedef const _T& const_reference;
- typedef pointer iterator;
- typedef const_pointer const_iterator;
+ typedef __wrapper_iterator<pointer,vector_type> iterator;
+ typedef __wrapper_iterator<const_pointer,vector_type> const_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
@@ -112,13 +115,11 @@ class vector
// @return A reference to the element.
reference operator[](size_type index) { return *(mBegin + index); }
- // We don't have iterator, use pointers for now. begin and end
- // return NULL if the vector has been cleared or not initialized.
- iterator begin() { return mBegin; }
- iterator end() { return mBegin + mLength; }
+ iterator begin() { return iterator(mBegin); }
+ iterator end() { return iterator(mBegin + mLength); }
- const_iterator begin() const { return mBegin; }
- const_iterator end() const { return mBegin + mLength; }
+ const_iterator begin() const { return const_iterator(mBegin); }
+ const_iterator end() const { return const_iterator(mBegin + mLength); }
// Add data at the end of the vector. Constant in time if the
// memory has been preallocated (e.g using reserve).
diff --git a/tests/test_vector.cpp b/tests/test_vector.cpp
index 99007b7..2412607 100644
--- a/tests/test_vector.cpp
+++ b/tests/test_vector.cpp
@@ -78,7 +78,6 @@ bool testConstructorRepeat()
{
const vector<int> vec1(100, 10);
- EXPECT_TRUE(vec1.end() - vec1.begin() == 100);
for (int i = 0; i < 100; ++i)
{
EXPECT_TRUE(vec1[i] == 10);
@@ -239,7 +238,7 @@ bool testPopBack()
EXPECT_TRUE(vec1.size() == 0);
EXPECT_TRUE(vec1.capacity() == 0);
EXPECT_TRUE(vec1.begin() == vec1.end());
- EXPECT_TRUE(vec1.begin() == NULL);
+ EXPECT_TRUE(vec1.begin().base() == NULL);
CtorDtorCounter instance;
vector<CtorDtorCounter> vec2(10, instance);
@@ -294,6 +293,28 @@ bool testIterators()
{
EXPECT_TRUE(c == *j);
}
+
+ {
+ const vector<int> vec1(100, 10);
+
+ EXPECT_TRUE(vec1.end().operator-(100) == vec1.begin());
+ EXPECT_TRUE(vec1.end() - 100 == vec1.begin());
+
+ EXPECT_TRUE(100 + vec1.begin() == vec1.end());
+ EXPECT_TRUE(vec1.begin() + 100 == vec1.end());
+
+ EXPECT_TRUE(vec1.end() - vec1.begin() == 100);
+
+ for (vector<int>::const_iterator i = vec1.begin();
+ i != vec1.end(); ++i) {
+ EXPECT_TRUE(*i == 10);
+ }
+ }
+
+ {
+ const vector<int> vec2;
+ EXPECT_TRUE(vec2.begin() == vec2.end());
+ }
return true;
}