// Iterators -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2001-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
#include <bits/move.h>
+#include <bits/ptr_traits.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
typedef typename __traits_type::reference reference;
/**
- * The default constructor default-initializes member @p current.
+ * The default constructor value-initializes member @p current.
* If it is a pointer, that means it is zero-initialized.
*/
// _GLIBCXX_RESOLVE_LIB_DEFECTS
: current(__x.current) { }
/**
- * A reverse_iterator across other types can be copied in the normal
- * fashion.
+ * A %reverse_iterator across other types can be copied if the
+ * underlying %iterator can be converted to the type of @c current.
*/
template<typename _Iter>
reverse_iterator(const reverse_iterator<_Iter>& __x)
{ return current; }
/**
- * @return TODO
+ * @return A reference to the value at @c --current
*
- * @doctodo
+ * This requires that @c --current is dereferenceable.
+ *
+ * @warning This implementation requires that for an iterator of the
+ * underlying iterator type, @c x, a reference obtained by
+ * @c *x remains valid after @c x has been modified or
+ * destroyed. This is a bug: http://gcc.gnu.org/PR51823
*/
reference
operator*() const
}
/**
- * @return TODO
+ * @return A pointer to the value at @c --current
*
- * @doctodo
+ * This requires that @c --current is dereferenceable.
*/
pointer
operator->() const
{ return &(operator*()); }
/**
- * @return TODO
+ * @return @c *this
*
- * @doctodo
+ * Decrements the underlying iterator.
*/
reverse_iterator&
operator++()
}
/**
- * @return TODO
+ * @return The original value of @c *this
*
- * @doctodo
+ * Decrements the underlying iterator.
*/
reverse_iterator
operator++(int)
}
/**
- * @return TODO
+ * @return @c *this
*
- * @doctodo
+ * Increments the underlying iterator.
*/
reverse_iterator&
operator--()
}
/**
- * @return TODO
+ * @return A reverse_iterator with the previous value of @c *this
*
- * @doctodo
+ * Increments the underlying iterator.
*/
reverse_iterator
operator--(int)
}
/**
- * @return TODO
+ * @return A reverse_iterator that refers to @c current - @a __n
*
- * @doctodo
+ * The underlying iterator must be a Random Access Iterator.
*/
reverse_iterator
operator+(difference_type __n) const
{ return reverse_iterator(current - __n); }
/**
- * @return TODO
+ * @return *this
*
- * @doctodo
+ * Moves the underlying iterator backwards @a __n steps.
+ * The underlying iterator must be a Random Access Iterator.
*/
reverse_iterator&
operator+=(difference_type __n)
}
/**
- * @return TODO
+ * @return A reverse_iterator that refers to @c current - @a __n
*
- * @doctodo
+ * The underlying iterator must be a Random Access Iterator.
*/
reverse_iterator
operator-(difference_type __n) const
{ return reverse_iterator(current + __n); }
/**
- * @return TODO
+ * @return *this
*
- * @doctodo
+ * Moves the underlying iterator forwards @a __n steps.
+ * The underlying iterator must be a Random Access Iterator.
*/
reverse_iterator&
operator-=(difference_type __n)
}
/**
- * @return TODO
+ * @return The value at @c current - @a __n - 1
*
- * @doctodo
+ * The underlying iterator must be a Random Access Iterator.
*/
reference
operator[](difference_type __n) const
//@{
/**
- * @param x A %reverse_iterator.
- * @param y A %reverse_iterator.
+ * @param __x A %reverse_iterator.
+ * @param __y A %reverse_iterator.
* @return A simple bool.
*
* Reverse iterators forward many operations to their underlying base()
{ return !(__x < __y); }
template<typename _IteratorL, typename _IteratorR>
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
// DR 685.
inline auto
operator-(const reverse_iterator<_IteratorL>& __x,
back_insert_iterator(_Container& __x) : container(&__x) { }
/**
- * @param value An instance of whatever type
+ * @param __value An instance of whatever type
* container_type::const_reference is; presumably a
* reference-to-const T for container<T>.
* @return This %iterator, for chained operations.
* the end, if you like). Assigning a value to the %iterator will
* always append the value to the end of the container.
*/
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus < 201103L
back_insert_iterator&
operator=(typename _Container::const_reference __value)
{
};
/**
- * @param x A container of arbitrary type.
- * @return An instance of back_insert_iterator working on @p x.
+ * @param __x A container of arbitrary type.
+ * @return An instance of back_insert_iterator working on @p __x.
*
* This wrapper function helps in creating back_insert_iterator instances.
* Typing the name of the %iterator requires knowing the precise full
explicit front_insert_iterator(_Container& __x) : container(&__x) { }
/**
- * @param value An instance of whatever type
+ * @param __value An instance of whatever type
* container_type::const_reference is; presumably a
* reference-to-const T for container<T>.
* @return This %iterator, for chained operations.
* the front, if you like). Assigning a value to the %iterator will
* always prepend the value to the front of the container.
*/
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus < 201103L
front_insert_iterator&
operator=(typename _Container::const_reference __value)
{
};
/**
- * @param x A container of arbitrary type.
+ * @param __x A container of arbitrary type.
* @return An instance of front_insert_iterator working on @p x.
*
* This wrapper function helps in creating front_insert_iterator instances.
: container(&__x), iter(__i) {}
/**
- * @param value An instance of whatever type
+ * @param __value An instance of whatever type
* container_type::const_reference is; presumably a
* reference-to-const T for container<T>.
* @return This %iterator, for chained operations.
* // vector v contains A, 1, 2, 3, and Z
* @endcode
*/
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus < 201103L
insert_iterator&
operator=(typename _Container::const_reference __value)
{
};
/**
- * @param x A container of arbitrary type.
- * @return An instance of insert_iterator working on @p x.
+ * @param __x A container of arbitrary type.
+ * @return An instance of insert_iterator working on @p __x.
*
* This wrapper function helps in creating insert_iterator instances.
* Typing the name of the %iterator requires knowing the precise full
typedef typename __traits_type::reference reference;
typedef typename __traits_type::pointer pointer;
- _GLIBCXX_CONSTEXPR __normal_iterator() : _M_current(_Iterator()) { }
+ _GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT
+ : _M_current(_Iterator()) { }
explicit
- __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
+ __normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT
+ : _M_current(__i) { }
// Allow iterator to const_iterator conversion
template<typename _Iter>
__normal_iterator(const __normal_iterator<_Iter,
typename __enable_if<
(std::__are_same<_Iter, typename _Container::pointer>::__value),
- _Container>::__type>& __i)
+ _Container>::__type>& __i) _GLIBCXX_NOEXCEPT
: _M_current(__i.base()) { }
+#if __cplusplus >= 201103L
+ __normal_iterator<typename _Container::pointer, _Container>
+ _M_const_cast() const noexcept
+ {
+ using _PTraits = std::pointer_traits<typename _Container::pointer>;
+ return __normal_iterator<typename _Container::pointer, _Container>
+ (_PTraits::pointer_to(const_cast<typename _PTraits::element_type&>
+ (*_M_current)));
+ }
+#else
+ __normal_iterator
+ _M_const_cast() const
+ { return *this; }
+#endif
+
// Forward iterator requirements
reference
- operator*() const
+ operator*() const _GLIBCXX_NOEXCEPT
{ return *_M_current; }
pointer
- operator->() const
+ operator->() const _GLIBCXX_NOEXCEPT
{ return _M_current; }
__normal_iterator&
- operator++()
+ operator++() _GLIBCXX_NOEXCEPT
{
++_M_current;
return *this;
}
__normal_iterator
- operator++(int)
+ operator++(int) _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current++); }
// Bidirectional iterator requirements
__normal_iterator&
- operator--()
+ operator--() _GLIBCXX_NOEXCEPT
{
--_M_current;
return *this;
}
__normal_iterator
- operator--(int)
+ operator--(int) _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current--); }
// Random access iterator requirements
reference
- operator[](const difference_type& __n) const
+ operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
{ return _M_current[__n]; }
__normal_iterator&
- operator+=(const difference_type& __n)
+ operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
{ _M_current += __n; return *this; }
__normal_iterator
- operator+(const difference_type& __n) const
+ operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current + __n); }
__normal_iterator&
- operator-=(const difference_type& __n)
+ operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
{ _M_current -= __n; return *this; }
__normal_iterator
- operator-(const difference_type& __n) const
+ operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current - __n); }
const _Iterator&
- base() const
+ base() const _GLIBCXX_NOEXCEPT
{ return _M_current; }
};
inline bool
operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() == __rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() == __rhs.base(); }
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() != __rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() != __rhs.base(); }
// Random access iterator requirements
inline bool
operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() < __rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() < __rhs.base(); }
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() > __rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() > __rhs.base(); }
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() <= __rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() <= __rhs.base(); }
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() >= __rhs.base(); }
template<typename _Iterator, typename _Container>
inline bool
operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() >= __rhs.base(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// operators but also operator- must accept mixed iterator/const_iterator
// parameters.
template<typename _IteratorL, typename _IteratorR, typename _Container>
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
// DR 685.
inline auto
operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
- const __normal_iterator<_IteratorR, _Container>& __rhs)
+ const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept
-> decltype(__lhs.base() - __rhs.base())
#else
inline typename __normal_iterator<_IteratorL, _Container>::difference_type
inline typename __normal_iterator<_Iterator, _Container>::difference_type
operator-(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.base() - __rhs.base(); }
template<typename _Iterator, typename _Container>
inline __normal_iterator<_Iterator, _Container>
operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
__n, const __normal_iterator<_Iterator, _Container>& __i)
+ _GLIBCXX_NOEXCEPT
{ return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
namespace std _GLIBCXX_VISIBILITY(default)
{
template<typename _Iterator>
inline move_iterator<_Iterator>
- make_move_iterator(const _Iterator& __i)
+ make_move_iterator(_Iterator __i)
{ return move_iterator<_Iterator>(__i); }
+ template<typename _Iterator, typename _ReturnType
+ = typename conditional<__move_if_noexcept_cond
+ <typename iterator_traits<_Iterator>::value_type>::value,
+ _Iterator, move_iterator<_Iterator>>::type>
+ inline _ReturnType
+ __make_move_if_noexcept_iterator(_Iterator __i)
+ { return _ReturnType(__i); }
+
// @} group iterators
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter)
+#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \
+ std::__make_move_if_noexcept_iterator(_Iter)
#else
#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter)
-#endif // __GXX_EXPERIMENTAL_CXX0X__
+#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter)
+#endif // C++11
#endif