This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
basic_string/vector iterators
- To: libstdc++-v3@cygnus.com
- Subject: basic_string/vector iterators
- From: Philip Martin <pm@corris.dircon.co.uk>
- Date: Mon, 15 Feb 1999 22:50:52 +0000 (GMT)
Hello
Here is a second implementation of a class for basic_string and vector
iterators. The first significant difference between this and the
previous post is that the template parameter is now an iterator
instead of a value type. This makes the class a more general iterator
adapter, although I only see it being used to change pointers into
classes. The iterator_category of the class is that of the template
parameter and thus the class is not necessarily a random access
iterator.
This change made it necessary to alter the way that an iterator is
converted to a const_iterator. Previously there was an ordinary
member constructor, now there is a template member constructor. This
has the effect that the assignment of a const_iterator to an iterator
now generates the same warning/error that would be generated for the
template parameter: in the case of basic_string and vector a warning
about discarding const. The previous implementation generated an
error for this case.
A second change is that I have made the comparison operators
non-member functions, much as for reverse_iterator<>. I have also
added operator+(difference_type,iterator) which was missing from the
previous post.
I have finally manged to compile and run with -fnew-abi and the size
problem caused by inheriting from std::iterator is indeed removed.
Philip
-------------------------------------------------------------------------------
1999-02-14 Philip Martin <pm@corris.dircon.co.uk>
* bits/basic_string.h: use __normal_iterator<> for iterators
* bits/std_sstream.h: support __normal_iterator<> iterators
* bits/string.tcc: ditto
* src/misc-inst.cc: ditto
* stl/bits/stl_iterator.h: add __normal_iterator<>
* stl/bits/stl_vector.h: use __normal_iterator<> for iterators
* testsuite/24/24iterator.cc: Add test cases for basic_string and
vector iterators
diff -cprN libstdc++/bits/basic_string.h libstdc++-modified/bits/basic_string.h
*** libstdc++/bits/basic_string.h Fri Feb 12 19:40:15 1999
--- libstdc++-modified/bits/basic_string.h Mon Feb 15 20:33:29 1999
*************** namespace std {
*** 40,45 ****
--- 40,47 ----
template<class _CharT, class _Traits, class _Alloc>
class basic_string
{
+ private:
+ typedef basic_string<_CharT, _Traits, _Alloc> string_type;
public:
// Types:
typedef _Traits traits_type;
*************** namespace std {
*** 51,58 ****
typedef typename _Alloc::const_reference const_reference;
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
! typedef pointer iterator;
! typedef const_pointer const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
static const size_type npos = ~(size_type)0;
--- 53,60 ----
typedef typename _Alloc::const_reference const_reference;
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
! typedef __normal_iterator<pointer, string_type> iterator;
! typedef __normal_iterator<const_pointer, string_type> const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
static const size_type npos = ~(size_type)0;
*************** namespace std {
*** 141,148 ****
// For the internal use we have functions similar to `begin'/`end'
// but they do not call _M_leak.
! iterator _M_ibegin () const { return _M_data (); }
! iterator _M_iend () const { return _M_data () + this->size (); }
void _M_leak () // for use in begin() & non-const op[]
{ if (_M_rep ()->_M_state >= 0) _M_leak_hard(); }
--- 143,150 ----
// For the internal use we have functions similar to `begin'/`end'
// but they do not call _M_leak.
! iterator _M_ibegin () const { return iterator (_M_data ()); }
! iterator _M_iend () const { return iterator (_M_data () + this->size ()); }
void _M_leak () // for use in begin() & non-const op[]
{ if (_M_rep ()->_M_state >= 0) _M_leak_hard(); }
*************** namespace std {
*** 213,222 ****
{ return assign (1, __c); }
// Iterators:
! iterator begin () { _M_leak (); return &this->operator[](0); }
! const_iterator begin () const { return &(*_M_rep ())[0]; }
! iterator end () { _M_leak (); return &(this->operator[](length ())); }
! const_iterator end () const { return &(*_M_rep ())[length ()]; }
reverse_iterator rbegin ()
{ return reverse_iterator (end ()); }
--- 215,229 ----
{ return assign (1, __c); }
// Iterators:
! iterator begin () { _M_leak (); return iterator (&this->operator[](0)); }
! const_iterator begin () const { return const_iterator (&(*_M_rep ())[0]); }
! iterator end ()
! {
! _M_leak ();
! return iterator (&(this->operator[](length ())));
! }
! const_iterator end () const
! { return const_iterator (&(*_M_rep ())[length ()]); }
reverse_iterator rbegin ()
{ return reverse_iterator (end ()); }
diff -cprN libstdc++/bits/std_sstream.h libstdc++-modified/bits/std_sstream.h
*** libstdc++/bits/std_sstream.h Fri Feb 12 19:41:10 1999
--- libstdc++-modified/bits/std_sstream.h Sun Feb 14 17:01:15 1999
*************** namespace std {
*** 240,251 ****
virtual int sync()
{
! // Will eventually need to cast these to _Alloc::pointer or
! // string_type::iterator types.
if (_M_mode & ios_base::in)
! setg(_M_str.begin(), _M_str.begin(), _M_str.end());
if (_M_mode & ios_base::out)
! setp(_M_str.begin(), _M_str.end());
return 0;
}
--- 240,252 ----
virtual int sync()
{
! // using details of iterator implementation to convert
! // iterator to pointer
if (_M_mode & ios_base::in)
! setg(_M_str.begin().base(), _M_str.begin().base(),
! _M_str.end().base());
if (_M_mode & ios_base::out)
! setp(_M_str.begin().base(), _M_str.end().base());
return 0;
}
diff -cprN libstdc++/bits/string.tcc libstdc++-modified/bits/string.tcc
*** libstdc++/bits/string.tcc Thu Dec 31 23:15:39 1998
--- libstdc++-modified/bits/string.tcc Sun Feb 14 18:04:33 1999
*************** template<class _CharT, class _Traits, cl
*** 450,456 ****
_M_mutate (__newlen, __off1, _M_iend () - __i2);
// invalidated __i1, __i2
if (__n2)
! _S_copy_chars(_M_ibegin () + __off1, __j1, __j2);
return *this;
}
--- 450,456 ----
_M_mutate (__newlen, __off1, _M_iend () - __i2);
// invalidated __i1, __i2
if (__n2)
! _S_copy_chars(_M_data () + __off1, __j1, __j2);
return *this;
}
*************** basic_string<_CharT,_Traits,_Alloc>::rep
*** 477,483 ****
_M_mutate (__newlen, __off1, _M_iend () - __i2);
// invalidated __i1, __i2
if (__n2)
! _Traits::assign(_M_ibegin () + __off1, __n2, __c);
return *this;
}
--- 477,483 ----
_M_mutate (__newlen, __off1, _M_iend () - __i2);
// invalidated __i1, __i2
if (__n2)
! _Traits::assign(_M_data () + __off1, __n2, __c);
return *this;
}
*************** basic_string<_CharT,_Traits,_Alloc>::fin
*** 533,540 ****
{
if (__pos < this->size())
{
! const _CharT* __p = _S_find(data () + __pos, _M_iend (), __c);
! if (__p != _M_iend ())
return __p - data ();
}
return npos;
--- 533,540 ----
{
if (__pos < this->size())
{
! const _CharT* __p = _S_find(data () + __pos, _M_data (), __c);
! if (__p != _M_data () + this->size())
return __p - data ();
}
return npos;
diff -cprN libstdc++/src/misc-inst.cc libstdc++-modified/src/misc-inst.cc
*** libstdc++/src/misc-inst.cc Fri Feb 12 19:41:20 1999
--- libstdc++-modified/src/misc-inst.cc Sun Feb 14 17:02:37 1999
***************
*** 47,55 ****
//
// string
//
! template string::basic_string(char*, char*, allocator<char> const&);
! template wstring::basic_string(wchar_t*, wchar_t*, allocator<wchar_t> const&);
template char* string::_S_construct<char *>(char *, char *, allocator<char> const &, forward_iterator_tag);
--- 47,55 ----
//
// string
//
! template string::basic_string(string::iterator, string::iterator, allocator<char> const&);
! template wstring::basic_string(wstring::iterator, wstring::iterator, allocator<wchar_t> const&);
template char* string::_S_construct<char *>(char *, char *, allocator<char> const &, forward_iterator_tag);
*************** template wchar_t* wstring::_S_construct<
*** 59,71 ****
template wchar_t* wstring::_S_construct<const wchar_t *>(const wchar_t *, const wchar_t *, allocator<wchar_t> const &, forward_iterator_tag);
! template string& string::_M_replace<char *>(char *, char *, char *, char *, forward_iterator_tag);
! template string& string::_M_replace<const char *>(char *, char *, const char *, const char *, forward_iterator_tag);
! template wstring& wstring::_M_replace<wchar_t *>(wchar_t *, wchar_t *, wchar_t *, wchar_t *, forward_iterator_tag);
! template wstring& wstring::_M_replace<const wchar_t *>(wchar_t *, wchar_t *, const wchar_t *, const wchar_t *, forward_iterator_tag);
//
--- 59,79 ----
template wchar_t* wstring::_S_construct<const wchar_t *>(const wchar_t *, const wchar_t *, allocator<wchar_t> const &, forward_iterator_tag);
! template string& string::_M_replace<char *>(string::iterator, string::iterator, char *, char *, forward_iterator_tag);
! template string& string::_M_replace<const char *>(string::iterator, string::iterator, const char *, const char *, forward_iterator_tag);
! template string& string::_M_replace<string::iterator>(string::iterator, string::iterator, string::iterator, string::iterator, forward_iterator_tag);
! template string& string::_M_replace<string::const_iterator>(string::iterator, string::iterator, string::const_iterator, string::const_iterator, forward_iterator_tag);
!
! template wstring& wstring::_M_replace<wchar_t *>(wstring::iterator, wstring::iterator, wchar_t *, wchar_t *, forward_iterator_tag);
!
! template wstring& wstring::_M_replace<const wchar_t *>(wstring::iterator, wstring::iterator, const wchar_t *, const wchar_t *, forward_iterator_tag);
!
! template wstring& wstring::_M_replace<wstring::iterator>(wstring::iterator, wstring::iterator, wstring::iterator, wstring::iterator, forward_iterator_tag);
!
! template wstring& wstring::_M_replace<wstring::const_iterator>(wstring::iterator, wstring::iterator, wstring::const_iterator, wstring::const_iterator, forward_iterator_tag);
//
*************** template wistreambuf_iter __match_parall
*** 83,89 ****
wistreambuf_iter, wistreambuf_iter, int, const string *, int *, int &, bool &);
template void vector<locale::facet *, allocator<locale::facet *> >::insert(
! locale::facet **, unsigned int, locale::facet *const &);
//template bool istreambuf_iter::_M_equal_helper(const istreambuf_iter &) const;
--- 91,97 ----
wistreambuf_iter, wistreambuf_iter, int, const string *, int *, int &, bool &);
template void vector<locale::facet *, allocator<locale::facet *> >::insert(
! vector<locale::facet *, allocator<locale::facet *> >::iterator, unsigned int, locale::facet *const &);
//template bool istreambuf_iter::_M_equal_helper(const istreambuf_iter &) const;
*************** template const char* find_if<const char
*** 216,226 ****
template string* __uninitialized_fill_n_aux<string*, unsigned int, string>
(string*, unsigned int, string const &, _Bool<false>);
! template string* __uninitialized_copy_aux<string const *, string *>
! (string const *, string const *, string*, _Bool<false>);
template locale::facet ** fill_n<locale::facet **, unsigned int, locale::facet *>(locale::facet **, unsigned int, locale::facet * const &);
template void fill<locale::facet **, locale::facet *>(locale::facet **, locale::facet *, locale::facet * const &);
--- 224,238 ----
template string* __uninitialized_fill_n_aux<string*, unsigned int, string>
(string*, unsigned int, string const &, _Bool<false>);
! template string* __uninitialized_copy_aux<vector<string>::const_iterator, string*> (vector<string>::const_iterator, vector<string>::const_iterator, string*, _Bool<false>);
template locale::facet ** fill_n<locale::facet **, unsigned int, locale::facet *>(locale::facet **, unsigned int, locale::facet * const &);
template void fill<locale::facet **, locale::facet *>(locale::facet **, locale::facet *, locale::facet * const &);
+ template const ctype<char>& use_facet<ctype<char> >(const locale &);
+
+ template const ctype<wchar_t>& use_facet<ctype<wchar_t> >(const locale &);
+
+ template const codecvt<char, char, mbstate_t>& use_facet<codecvt<char, char, mbstate_t> >(const locale &);
diff -cprN libstdc++/stl/bits/stl_iterator.h libstdc++-modified/stl/bits/stl_iterator.h
*** libstdc++/stl/bits/stl_iterator.h Fri Feb 12 19:45:40 1999
--- libstdc++-modified/stl/bits/stl_iterator.h Mon Feb 15 22:30:50 1999
*************** iterator_category(const ostream_iterator
*** 944,949 ****
--- 944,1079 ----
#endif /* __STL_USE_NEW_IOSTREAMS */
+ // This iterator adapter is 'normal' in the sense that it does not
+ // change the semantics of any of the operators of its itererator
+ // parameter. Its primary purpose is to convert an iterator that is
+ // not a class, e.g. a pointer, into an iterator that is a class.
+ // The _Container parameter exists solely so that different containers
+ // using this template can instantiate different types, even if the
+ // _Iterator parameter is the same.
+ template<typename _Iterator, typename _Container>
+ class __normal_iterator
+ : public iterator<iterator_traits<_Iterator>::iterator_category,
+ iterator_traits<_Iterator>::value_type,
+ iterator_traits<_Iterator>::difference_type,
+ iterator_traits<_Iterator>::pointer,
+ iterator_traits<_Iterator>::reference>
+ {
+ public:
+
+ typedef __normal_iterator<_Iterator, _Container> normal_iterator_type;
+
+ inline __normal_iterator() : _M_current() { }
+
+ inline explicit __normal_iterator(const _Iterator& __i)
+ : _M_current(__i) { }
+
+ // Allow iterator to const_iterator conversion
+ template<typename _Iter>
+ inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
+ : _M_current(__i.base()) { }
+
+ // forward iterator requirements
+
+ inline reference
+ operator*() const
+ { return *_M_current; }
+
+ inline pointer
+ operator->() const
+ { return _M_current; }
+
+ inline normal_iterator_type&
+ operator++()
+ { ++_M_current; return *this; }
+
+ inline normal_iterator_type
+ operator++(int)
+ { return __normal_iterator(_M_current++); }
+
+ // bidirectional iterator requirements
+
+ inline normal_iterator_type&
+ operator--()
+ { --_M_current; return *this; }
+
+ inline normal_iterator_type
+ operator--(int)
+ { return __normal_iterator(_M_current--); }
+
+ // random access iterator requirements
+
+ inline reference
+ operator[](const difference_type& __n) const
+ { return _M_current[__n]; }
+
+ inline normal_iterator_type&
+ operator+=(const difference_type& __n)
+ { _M_current += __n; return *this; }
+
+ inline normal_iterator_type
+ operator+(const difference_type& __n) const
+ { return __normal_iterator(_M_current + __n); }
+
+ inline normal_iterator_type&
+ operator-=(const difference_type& __n)
+ { _M_current -= __n; return *this; }
+
+ inline normal_iterator_type
+ operator-(const difference_type& __n) const
+ { return __normal_iterator(_M_current - __n); }
+
+ inline difference_type
+ operator-(const normal_iterator_type& __i) const
+ { return _M_current - __i._M_current; }
+
+ const _Iterator& base() const
+ { return _M_current; }
+
+ protected:
+ _Iterator _M_current;
+ };
+
+ // forward iterator requirements
+
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return __lhs.base() == __rhs.base(); }
+
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return !(__lhs == __rhs); }
+
+ // random access iterator requirements
+
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return __lhs.base() < __rhs.base(); }
+
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return __rhs < __lhs; }
+
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return !(__rhs < __lhs); }
+
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return !(__lhs < __rhs); }
+
+ template<typename _Iterator, typename _Container>
+ inline __normal_iterator<_Iterator, _Container>
+ operator+(__normal_iterator<_Iterator, _Container>::difference_type __n,
+ const __normal_iterator<_Iterator, _Container>& __i)
+ { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
+
__STL_END_NAMESPACE
#endif /* __SGI_STL_INTERNAL_ITERATOR_H */
diff -cprN libstdc++/stl/bits/stl_vector.h libstdc++-modified/stl/bits/stl_vector.h
*** libstdc++/stl/bits/stl_vector.h Fri Feb 12 19:46:25 1999
--- libstdc++-modified/stl/bits/stl_vector.h Mon Feb 15 20:33:39 1999
*************** class vector : protected _Vector_base<_T
*** 154,165 ****
{
private:
typedef _Vector_base<_Tp, _Alloc> _Base;
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
! typedef value_type* iterator;
! typedef const value_type* const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
--- 154,166 ----
{
private:
typedef _Vector_base<_Tp, _Alloc> _Base;
+ typedef vector<_Tp, _Alloc> vector_type;
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
! typedef __normal_iterator<pointer, vector_type> iterator;
! typedef __normal_iterator<const_pointer, vector_type> const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
*************** protected:
*** 192,201 ****
void _M_insert_aux(iterator __position);
public:
! iterator begin() { return _M_start; }
! const_iterator begin() const { return _M_start; }
! iterator end() { return _M_finish; }
! const_iterator end() const { return _M_finish; }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
--- 193,203 ----
void _M_insert_aux(iterator __position);
public:
! iterator begin() { return iterator (_M_start); }
! const_iterator begin() const
! { return const_iterator (_M_start); }
! iterator end() { return iterator (_M_finish); }
! const_iterator end() const { return const_iterator (_M_finish); }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
*************** public:
*** 269,275 ****
void reserve(size_type __n) {
if (capacity() < __n) {
const size_type __old_size = size();
! iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
--- 271,277 ----
void reserve(size_type __n) {
if (capacity() < __n) {
const size_type __old_size = size();
! iterator __tmp(_M_allocate_and_copy(__n, _M_start, _M_finish));
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
*************** public:
*** 391,404 ****
}
iterator erase(iterator __position) {
if (__position + 1 != end())
! copy(__position + 1, _M_finish, __position);
--_M_finish;
destroy(_M_finish);
return __position;
}
iterator erase(iterator __first, iterator __last) {
! iterator __i = copy(__last, _M_finish, __first);
! destroy(__i, _M_finish);
_M_finish = _M_finish - (__last - __first);
return __first;
}
--- 393,406 ----
}
iterator erase(iterator __position) {
if (__position + 1 != end())
! copy(__position + 1, end(), __position);
--_M_finish;
destroy(_M_finish);
return __position;
}
iterator erase(iterator __first, iterator __last) {
! iterator __i(copy(__last, end(), __first));
! destroy(__i, end());
_M_finish = _M_finish - (__last - __first);
return __first;
}
*************** protected:
*** 419,425 ****
iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
_ForwardIterator __last)
{
! iterator __result = _M_allocate(__n);
__STL_TRY {
uninitialized_copy(__first, __last, __result);
return __result;
--- 421,427 ----
iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
_ForwardIterator __last)
{
! iterator __result(_M_allocate(__n));
__STL_TRY {
uninitialized_copy(__first, __last, __result);
return __result;
*************** protected:
*** 430,436 ****
iterator _M_allocate_and_copy(size_type __n, const_iterator __first,
const_iterator __last)
{
! iterator __result = _M_allocate(__n);
__STL_TRY {
uninitialized_copy(__first, __last, __result);
return __result;
--- 432,438 ----
iterator _M_allocate_and_copy(size_type __n, const_iterator __first,
const_iterator __last)
{
! iterator __result(_M_allocate(__n));
__STL_TRY {
uninitialized_copy(__first, __last, __result);
return __result;
*************** vector<_Tp,_Alloc>::operator=(const vect
*** 531,544 ****
if (&__x != this) {
const size_type __xlen = __x.size();
if (__xlen > capacity()) {
! iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
_M_end_of_storage = _M_start + __xlen;
}
else if (size() >= __xlen) {
! iterator __i = copy(__x.begin(), __x.end(), begin());
destroy(__i, _M_finish);
}
else {
--- 533,546 ----
if (&__x != this) {
const size_type __xlen = __x.size();
if (__xlen > capacity()) {
! iterator __tmp(_M_allocate_and_copy(__xlen, __x.begin(), __x.end()));
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
_M_end_of_storage = _M_start + __xlen;
}
else if (size() >= __xlen) {
! iterator __i(copy(__x.begin(), __x.end(), begin()));
destroy(__i, _M_finish);
}
else {
*************** void vector<_Tp, _Alloc>::assign(size_t
*** 569,575 ****
template <class _Tp, class _Alloc> template <class _InputIter>
void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
input_iterator_tag) {
! iterator __cur = begin();
for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
*__cur = *__first;
if (__first == __last)
--- 571,577 ----
template <class _Tp, class _Alloc> template <class _InputIter>
void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
input_iterator_tag) {
! iterator __cur(begin());
for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
*__cur = *__first;
if (__first == __last)
*************** vector<_Tp, _Alloc>::_M_assign_aux(_Forw
*** 586,599 ****
distance(__first, __last, __len);
if (__len > capacity()) {
! iterator __tmp = _M_allocate_and_copy(__len, __first, __last);
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
_M_end_of_storage = _M_finish = _M_start + __len;
}
else if (size() >= __len) {
! iterator __new_finish = copy(__first, __last, _M_start);
destroy(__new_finish, _M_finish);
_M_finish = __new_finish;
}
--- 588,601 ----
distance(__first, __last, __len);
if (__len > capacity()) {
! iterator __tmp(_M_allocate_and_copy(__len, __first, __last));
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
_M_end_of_storage = _M_finish = _M_start + __len;
}
else if (size() >= __len) {
! iterator __new_finish(copy(__first, __last, _M_start));
destroy(__new_finish, _M_finish);
_M_finish = __new_finish;
}
*************** vector<_Tp, _Alloc>::_M_insert_aux(itera
*** 615,641 ****
construct(_M_finish, *(_M_finish - 1));
++_M_finish;
_Tp __x_copy = __x;
! copy_backward(__position, _M_finish - 2, _M_finish - 1);
*__position = __x_copy;
}
else {
const size_type __old_size = size();
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
! iterator __new_start = _M_allocate(__len);
! iterator __new_finish = __new_start;
__STL_TRY {
! __new_finish = uninitialized_copy(_M_start, __position, __new_start);
! construct(__new_finish, __x);
++__new_finish;
! __new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
! _M_deallocate(__new_start,__len)));
destroy(begin(), end());
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
! _M_start = __new_start;
! _M_finish = __new_finish;
! _M_end_of_storage = __new_start + __len;
}
}
--- 617,645 ----
construct(_M_finish, *(_M_finish - 1));
++_M_finish;
_Tp __x_copy = __x;
! copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
*__position = __x_copy;
}
else {
const size_type __old_size = size();
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
! iterator __new_start(_M_allocate(__len));
! iterator __new_finish(__new_start);
__STL_TRY {
! __new_finish = uninitialized_copy(iterator(_M_start), __position,
! __new_start);
! construct(__new_finish.base(), __x);
++__new_finish;
! __new_finish = uninitialized_copy(__position, iterator(_M_finish),
! __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
! _M_deallocate(__new_start.base(),__len)));
destroy(begin(), end());
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
! _M_start = __new_start.base();
! _M_finish = __new_finish.base();
! _M_end_of_storage = __new_start.base() + __len;
}
}
*************** vector<_Tp, _Alloc>::_M_insert_aux(itera
*** 652,659 ****
else {
const size_type __old_size = size();
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
! iterator __new_start = _M_allocate(__len);
! iterator __new_finish = __new_start;
__STL_TRY {
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
construct(__new_finish);
--- 656,663 ----
else {
const size_type __old_size = size();
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
! iterator __new_start(_M_allocate(__len));
! iterator __new_finish(__new_start);
__STL_TRY {
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
construct(__new_finish);
*************** void vector<_Tp, _Alloc>::insert(iterato
*** 677,684 ****
if (__n != 0) {
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
_Tp __x_copy = __x;
! const size_type __elems_after = _M_finish - __position;
! iterator __old_finish = _M_finish;
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
_M_finish += __n;
--- 681,688 ----
if (__n != 0) {
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
_Tp __x_copy = __x;
! const size_type __elems_after = end() - __position;
! iterator __old_finish(_M_finish);
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
_M_finish += __n;
*************** void vector<_Tp, _Alloc>::insert(iterato
*** 696,716 ****
else {
const size_type __old_size = size();
const size_type __len = __old_size + max(__old_size, __n);
! iterator __new_start = _M_allocate(__len);
! iterator __new_finish = __new_start;
__STL_TRY {
! __new_finish = uninitialized_copy(_M_start, __position, __new_start);
__new_finish = uninitialized_fill_n(__new_finish, __n, __x);
__new_finish
! = uninitialized_copy(__position, _M_finish, __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
! _M_deallocate(__new_start,__len)));
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
! _M_start = __new_start;
! _M_finish = __new_finish;
! _M_end_of_storage = __new_start + __len;
}
}
}
--- 700,720 ----
else {
const size_type __old_size = size();
const size_type __len = __old_size + max(__old_size, __n);
! iterator __new_start(_M_allocate(__len));
! iterator __new_finish(__new_start);
__STL_TRY {
! __new_finish = uninitialized_copy(_M_start, __position.base(), __new_start);
__new_finish = uninitialized_fill_n(__new_finish, __n, __x);
__new_finish
! = uninitialized_copy(__position.base(), _M_finish, __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
! _M_deallocate(__new_start.base(),__len)));
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
! _M_start = __new_start.base();
! _M_finish = __new_finish.base();
! _M_end_of_storage = __new_start.base() + __len;
}
}
}
*************** vector<_Tp, _Alloc>::_M_range_insert(ite
*** 742,748 ****
distance(__first, __last, __n);
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
const size_type __elems_after = _M_finish - __position;
! iterator __old_finish = _M_finish;
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
_M_finish += __n;
--- 746,752 ----
distance(__first, __last, __n);
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
const size_type __elems_after = _M_finish - __position;
! iterator __old_finish(_M_finish);
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
_M_finish += __n;
*************** vector<_Tp, _Alloc>::_M_range_insert(ite
*** 762,769 ****
else {
const size_type __old_size = size();
const size_type __len = __old_size + max(__old_size, __n);
! iterator __new_start = _M_allocate(__len);
! iterator __new_finish = __new_start;
__STL_TRY {
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
__new_finish = uninitialized_copy(__first, __last, __new_finish);
--- 766,773 ----
else {
const size_type __old_size = size();
const size_type __len = __old_size + max(__old_size, __n);
! iterator __new_start(_M_allocate(__len));
! iterator __new_finish(__new_start);
__STL_TRY {
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
__new_finish = uninitialized_copy(__first, __last, __new_finish);
*************** vector<_Tp, _Alloc>::insert(iterator __p
*** 794,800 ****
distance(__first, __last, __n);
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
const size_type __elems_after = _M_finish - __position;
! iterator __old_finish = _M_finish;
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
_M_finish += __n;
--- 798,804 ----
distance(__first, __last, __n);
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
const size_type __elems_after = _M_finish - __position;
! iterator __old_finish(_M_finish);
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
_M_finish += __n;
*************** vector<_Tp, _Alloc>::insert(iterator __p
*** 812,819 ****
else {
const size_type __old_size = size();
const size_type __len = __old_size + max(__old_size, __n);
! iterator __new_start = _M_allocate(__len);
! iterator __new_finish = __new_start;
__STL_TRY {
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
__new_finish = uninitialized_copy(__first, __last, __new_finish);
--- 816,823 ----
else {
const size_type __old_size = size();
const size_type __len = __old_size + max(__old_size, __n);
! iterator __new_start(_M_allocate(__len));
! iterator __new_finish(__new_start);
__STL_TRY {
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
__new_finish = uninitialized_copy(__first, __last, __new_finish);
diff -cprN libstdc++/testsuite/24/24iterator.cc libstdc++-modified/testsuite/24/24iterator.cc
*** libstdc++/testsuite/24/24iterator.cc Thu Jan 1 01:00:00 1970
--- libstdc++-modified/testsuite/24/24iterator.cc Mon Feb 15 20:53:11 1999
***************
*** 0 ****
--- 1,581 ----
+ // 24.1.5 Random accesss iterators
+ // 24.3.1 Iterator traits
+ // (basic_string and vector implementations)
+ //
+ // Copyright (C) 1999 Philip Martin
+ // This program is free software; you can redistribute it and/or modify
+ // it under the terms of the GNU General Public License as published by
+ // the Free Software Foundation; either version 2 of the License, or
+ // (at your option) any later version.
+ //
+ // This program is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License
+ // along with this program; if not, write to the Free Software
+ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ // USA
+
+
+ #include <string>
+ #include <vector>
+
+ int string_stuff()
+ {
+ int failures(0);
+
+ std::string s("abcde");
+
+ std::string::iterator i1(s.begin());
+ if (*i1 != 'a')
+ ++failures;
+
+ ++i1;
+ if (*i1 != 'b')
+ ++failures;
+
+ i1++;
+ if (*i1 != 'c')
+ ++failures;
+
+ ++ ++i1;
+ if (*i1 != 'e')
+ ++failures;
+
+ --i1;
+ if (*i1 != 'd')
+ ++failures;
+
+ i1--;
+ if (*i1 != 'c')
+ ++failures;
+
+ -- --i1;
+ if (*i1 != 'a')
+ ++failures;
+
+ std::string::iterator i2;
+ i2 = s.end();
+ std::iterator_traits<std::string::iterator>::difference_type d1;
+ d1 = i2 - i1;
+ if (d1 != 5)
+ ++failures;
+
+ std::iterator_traits<std::string::iterator>::value_type v1;
+ v1 = i1[0];
+ if (v1 != 'a')
+ ++failures;
+
+ std::iterator_traits<std::string::iterator>::reference r1(i1[0]);
+ if (r1 != 'a')
+ ++failures;
+ r1 = 'x';
+ if (r1 != 'x')
+ ++failures;
+ r1 = 'a';
+
+ if ((i1 != i2) != true)
+ ++failures;
+ if ((i1 == i2) != false)
+ ++failures;
+ if ((i1 < i2) != true)
+ ++failures;
+ if ((i1 > i2) != false)
+ ++failures;
+ if ((i1 <= i2) != true)
+ ++failures;
+ if ((i1 >= i2) != false)
+ ++failures;
+
+ std::string::iterator i3;
+ i3 = i1;
+ if ((i3 == i1) != true)
+ ++failures;
+
+ i3 += 5;
+ if ((i3 == i2) != true)
+ ++failures;
+
+ i3 -= 5;
+ if ((i3 == i1) != true)
+ ++failures;
+
+ if (i3 + 5 != i2)
+ ++failures;
+
+ if (5 + i3 != i2)
+ ++failures;
+
+ if (i2 - 5 != i3)
+ ++failures;
+
+ if (i1[0] != 'a')
+ ++failures;
+
+ i1[4] = 'x';
+ if (i2[-1] != 'x')
+ ++failures;
+ i1[4] = 'e';
+
+ i1[2] = 'x';
+ if (i2[-3] != 'x')
+ ++failures;
+ i1[2] = 'c';
+
+ std::string::const_iterator ci1(s.begin());
+ if (*ci1 != 'a')
+ ++failures;
+
+ ++ci1;
+ if (*ci1 != 'b')
+ ++failures;
+
+ ci1++;
+ if (*ci1 != 'c')
+ ++failures;
+
+ ++ ++ci1;
+ if (*ci1 != 'e')
+ ++failures;
+
+ --ci1;
+ if (*ci1 != 'd')
+ ++failures;
+
+ ci1--;
+ if (*ci1 != 'c')
+ ++failures;
+
+ -- --ci1;
+ if (*ci1 != 'a')
+ ++failures;
+
+ std::string::const_iterator ci2;
+ ci2 = s.end();
+ std::iterator_traits<std::string::const_iterator>::difference_type d2;
+ d2 = ci2 - ci1;
+ if (d2 != 5)
+ ++failures;
+
+ std::iterator_traits<std::string::const_iterator>::value_type v2;
+ v2 = ci1[0];
+ if (v2 != 'a')
+ ++failures;
+
+ std::iterator_traits<std::string::const_iterator>::reference r2(ci1[0]);
+ if (r2 != 'a')
+ ++failures;
+
+ if ((ci1 != ci2) != true)
+ ++failures;
+ if ((ci1 == ci2) != false)
+ ++failures;
+ if ((ci1 < ci2) != true)
+ ++failures;
+ if ((ci1 > ci2) != false)
+ ++failures;
+ if ((ci1 <= ci2) != true)
+ ++failures;
+ if ((ci1 >= ci2) != false)
+ ++failures;
+
+ std::string::const_iterator ci3;
+ ci3 = ci1;
+ if ((ci3 == ci1) != true)
+ ++failures;
+
+ ci3 += 5;
+ if ((ci3 == ci2) != true)
+ ++failures;
+
+ ci3 -= 5;
+ if ((ci3 == ci1) != true)
+ ++failures;
+
+ if (ci3 + 5 != ci2)
+ ++failures;
+
+ if (5 + ci3 != ci2)
+ ++failures;
+
+ if (ci2 - 5 != ci3)
+ ++failures;
+
+ if (ci1[2] != 'c')
+ ++failures;
+
+ if (ci2[-1] != 'e')
+ ++failures;
+
+ // iterator and const_iterator
+ std::string::const_iterator ci4(i1);
+ if ((ci4 == i1) != true)
+ ++failures;
+ if ((ci4 != i1) != false)
+ ++failures;
+ if ((ci4 < i1) != false)
+ ++failures;
+ if ((ci4 > i1) != false)
+ ++failures;
+ if ((ci4 <= i1) != true)
+ ++failures;
+ if ((ci4 >= i1) != true)
+ ++failures;
+ ci4 = i2;
+ if ((i2 == ci4) != true)
+ ++failures;
+ if ((i2 < ci4) != false)
+ ++failures;
+ if ((i2 > ci4) != false)
+ ++failures;
+ if ((i2 <= ci4) != true)
+ ++failures;
+ if ((i2 >= ci4) != true)
+ ++failures;
+
+ const std::string cs("ABCDE");
+ std::string::const_iterator ci5(cs.begin());
+ if (ci5[0] != 'A')
+ ++failures;
+
+ return failures;
+ }
+
+ int vector_stuff()
+ {
+ int failures(0);
+
+ std::vector<int> v;
+ v.push_back(int(1));
+ v.push_back(int(2));
+ v.push_back(int(3));
+ v.push_back(int(4));
+ v.push_back(int(5));
+
+ std::vector<int>::iterator i1(v.begin());
+ if (*i1 != 1)
+ ++failures;
+
+ ++i1;
+ if (*i1 != 2)
+ ++failures;
+
+ i1++;
+ if (*i1 != 3)
+ ++failures;
+
+ ++ ++i1;
+ if (*i1 != 5)
+ ++failures;
+
+ --i1;
+ if (*i1 != 4)
+ ++failures;
+
+ i1--;
+ if (*i1 != 3)
+ ++failures;
+
+ -- --i1;
+ if (*i1 != 1)
+ ++failures;
+
+ std::vector<int>::iterator i2;
+ i2 = v.end();
+ std::iterator_traits<std::vector<int>::iterator>::difference_type d1;
+ d1 = i2 - i1;
+ if (d1 != 5)
+ ++failures;
+
+ std::iterator_traits<std::vector<int>::iterator>::value_type v1;
+ v1 = i1[0];
+ if (v1 != 1)
+ ++failures;
+
+ std::iterator_traits<std::vector<int>::iterator>::reference r1(i1[0]);
+ if (r1 != 1)
+ ++failures;
+ r1 = 9;
+ if (r1 != 9)
+ ++failures;
+ r1 = 1;
+
+ if ((i1 != i2) != true)
+ ++failures;
+ if ((i1 == i2) != false)
+ ++failures;
+ if ((i1 < i2) != true)
+ ++failures;
+ if ((i1 > i2) != false)
+ ++failures;
+ if ((i1 <= i2) != true)
+ ++failures;
+ if ((i1 >= i2) != false)
+ ++failures;
+
+ std::vector<int>::iterator i3;
+ i3 = i1;
+ if ((i3 == i1) != true)
+ ++failures;
+
+ i3 += 5;
+ if ((i3 == i2) != true)
+ ++failures;
+
+ i3 -= 5;
+ if ((i3 == i1) != true)
+ ++failures;
+
+ if (i3 + 5 != i2)
+ ++failures;
+
+ if (5 + i3 != i2)
+ ++failures;
+
+ if (i2 - 5 != i3)
+ ++failures;
+
+ if (i1[0] != 1)
+ ++failures;
+
+ i1[4] = 9;
+ if (i2[-1] != 9)
+ ++failures;
+ i1[4] = 5;
+
+ i1[2] = 9;
+ if (i2[-3] != 9)
+ ++failures;
+ i1[2] = 3;
+
+ std::vector<int>::const_iterator ci1(v.begin());
+ if (*ci1 != 1)
+ ++failures;
+
+ ++ci1;
+ if (*ci1 != 2)
+ ++failures;
+
+ ci1++;
+ if (*ci1 != 3)
+ ++failures;
+
+ ++ ++ci1;
+ if (*ci1 != 5)
+ ++failures;
+
+ --ci1;
+ if (*ci1 != 4)
+ ++failures;
+
+ ci1--;
+ if (*ci1 != 3)
+ ++failures;
+
+ -- --ci1;
+ if (*ci1 != 1)
+ ++failures;
+
+ std::vector<int>::const_iterator ci2;
+ ci2 = v.end();
+ std::iterator_traits<std::vector<int>::const_iterator>::difference_type d2;
+ d2 = ci2 - ci1;
+ if (d2 != 5)
+ ++failures;
+
+ std::iterator_traits<std::vector<int>::const_iterator>::value_type v2;
+ v2 = ci1[0];
+ if (v2 != 1)
+ ++failures;
+
+ std::iterator_traits<std::vector<int>::const_iterator>::reference
+ r2(ci1[0]);
+ if (r2 != 1)
+ ++failures;
+
+ if ((ci1 != ci2) != true)
+ ++failures;
+ if ((ci1 == ci2) != false)
+ ++failures;
+ if ((ci1 < ci2) != true)
+ ++failures;
+ if ((ci1 > ci2) != false)
+ ++failures;
+ if ((ci1 <= ci2) != true)
+ ++failures;
+ if ((ci1 >= ci2) != false)
+ ++failures;
+
+ std::vector<int>::const_iterator ci3;
+ ci3 = ci1;
+ if ((ci3 == ci1) != true)
+ ++failures;
+
+ ci3 += 5;
+ if ((ci3 == ci2) != true)
+ ++failures;
+
+ ci3 -= 5;
+ if ((ci3 == ci1) != true)
+ ++failures;
+
+ if (ci3 + 5 != ci2)
+ ++failures;
+
+ if (5 + ci3 != ci2)
+ ++failures;
+
+ if (ci2 - 5 != ci3)
+ ++failures;
+
+ if (ci1[2] != 3)
+ ++failures;
+
+ if (ci2[-1] != 5)
+ ++failures;
+
+ // iterator to const_iterator
+ std::vector<int>::const_iterator ci4(i1);
+ if ((ci4 == i1) != true)
+ ++failures;
+ if ((ci4 != i1) != false)
+ ++failures;
+ if ((ci4 < i1) != false)
+ ++failures;
+ if ((ci4 > i1) != false)
+ ++failures;
+ if ((ci4 <= i1) != true)
+ ++failures;
+ if ((ci4 >= i1) != true)
+ ++failures;
+ ci4 = i2;
+ if ((i2 == ci4) != true)
+ ++failures;
+ if ((i2 < ci4) != false)
+ ++failures;
+ if ((i2 > ci4) != false)
+ ++failures;
+ if ((i2 <= ci4) != true)
+ ++failures;
+ if ((i2 >= ci4) != true)
+ ++failures;
+
+ const std::vector<int> cv(v);
+ std::vector<int>::const_iterator ci5(cv.begin());
+ if (ci5[0] != 1)
+ ++failures;
+
+ std::vector<std::string> vs;
+ vs.push_back(string("abc"));
+ std::vector<std::string>::iterator ivs(vs.begin());
+ if (ivs->c_str()[1] != 'b')
+ ++failures;
+
+ return failures;
+ }
+
+ int reverse_stuff()
+ {
+ int failures(0);
+
+ std::string s("abcde");
+
+ std::string::reverse_iterator ri(s.rbegin());
+ if (*ri != 'e')
+ ++failures;
+
+ std::iterator_traits<std::string::reverse_iterator>::difference_type d;
+ d = s.rend() - ri;
+ if (d != 5)
+ ++failures;
+
+ const std::string cs("abcde");
+ std::string::const_reverse_iterator cri(cs.rend());
+ if (cri - 5 != cs.rbegin())
+ ++failures;
+
+ return failures;
+ }
+
+ // the following should be compiler errors
+ // flag runtime errors in case they slip through the compiler
+ int wrong_stuff()
+ {
+ int failures(0);
+
+ #ifdef ITER24_F1
+ extern void f(std::vector<string*>::iterator);
+ vector<string*> vs[2];
+ f(vs); // address of array is not an iterator
+ failures++;
+ #endif
+
+ #ifdef ITER24_F2
+ string s;
+ char *i = s.begin(); // begin() doesn't return a pointer
+ failures++;
+ #endif
+
+ #ifdef ITER24_F3
+ std::string::const_iterator ci;
+ std::string::iterator i;
+ if (i - ci) // remove const_ is a warning
+ i++;
+ // failures++; only a warning
+ #endif
+
+ #ifdef ITER24_F4
+ std::vector<char>::iterator iv;
+ std::string::iterator is(iv);// vector<char> is not string
+ failures++;
+ #endif
+
+ #ifdef ITER24_F5
+ std::vector<char>::iterator iv;
+ std::string::iterator is;
+ if (iv == is) // vector<char> is not string
+ ++iv;
+ failures++;
+ #endif
+
+ #ifdef ITER24_F6
+ std::vector<char>::const_iterator ci;
+ std::vector<char>::iterator i = ci; // remove const_ is a warning
+ ++i;
+ // failures++; only a warning
+ #endif
+
+ #ifdef ITER24_F7
+ std::vector<int> v(1);
+ std::vector<int>::const_iterator ci(v.begin());
+ *ci = 1; // cannot assign through const_iterator
+ failures++;
+ #endif
+
+ #ifdef ITER24_F8
+ std::vector<const int> v(1);
+ std::vector<const int>::reference r(v.begin()[0]);
+ r = 1; // cannot assign through reference to const
+ failures++;
+ #endif
+
+ return failures;
+ }
+
+ int main(int argc,
+ char **argv)
+ {
+ int failures(0);
+
+ failures += string_stuff();
+
+ failures += vector_stuff();
+
+ failures += reverse_stuff();
+
+ failures += wrong_stuff();
+
+ return failures ? 1 : 0;
+ }