forked from KolibriOS/kolibrios
sdk: build libsupc++ from libstdc++ source
git-svn-id: svn://kolibrios.org@5134 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
305
contrib/sdk/sources/libstdc++-v3/include/debug/array
Normal file
305
contrib/sdk/sources/libstdc++-v3/include/debug/array
Normal file
@@ -0,0 +1,305 @@
|
||||
// Debugging array implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2012-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/array
|
||||
* This is a Standard C++ Library header.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_ARRAY
|
||||
#define _GLIBCXX_DEBUG_ARRAY 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include <debug/safe_sequence.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
struct array
|
||||
{
|
||||
typedef _Tp value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef value_type* iterator;
|
||||
typedef const value_type* const_iterator;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// Support for zero-sized arrays mandatory.
|
||||
typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
|
||||
typename _AT_Type::_Type _M_elems;
|
||||
|
||||
template<std::size_t _Size>
|
||||
struct _Array_check_subscript
|
||||
{
|
||||
std::size_t size() { return _Size; }
|
||||
|
||||
_Array_check_subscript(std::size_t __index)
|
||||
{ __glibcxx_check_subscript(__index); }
|
||||
};
|
||||
|
||||
template<std::size_t _Size>
|
||||
struct _Array_check_nonempty
|
||||
{
|
||||
bool empty() { return _Size == 0; }
|
||||
|
||||
_Array_check_nonempty()
|
||||
{ __glibcxx_check_nonempty(); }
|
||||
};
|
||||
|
||||
// No explicit construct/copy/destroy for aggregate type.
|
||||
|
||||
// DR 776.
|
||||
void
|
||||
fill(const value_type& __u)
|
||||
{ std::fill_n(begin(), size(), __u); }
|
||||
|
||||
void
|
||||
swap(array& __other)
|
||||
noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
|
||||
{ std::swap_ranges(begin(), end(), __other.begin()); }
|
||||
|
||||
// Iterators.
|
||||
iterator
|
||||
begin() noexcept
|
||||
{ return iterator(data()); }
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{ return const_iterator(data()); }
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{ return iterator(data() + _Nm); }
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{ return const_iterator(data() + _Nm); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() noexcept
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() noexcept
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(data()); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(data() + _Nm); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
// Capacity.
|
||||
constexpr size_type
|
||||
size() const noexcept { return _Nm; }
|
||||
|
||||
constexpr size_type
|
||||
max_size() const noexcept { return _Nm; }
|
||||
|
||||
constexpr bool
|
||||
empty() const noexcept { return size() == 0; }
|
||||
|
||||
// Element access.
|
||||
reference
|
||||
operator[](size_type __n)
|
||||
{
|
||||
__glibcxx_check_subscript(__n);
|
||||
return _AT_Type::_S_ref(_M_elems, __n);
|
||||
}
|
||||
|
||||
constexpr const_reference
|
||||
operator[](size_type __n) const noexcept
|
||||
{
|
||||
return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
|
||||
: (_GLIBCXX_THROW_OR_ABORT(_Array_check_subscript<_Nm>(__n)),
|
||||
_AT_Type::_S_ref(_M_elems, 0));
|
||||
}
|
||||
|
||||
reference
|
||||
at(size_type __n)
|
||||
{
|
||||
if (__n >= _Nm)
|
||||
std::__throw_out_of_range(__N("array::at"));
|
||||
return _AT_Type::_S_ref(_M_elems, __n);
|
||||
}
|
||||
|
||||
constexpr const_reference
|
||||
at(size_type __n) const
|
||||
{
|
||||
// Result of conditional expression must be an lvalue so use
|
||||
// boolean ? lvalue : (throw-expr, lvalue)
|
||||
return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
|
||||
: (std::__throw_out_of_range(__N("array::at")),
|
||||
_AT_Type::_S_ref(_M_elems, 0));
|
||||
}
|
||||
|
||||
reference
|
||||
front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return *begin();
|
||||
}
|
||||
|
||||
constexpr const_reference
|
||||
front() const
|
||||
{
|
||||
return _Nm ? _AT_Type::_S_ref(_M_elems, 0)
|
||||
: (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
|
||||
_AT_Type::_S_ref(_M_elems, 0));
|
||||
}
|
||||
|
||||
reference
|
||||
back()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Nm ? *(end() - 1) : *end();
|
||||
}
|
||||
|
||||
constexpr const_reference
|
||||
back() const
|
||||
{
|
||||
return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
|
||||
: (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
|
||||
_AT_Type::_S_ref(_M_elems, 0));
|
||||
}
|
||||
|
||||
pointer
|
||||
data() noexcept
|
||||
{ return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
|
||||
|
||||
const_pointer
|
||||
data() const noexcept
|
||||
{ return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
|
||||
};
|
||||
|
||||
// Array comparisons.
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
inline bool
|
||||
operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
|
||||
{ return std::equal(__one.begin(), __one.end(), __two.begin()); }
|
||||
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
inline bool
|
||||
operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
|
||||
{ return !(__one == __two); }
|
||||
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
inline bool
|
||||
operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
|
||||
{
|
||||
return std::lexicographical_compare(__a.begin(), __a.end(),
|
||||
__b.begin(), __b.end());
|
||||
}
|
||||
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
inline bool
|
||||
operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
|
||||
{ return __two < __one; }
|
||||
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
inline bool
|
||||
operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
|
||||
{ return !(__one > __two); }
|
||||
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
inline bool
|
||||
operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
|
||||
{ return !(__one < __two); }
|
||||
|
||||
// Specialized algorithms.
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
inline void
|
||||
swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
|
||||
noexcept(noexcept(__one.swap(__two)))
|
||||
{ __one.swap(__two); }
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
constexpr _Tp&
|
||||
get(array<_Tp, _Nm>& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
|
||||
_S_ref(__arr._M_elems, _Int);
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
constexpr _Tp&&
|
||||
get(array<_Tp, _Nm>&& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
return std::move(get<_Int>(__arr));
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
constexpr const _Tp&
|
||||
get(const array<_Tp, _Nm>& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
|
||||
_S_ref(__arr._M_elems, _Int);
|
||||
}
|
||||
} // namespace __debug
|
||||
|
||||
// Tuple interface to class template array.
|
||||
|
||||
/// tuple_size
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
struct tuple_size<__debug::array<_Tp, _Nm>>
|
||||
: public integral_constant<std::size_t, _Nm> { };
|
||||
|
||||
/// tuple_element
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
struct tuple_element<_Int, __debug::array<_Tp, _Nm>>
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
typedef _Tp type;
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif // _GLIBCXX_DEBUG_ARRAY
|
426
contrib/sdk/sources/libstdc++-v3/include/debug/bitset
Normal file
426
contrib/sdk/sources/libstdc++-v3/include/debug/bitset
Normal file
@@ -0,0 +1,426 @@
|
||||
// Debugging bitset implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/bitset
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_BITSET
|
||||
#define _GLIBCXX_DEBUG_BITSET
|
||||
|
||||
#include <bitset>
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::bitset with additional safety/checking/debug instrumentation.
|
||||
template<size_t _Nb>
|
||||
class bitset
|
||||
: public _GLIBCXX_STD_C::bitset<_Nb>
|
||||
#if __cplusplus < 201103L
|
||||
, public __gnu_debug::_Safe_sequence_base
|
||||
#endif
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;
|
||||
|
||||
public:
|
||||
// In C++0x we rely on normal reference type to preserve the property
|
||||
// of bitset to be use as a literal.
|
||||
// TODO: Find another solution.
|
||||
#if __cplusplus >= 201103L
|
||||
typedef typename _Base::reference reference;
|
||||
#else
|
||||
// bit reference:
|
||||
class reference
|
||||
: private _Base::reference
|
||||
, public __gnu_debug::_Safe_iterator_base
|
||||
{
|
||||
typedef typename _Base::reference _Base_ref;
|
||||
|
||||
friend class bitset;
|
||||
reference();
|
||||
|
||||
reference(const _Base_ref& __base,
|
||||
bitset* __seq __attribute__((__unused__))) _GLIBCXX_NOEXCEPT
|
||||
: _Base_ref(__base)
|
||||
, _Safe_iterator_base(__seq, false)
|
||||
{ }
|
||||
|
||||
public:
|
||||
reference(const reference& __x) _GLIBCXX_NOEXCEPT
|
||||
: _Base_ref(__x)
|
||||
, _Safe_iterator_base(__x, false)
|
||||
{ }
|
||||
|
||||
reference&
|
||||
operator=(bool __x) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
|
||||
_M_message(__gnu_debug::__msg_bad_bitset_write)
|
||||
._M_iterator(*this));
|
||||
*static_cast<_Base_ref*>(this) = __x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference&
|
||||
operator=(const reference& __x) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __x._M_singular(),
|
||||
_M_message(__gnu_debug::__msg_bad_bitset_read)
|
||||
._M_iterator(__x));
|
||||
_GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
|
||||
_M_message(__gnu_debug::__msg_bad_bitset_write)
|
||||
._M_iterator(*this));
|
||||
*static_cast<_Base_ref*>(this) = __x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
operator~() const _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
|
||||
_M_message(__gnu_debug::__msg_bad_bitset_read)
|
||||
._M_iterator(*this));
|
||||
return ~(*static_cast<const _Base_ref*>(this));
|
||||
}
|
||||
|
||||
operator bool() const _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
|
||||
_M_message(__gnu_debug::__msg_bad_bitset_read)
|
||||
._M_iterator(*this));
|
||||
return *static_cast<const _Base_ref*>(this);
|
||||
}
|
||||
|
||||
reference&
|
||||
flip() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
|
||||
_M_message(__gnu_debug::__msg_bad_bitset_flip)
|
||||
._M_iterator(*this));
|
||||
_Base_ref::flip();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// 23.3.5.1 constructors:
|
||||
_GLIBCXX_CONSTEXPR bitset() _GLIBCXX_NOEXCEPT
|
||||
: _Base() { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
constexpr bitset(unsigned long long __val) noexcept
|
||||
#else
|
||||
bitset(unsigned long __val)
|
||||
#endif
|
||||
: _Base(__val) { }
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
explicit
|
||||
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
|
||||
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
|
||||
__pos = 0,
|
||||
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
|
||||
__n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
|
||||
: _Base(__str, __pos, __n) { }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 396. what are characters zero and one.
|
||||
template<class _CharT, class _Traits, class _Alloc>
|
||||
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
|
||||
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
|
||||
__pos,
|
||||
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
|
||||
__n,
|
||||
_CharT __zero, _CharT __one = _CharT('1'))
|
||||
: _Base(__str, __pos, __n, __zero, __one) { }
|
||||
|
||||
bitset(const _Base& __x) : _Base(__x) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _CharT>
|
||||
explicit
|
||||
bitset(const _CharT* __str,
|
||||
typename std::basic_string<_CharT>::size_type __n
|
||||
= std::basic_string<_CharT>::npos,
|
||||
_CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
|
||||
: _Base(__str, __n, __zero, __one) { }
|
||||
#endif
|
||||
|
||||
// 23.3.5.2 bitset operations:
|
||||
bitset<_Nb>&
|
||||
operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_M_base() &= __rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_M_base() |= __rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_M_base() ^= __rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_M_base() <<= __pos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_M_base() >>= __pos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
set() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_Base::set();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 186. bitset::set() second parameter should be bool
|
||||
bitset<_Nb>&
|
||||
set(size_t __pos, bool __val = true)
|
||||
{
|
||||
_Base::set(__pos, __val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
reset() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_Base::reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
reset(size_t __pos)
|
||||
{
|
||||
_Base::reset(__pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>
|
||||
operator~() const _GLIBCXX_NOEXCEPT
|
||||
{ return bitset(~_M_base()); }
|
||||
|
||||
bitset<_Nb>&
|
||||
flip() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_Base::flip();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset<_Nb>&
|
||||
flip(size_t __pos)
|
||||
{
|
||||
_Base::flip(__pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// element access:
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 11. Bitset minor problems
|
||||
reference
|
||||
operator[](size_t __pos)
|
||||
{
|
||||
__glibcxx_check_subscript(__pos);
|
||||
#if __cplusplus >= 201103L
|
||||
return _M_base()[__pos];
|
||||
#else
|
||||
return reference(_M_base()[__pos], this);
|
||||
#endif
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 11. Bitset minor problems
|
||||
_GLIBCXX_CONSTEXPR bool
|
||||
operator[](size_t __pos) const
|
||||
{
|
||||
#if __cplusplus < 201103L
|
||||
// TODO: Check in debug-mode too.
|
||||
__glibcxx_check_subscript(__pos);
|
||||
#endif
|
||||
return _Base::operator[](__pos);
|
||||
}
|
||||
|
||||
using _Base::to_ulong;
|
||||
#if __cplusplus >= 201103L
|
||||
using _Base::to_ullong;
|
||||
#endif
|
||||
|
||||
template <typename _CharT, typename _Traits, typename _Alloc>
|
||||
std::basic_string<_CharT, _Traits, _Alloc>
|
||||
to_string() const
|
||||
{ return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 396. what are characters zero and one.
|
||||
template<class _CharT, class _Traits, class _Alloc>
|
||||
std::basic_string<_CharT, _Traits, _Alloc>
|
||||
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
|
||||
{
|
||||
return _M_base().template
|
||||
to_string<_CharT, _Traits, _Alloc>(__zero, __one);
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 434. bitset::to_string() hard to use.
|
||||
template<typename _CharT, typename _Traits>
|
||||
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
|
||||
to_string() const
|
||||
{ return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 853. to_string needs updating with zero and one.
|
||||
template<class _CharT, class _Traits>
|
||||
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
|
||||
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
|
||||
{ return to_string<_CharT, _Traits,
|
||||
std::allocator<_CharT> >(__zero, __one); }
|
||||
|
||||
template<typename _CharT>
|
||||
std::basic_string<_CharT, std::char_traits<_CharT>,
|
||||
std::allocator<_CharT> >
|
||||
to_string() const
|
||||
{
|
||||
return to_string<_CharT, std::char_traits<_CharT>,
|
||||
std::allocator<_CharT> >();
|
||||
}
|
||||
|
||||
template<class _CharT>
|
||||
std::basic_string<_CharT, std::char_traits<_CharT>,
|
||||
std::allocator<_CharT> >
|
||||
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
|
||||
{
|
||||
return to_string<_CharT, std::char_traits<_CharT>,
|
||||
std::allocator<_CharT> >(__zero, __one);
|
||||
}
|
||||
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
|
||||
to_string() const
|
||||
{
|
||||
return to_string<char,std::char_traits<char>,std::allocator<char> >();
|
||||
}
|
||||
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
|
||||
to_string(char __zero, char __one = '1') const
|
||||
{
|
||||
return to_string<char, std::char_traits<char>,
|
||||
std::allocator<char> >(__zero, __one);
|
||||
}
|
||||
|
||||
using _Base::count;
|
||||
using _Base::size;
|
||||
|
||||
bool
|
||||
operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
|
||||
{ return _M_base() == __rhs; }
|
||||
|
||||
bool
|
||||
operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
|
||||
{ return _M_base() != __rhs; }
|
||||
|
||||
using _Base::test;
|
||||
using _Base::all;
|
||||
using _Base::any;
|
||||
using _Base::none;
|
||||
|
||||
bitset<_Nb>
|
||||
operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT
|
||||
{ return bitset<_Nb>(_M_base() << __pos); }
|
||||
|
||||
bitset<_Nb>
|
||||
operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT
|
||||
{ return bitset<_Nb>(_M_base() >> __pos); }
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT
|
||||
{ return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
template<size_t _Nb>
|
||||
bitset<_Nb>
|
||||
operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
|
||||
{ return bitset<_Nb>(__x) &= __y; }
|
||||
|
||||
template<size_t _Nb>
|
||||
bitset<_Nb>
|
||||
operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
|
||||
{ return bitset<_Nb>(__x) |= __y; }
|
||||
|
||||
template<size_t _Nb>
|
||||
bitset<_Nb>
|
||||
operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
|
||||
{ return bitset<_Nb>(__x) ^= __y; }
|
||||
|
||||
template<typename _CharT, typename _Traits, size_t _Nb>
|
||||
std::basic_istream<_CharT, _Traits>&
|
||||
operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
|
||||
{ return __is >> __x._M_base(); }
|
||||
|
||||
template<typename _CharT, typename _Traits, size_t _Nb>
|
||||
std::basic_ostream<_CharT, _Traits>&
|
||||
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
|
||||
const bitset<_Nb>& __x)
|
||||
{ return __os << __x._M_base(); }
|
||||
|
||||
} // namespace __debug
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// DR 1182.
|
||||
/// std::hash specialization for bitset.
|
||||
template<size_t _Nb>
|
||||
struct hash<__debug::bitset<_Nb>>
|
||||
: public __hash_base<size_t, __debug::bitset<_Nb>>
|
||||
{
|
||||
size_t
|
||||
operator()(const __debug::bitset<_Nb>& __b) const noexcept
|
||||
{ return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
131
contrib/sdk/sources/libstdc++-v3/include/debug/debug.h
Normal file
131
contrib/sdk/sources/libstdc++-v3/include/debug/debug.h
Normal file
@@ -0,0 +1,131 @@
|
||||
// Debugging support implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/debug.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_MACRO_SWITCH_H
|
||||
#define _GLIBCXX_DEBUG_MACRO_SWITCH_H 1
|
||||
|
||||
/** Macros and namespaces used by the implementation outside of debug
|
||||
* wrappers to verify certain properties. The __glibcxx_requires_xxx
|
||||
* macros are merely wrappers around the __glibcxx_check_xxx wrappers
|
||||
* when we are compiling with debug mode, but disappear when we are
|
||||
* in release mode so that there is no checking performed in, e.g.,
|
||||
* the standard library algorithms.
|
||||
*/
|
||||
|
||||
// Debug mode namespaces.
|
||||
|
||||
/**
|
||||
* @namespace std::__debug
|
||||
* @brief GNU debug code, replaces standard behavior with debug behavior.
|
||||
*/
|
||||
namespace std
|
||||
{
|
||||
namespace __debug { }
|
||||
}
|
||||
|
||||
/** @namespace __gnu_debug
|
||||
* @brief GNU debug classes for public use.
|
||||
*/
|
||||
namespace __gnu_debug
|
||||
{
|
||||
using namespace std::__debug;
|
||||
}
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG
|
||||
|
||||
# define _GLIBCXX_DEBUG_ASSERT(_Condition)
|
||||
# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
|
||||
# define _GLIBCXX_DEBUG_ONLY(_Statement) ;
|
||||
# define __glibcxx_requires_cond(_Cond,_Msg)
|
||||
# define __glibcxx_requires_valid_range(_First,_Last)
|
||||
# define __glibcxx_requires_non_empty_range(_First,_Last)
|
||||
# define __glibcxx_requires_sorted(_First,_Last)
|
||||
# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred)
|
||||
# define __glibcxx_requires_sorted_set(_First1,_Last1,_First2)
|
||||
# define __glibcxx_requires_sorted_set_pred(_First1,_Last1,_First2,_Pred)
|
||||
# define __glibcxx_requires_partitioned_lower(_First,_Last,_Value)
|
||||
# define __glibcxx_requires_partitioned_upper(_First,_Last,_Value)
|
||||
# define __glibcxx_requires_partitioned_lower_pred(_First,_Last,_Value,_Pred)
|
||||
# define __glibcxx_requires_partitioned_upper_pred(_First,_Last,_Value,_Pred)
|
||||
# define __glibcxx_requires_heap(_First,_Last)
|
||||
# define __glibcxx_requires_heap_pred(_First,_Last,_Pred)
|
||||
# define __glibcxx_requires_nonempty()
|
||||
# define __glibcxx_requires_string(_String)
|
||||
# define __glibcxx_requires_string_len(_String,_Len)
|
||||
# define __glibcxx_requires_subscript(_N)
|
||||
|
||||
#else
|
||||
|
||||
# include <debug/macros.h>
|
||||
|
||||
#define _GLIBCXX_DEBUG_ASSERT(_Condition) __glibcxx_assert(_Condition)
|
||||
|
||||
#ifdef _GLIBCXX_DEBUG_PEDANTIC
|
||||
# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition)
|
||||
#else
|
||||
# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
|
||||
#endif
|
||||
|
||||
# define _GLIBCXX_DEBUG_ONLY(_Statement) _Statement
|
||||
|
||||
# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg)
|
||||
# define __glibcxx_requires_valid_range(_First,_Last) \
|
||||
__glibcxx_check_valid_range(_First,_Last)
|
||||
# define __glibcxx_requires_non_empty_range(_First,_Last) \
|
||||
__glibcxx_check_non_empty_range(_First,_Last)
|
||||
# define __glibcxx_requires_sorted(_First,_Last) \
|
||||
__glibcxx_check_sorted(_First,_Last)
|
||||
# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \
|
||||
__glibcxx_check_sorted_pred(_First,_Last,_Pred)
|
||||
# define __glibcxx_requires_sorted_set(_First1,_Last1,_First2) \
|
||||
__glibcxx_check_sorted_set(_First1,_Last1,_First2)
|
||||
# define __glibcxx_requires_sorted_set_pred(_First1,_Last1,_First2,_Pred) \
|
||||
__glibcxx_check_sorted_set_pred(_First1,_Last1,_First2,_Pred)
|
||||
# define __glibcxx_requires_partitioned_lower(_First,_Last,_Value) \
|
||||
__glibcxx_check_partitioned_lower(_First,_Last,_Value)
|
||||
# define __glibcxx_requires_partitioned_upper(_First,_Last,_Value) \
|
||||
__glibcxx_check_partitioned_upper(_First,_Last,_Value)
|
||||
# define __glibcxx_requires_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
|
||||
__glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred)
|
||||
# define __glibcxx_requires_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
|
||||
__glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred)
|
||||
# define __glibcxx_requires_heap(_First,_Last) \
|
||||
__glibcxx_check_heap(_First,_Last)
|
||||
# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \
|
||||
__glibcxx_check_heap_pred(_First,_Last,_Pred)
|
||||
# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty()
|
||||
# define __glibcxx_requires_string(_String) __glibcxx_check_string(_String)
|
||||
# define __glibcxx_requires_string_len(_String,_Len) \
|
||||
__glibcxx_check_string_len(_String,_Len)
|
||||
# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N)
|
||||
|
||||
# include <debug/functions.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _GLIBCXX_DEBUG_MACRO_SWITCH_H
|
579
contrib/sdk/sources/libstdc++-v3/include/debug/deque
Normal file
579
contrib/sdk/sources/libstdc++-v3/include/debug/deque
Normal file
@@ -0,0 +1,579 @@
|
||||
// Debugging deque implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/deque
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_DEQUE
|
||||
#define _GLIBCXX_DEBUG_DEQUE 1
|
||||
|
||||
#include <deque>
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::deque with safety/checking/debug instrumentation.
|
||||
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
|
||||
class deque
|
||||
: public _GLIBCXX_STD_C::deque<_Tp, _Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
|
||||
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
|
||||
public:
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator,deque>
|
||||
iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,deque>
|
||||
const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
|
||||
typedef _Tp value_type;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// 23.2.1.1 construct/copy/destroy:
|
||||
explicit
|
||||
deque(const _Allocator& __a = _Allocator())
|
||||
: _Base(__a) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
explicit
|
||||
deque(size_type __n)
|
||||
: _Base(__n) { }
|
||||
|
||||
deque(size_type __n, const _Tp& __value,
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__n, __value, __a) { }
|
||||
#else
|
||||
explicit
|
||||
deque(size_type __n, const _Tp& __value = _Tp(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__n, __value, __a) { }
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
deque(_InputIterator __first, _InputIterator __last,
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __a)
|
||||
{ }
|
||||
|
||||
deque(const deque& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
deque(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
deque(deque&& __x)
|
||||
: _Base(std::move(__x))
|
||||
{ this->_M_swap(__x); }
|
||||
|
||||
deque(initializer_list<value_type> __l,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __a) { }
|
||||
#endif
|
||||
|
||||
~deque() _GLIBCXX_NOEXCEPT { }
|
||||
|
||||
deque&
|
||||
operator=(const deque& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
deque&
|
||||
operator=(deque&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
deque&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __l;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
void
|
||||
assign(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::assign(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
void
|
||||
assign(size_type __n, const _Tp& __t)
|
||||
{
|
||||
_Base::assign(__n, __t);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
assign(initializer_list<value_type> __l)
|
||||
{
|
||||
_Base::assign(__l);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
iterator
|
||||
begin() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_after_nth(difference_type __n)
|
||||
{
|
||||
typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
|
||||
this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
|
||||
}
|
||||
|
||||
public:
|
||||
// 23.2.1.2 capacity:
|
||||
using _Base::size;
|
||||
using _Base::max_size;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
resize(size_type __sz)
|
||||
{
|
||||
bool __invalidate_all = __sz > this->size();
|
||||
if (__sz < this->size())
|
||||
this->_M_invalidate_after_nth(__sz);
|
||||
|
||||
_Base::resize(__sz);
|
||||
|
||||
if (__invalidate_all)
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
void
|
||||
resize(size_type __sz, const _Tp& __c)
|
||||
{
|
||||
bool __invalidate_all = __sz > this->size();
|
||||
if (__sz < this->size())
|
||||
this->_M_invalidate_after_nth(__sz);
|
||||
|
||||
_Base::resize(__sz, __c);
|
||||
|
||||
if (__invalidate_all)
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
#else
|
||||
void
|
||||
resize(size_type __sz, _Tp __c = _Tp())
|
||||
{
|
||||
bool __invalidate_all = __sz > this->size();
|
||||
if (__sz < this->size())
|
||||
this->_M_invalidate_after_nth(__sz);
|
||||
|
||||
_Base::resize(__sz, __c);
|
||||
|
||||
if (__invalidate_all)
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
shrink_to_fit()
|
||||
{
|
||||
if (_Base::_M_shrink_to_fit())
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
using _Base::empty;
|
||||
|
||||
// element access:
|
||||
reference
|
||||
operator[](size_type __n)
|
||||
{
|
||||
__glibcxx_check_subscript(__n);
|
||||
return _M_base()[__n];
|
||||
}
|
||||
|
||||
const_reference
|
||||
operator[](size_type __n) const
|
||||
{
|
||||
__glibcxx_check_subscript(__n);
|
||||
return _M_base()[__n];
|
||||
}
|
||||
|
||||
using _Base::at;
|
||||
|
||||
reference
|
||||
front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
reference
|
||||
back()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::back();
|
||||
}
|
||||
|
||||
const_reference
|
||||
back() const
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::back();
|
||||
}
|
||||
|
||||
// 23.2.1.3 modifiers:
|
||||
void
|
||||
push_front(const _Tp& __x)
|
||||
{
|
||||
_Base::push_front(__x);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
void
|
||||
push_back(const _Tp& __x)
|
||||
{
|
||||
_Base::push_back(__x);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
push_front(_Tp&& __x)
|
||||
{ emplace_front(std::move(__x)); }
|
||||
|
||||
void
|
||||
push_back(_Tp&& __x)
|
||||
{ emplace_back(std::move(__x)); }
|
||||
|
||||
template<typename... _Args>
|
||||
void
|
||||
emplace_front(_Args&&... __args)
|
||||
{
|
||||
_Base::emplace_front(std::forward<_Args>(__args)...);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
void
|
||||
emplace_back(_Args&&... __args)
|
||||
{
|
||||
_Base::emplace_back(std::forward<_Args>(__args)...);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace(iterator __position, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
_Base_iterator __res = _Base::emplace(__position.base(),
|
||||
std::forward<_Args>(__args)...);
|
||||
this->_M_invalidate_all();
|
||||
return iterator(__res, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator
|
||||
insert(iterator __position, const _Tp& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
_Base_iterator __res = _Base::insert(__position.base(), __x);
|
||||
this->_M_invalidate_all();
|
||||
return iterator(__res, this);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
insert(iterator __position, _Tp&& __x)
|
||||
{ return emplace(__position, std::move(__x)); }
|
||||
|
||||
void
|
||||
insert(iterator __p, initializer_list<value_type> __l)
|
||||
{
|
||||
_Base::insert(__p, __l);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
insert(iterator __position, size_type __n, const _Tp& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
_Base::insert(__position.base(), __n, __x);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
void
|
||||
insert(iterator __position,
|
||||
_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_insert_range(__position, __first, __last);
|
||||
_Base::insert(__position.base(), __gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
void
|
||||
pop_front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
this->_M_invalidate_if(_Equal(_Base::begin()));
|
||||
_Base::pop_front();
|
||||
}
|
||||
|
||||
void
|
||||
pop_back()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
this->_M_invalidate_if(_Equal(--_Base::end()));
|
||||
_Base::pop_back();
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
_Base_iterator __victim = __position.base();
|
||||
if (__victim == _Base::begin() || __victim == _Base::end()-1)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
return iterator(_Base::erase(__victim), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_Base_iterator __res = _Base::erase(__victim);
|
||||
this->_M_invalidate_all();
|
||||
return iterator(__res, this);
|
||||
}
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __first, iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
|
||||
if (__first.base() == __last.base())
|
||||
return __first;
|
||||
else if (__first.base() == _Base::begin()
|
||||
|| __last.base() == _Base::end())
|
||||
{
|
||||
this->_M_detach_singular();
|
||||
for (_Base_iterator __position = __first.base();
|
||||
__position != __last.base(); ++__position)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__position));
|
||||
}
|
||||
__try
|
||||
{
|
||||
return iterator(_Base::erase(__first.base(), __last.base()),
|
||||
this);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
this->_M_revalidate_singular();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_Base_iterator __res = _Base::erase(__first.base(),
|
||||
__last.base());
|
||||
this->_M_invalidate_all();
|
||||
return iterator(__res, this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
swap(deque& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
|
||||
};
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator==(const deque<_Tp, _Alloc>& __lhs,
|
||||
const deque<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() == __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const deque<_Tp, _Alloc>& __lhs,
|
||||
const deque<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() != __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<(const deque<_Tp, _Alloc>& __lhs,
|
||||
const deque<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() < __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<=(const deque<_Tp, _Alloc>& __lhs,
|
||||
const deque<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() <= __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>=(const deque<_Tp, _Alloc>& __lhs,
|
||||
const deque<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() >= __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>(const deque<_Tp, _Alloc>& __lhs,
|
||||
const deque<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() > __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline void
|
||||
swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
|
||||
{ __lhs.swap(__rhs); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif
|
462
contrib/sdk/sources/libstdc++-v3/include/debug/formatter.h
Normal file
462
contrib/sdk/sources/libstdc++-v3/include/debug/formatter.h
Normal file
@@ -0,0 +1,462 @@
|
||||
// Debug-mode error formatting implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/formatter.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_FORMATTER_H
|
||||
#define _GLIBCXX_DEBUG_FORMATTER_H 1
|
||||
|
||||
#include <bits/c++config.h>
|
||||
#include <bits/cpp_type_traits.h>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
using std::type_info;
|
||||
|
||||
template<typename _Iterator>
|
||||
bool __check_singular(_Iterator&);
|
||||
|
||||
class _Safe_sequence_base;
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
class _Safe_iterator;
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
class _Safe_local_iterator;
|
||||
|
||||
template<typename _Sequence>
|
||||
class _Safe_sequence;
|
||||
|
||||
enum _Debug_msg_id
|
||||
{
|
||||
// General checks
|
||||
__msg_valid_range,
|
||||
__msg_insert_singular,
|
||||
__msg_insert_different,
|
||||
__msg_erase_bad,
|
||||
__msg_erase_different,
|
||||
__msg_subscript_oob,
|
||||
__msg_empty,
|
||||
__msg_unpartitioned,
|
||||
__msg_unpartitioned_pred,
|
||||
__msg_unsorted,
|
||||
__msg_unsorted_pred,
|
||||
__msg_not_heap,
|
||||
__msg_not_heap_pred,
|
||||
// std::bitset checks
|
||||
__msg_bad_bitset_write,
|
||||
__msg_bad_bitset_read,
|
||||
__msg_bad_bitset_flip,
|
||||
// std::list checks
|
||||
__msg_self_splice,
|
||||
__msg_splice_alloc,
|
||||
__msg_splice_bad,
|
||||
__msg_splice_other,
|
||||
__msg_splice_overlap,
|
||||
// iterator checks
|
||||
__msg_init_singular,
|
||||
__msg_init_copy_singular,
|
||||
__msg_init_const_singular,
|
||||
__msg_copy_singular,
|
||||
__msg_bad_deref,
|
||||
__msg_bad_inc,
|
||||
__msg_bad_dec,
|
||||
__msg_iter_subscript_oob,
|
||||
__msg_advance_oob,
|
||||
__msg_retreat_oob,
|
||||
__msg_iter_compare_bad,
|
||||
__msg_compare_different,
|
||||
__msg_iter_order_bad,
|
||||
__msg_order_different,
|
||||
__msg_distance_bad,
|
||||
__msg_distance_different,
|
||||
// istream_iterator
|
||||
__msg_deref_istream,
|
||||
__msg_inc_istream,
|
||||
// ostream_iterator
|
||||
__msg_output_ostream,
|
||||
// istreambuf_iterator
|
||||
__msg_deref_istreambuf,
|
||||
__msg_inc_istreambuf,
|
||||
// forward_list
|
||||
__msg_insert_after_end,
|
||||
__msg_erase_after_bad,
|
||||
__msg_valid_range2,
|
||||
// unordered container local iterators
|
||||
__msg_local_iter_compare_bad,
|
||||
__msg_non_empty_range,
|
||||
// self move assign
|
||||
__msg_self_move_assign,
|
||||
// unordered container buckets
|
||||
__msg_bucket_index_oob,
|
||||
__msg_valid_load_factor,
|
||||
__msg_equal_allocs
|
||||
};
|
||||
|
||||
class _Error_formatter
|
||||
{
|
||||
/// Whether an iterator is constant, mutable, or unknown
|
||||
enum _Constness
|
||||
{
|
||||
__unknown_constness,
|
||||
__const_iterator,
|
||||
__mutable_iterator,
|
||||
__last_constness
|
||||
};
|
||||
|
||||
// The state of the iterator (fine-grained), if we know it.
|
||||
enum _Iterator_state
|
||||
{
|
||||
__unknown_state,
|
||||
__singular, // singular, may still be attached to a sequence
|
||||
__begin, // dereferenceable, and at the beginning
|
||||
__middle, // dereferenceable, not at the beginning
|
||||
__end, // past-the-end, may be at beginning if sequence empty
|
||||
__before_begin, // before begin
|
||||
__last_state
|
||||
};
|
||||
|
||||
// Tags denoting the type of parameter for construction
|
||||
struct _Is_iterator { };
|
||||
struct _Is_sequence { };
|
||||
|
||||
// A parameter that may be referenced by an error message
|
||||
struct _Parameter
|
||||
{
|
||||
enum
|
||||
{
|
||||
__unused_param,
|
||||
__iterator,
|
||||
__sequence,
|
||||
__integer,
|
||||
__string
|
||||
} _M_kind;
|
||||
|
||||
union
|
||||
{
|
||||
// When _M_kind == __iterator
|
||||
struct
|
||||
{
|
||||
const char* _M_name;
|
||||
const void* _M_address;
|
||||
const type_info* _M_type;
|
||||
_Constness _M_constness;
|
||||
_Iterator_state _M_state;
|
||||
const void* _M_sequence;
|
||||
const type_info* _M_seq_type;
|
||||
} _M_iterator;
|
||||
|
||||
// When _M_kind == __sequence
|
||||
struct
|
||||
{
|
||||
const char* _M_name;
|
||||
const void* _M_address;
|
||||
const type_info* _M_type;
|
||||
} _M_sequence;
|
||||
|
||||
// When _M_kind == __integer
|
||||
struct
|
||||
{
|
||||
const char* _M_name;
|
||||
long _M_value;
|
||||
} _M_integer;
|
||||
|
||||
// When _M_kind == __string
|
||||
struct
|
||||
{
|
||||
const char* _M_name;
|
||||
const char* _M_value;
|
||||
} _M_string;
|
||||
} _M_variant;
|
||||
|
||||
_Parameter() : _M_kind(__unused_param), _M_variant() { }
|
||||
|
||||
_Parameter(long __value, const char* __name)
|
||||
: _M_kind(__integer), _M_variant()
|
||||
{
|
||||
_M_variant._M_integer._M_name = __name;
|
||||
_M_variant._M_integer._M_value = __value;
|
||||
}
|
||||
|
||||
_Parameter(const char* __value, const char* __name)
|
||||
: _M_kind(__string), _M_variant()
|
||||
{
|
||||
_M_variant._M_string._M_name = __name;
|
||||
_M_variant._M_string._M_value = __value;
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
_Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it,
|
||||
const char* __name, _Is_iterator)
|
||||
: _M_kind(__iterator), _M_variant()
|
||||
{
|
||||
_M_variant._M_iterator._M_name = __name;
|
||||
_M_variant._M_iterator._M_address = &__it;
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_iterator._M_type = &typeid(__it);
|
||||
#else
|
||||
_M_variant._M_iterator._M_type = 0;
|
||||
#endif
|
||||
_M_variant._M_iterator._M_constness =
|
||||
std::__are_same<_Safe_iterator<_Iterator, _Sequence>,
|
||||
typename _Sequence::iterator>::
|
||||
__value ? __mutable_iterator : __const_iterator;
|
||||
_M_variant._M_iterator._M_sequence = __it._M_get_sequence();
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
|
||||
#else
|
||||
_M_variant._M_iterator._M_seq_type = 0;
|
||||
#endif
|
||||
|
||||
if (__it._M_singular())
|
||||
_M_variant._M_iterator._M_state = __singular;
|
||||
else
|
||||
{
|
||||
if (__it._M_is_before_begin())
|
||||
_M_variant._M_iterator._M_state = __before_begin;
|
||||
else if (__it._M_is_end())
|
||||
_M_variant._M_iterator._M_state = __end;
|
||||
else if (__it._M_is_begin())
|
||||
_M_variant._M_iterator._M_state = __begin;
|
||||
else
|
||||
_M_variant._M_iterator._M_state = __middle;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
_Parameter(const _Safe_local_iterator<_Iterator, _Sequence>& __it,
|
||||
const char* __name, _Is_iterator)
|
||||
: _M_kind(__iterator), _M_variant()
|
||||
{
|
||||
_M_variant._M_iterator._M_name = __name;
|
||||
_M_variant._M_iterator._M_address = &__it;
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_iterator._M_type = &typeid(__it);
|
||||
#else
|
||||
_M_variant._M_iterator._M_type = 0;
|
||||
#endif
|
||||
_M_variant._M_iterator._M_constness =
|
||||
std::__are_same<_Safe_local_iterator<_Iterator, _Sequence>,
|
||||
typename _Sequence::local_iterator>::
|
||||
__value ? __mutable_iterator : __const_iterator;
|
||||
_M_variant._M_iterator._M_sequence = __it._M_get_sequence();
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
|
||||
#else
|
||||
_M_variant._M_iterator._M_seq_type = 0;
|
||||
#endif
|
||||
|
||||
if (__it._M_singular())
|
||||
_M_variant._M_iterator._M_state = __singular;
|
||||
else
|
||||
{
|
||||
if (__it._M_is_end())
|
||||
_M_variant._M_iterator._M_state = __end;
|
||||
else if (__it._M_is_begin())
|
||||
_M_variant._M_iterator._M_state = __begin;
|
||||
else
|
||||
_M_variant._M_iterator._M_state = __middle;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Type>
|
||||
_Parameter(const _Type*& __it, const char* __name, _Is_iterator)
|
||||
: _M_kind(__iterator), _M_variant()
|
||||
{
|
||||
_M_variant._M_iterator._M_name = __name;
|
||||
_M_variant._M_iterator._M_address = &__it;
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_iterator._M_type = &typeid(__it);
|
||||
#else
|
||||
_M_variant._M_iterator._M_type = 0;
|
||||
#endif
|
||||
_M_variant._M_iterator._M_constness = __mutable_iterator;
|
||||
_M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
|
||||
_M_variant._M_iterator._M_sequence = 0;
|
||||
_M_variant._M_iterator._M_seq_type = 0;
|
||||
}
|
||||
|
||||
template<typename _Type>
|
||||
_Parameter(_Type*& __it, const char* __name, _Is_iterator)
|
||||
: _M_kind(__iterator), _M_variant()
|
||||
{
|
||||
_M_variant._M_iterator._M_name = __name;
|
||||
_M_variant._M_iterator._M_address = &__it;
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_iterator._M_type = &typeid(__it);
|
||||
#else
|
||||
_M_variant._M_iterator._M_type = 0;
|
||||
#endif
|
||||
_M_variant._M_iterator._M_constness = __const_iterator;
|
||||
_M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
|
||||
_M_variant._M_iterator._M_sequence = 0;
|
||||
_M_variant._M_iterator._M_seq_type = 0;
|
||||
}
|
||||
|
||||
template<typename _Iterator>
|
||||
_Parameter(const _Iterator& __it, const char* __name, _Is_iterator)
|
||||
: _M_kind(__iterator), _M_variant()
|
||||
{
|
||||
_M_variant._M_iterator._M_name = __name;
|
||||
_M_variant._M_iterator._M_address = &__it;
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_iterator._M_type = &typeid(__it);
|
||||
#else
|
||||
_M_variant._M_iterator._M_type = 0;
|
||||
#endif
|
||||
_M_variant._M_iterator._M_constness = __unknown_constness;
|
||||
_M_variant._M_iterator._M_state =
|
||||
__gnu_debug::__check_singular(__it)? __singular : __unknown_state;
|
||||
_M_variant._M_iterator._M_sequence = 0;
|
||||
_M_variant._M_iterator._M_seq_type = 0;
|
||||
}
|
||||
|
||||
template<typename _Sequence>
|
||||
_Parameter(const _Safe_sequence<_Sequence>& __seq,
|
||||
const char* __name, _Is_sequence)
|
||||
: _M_kind(__sequence), _M_variant()
|
||||
{
|
||||
_M_variant._M_sequence._M_name = __name;
|
||||
_M_variant._M_sequence._M_address =
|
||||
static_cast<const _Sequence*>(&__seq);
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_sequence._M_type = &typeid(_Sequence);
|
||||
#else
|
||||
_M_variant._M_sequence._M_type = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename _Sequence>
|
||||
_Parameter(const _Sequence& __seq, const char* __name, _Is_sequence)
|
||||
: _M_kind(__sequence), _M_variant()
|
||||
{
|
||||
_M_variant._M_sequence._M_name = __name;
|
||||
_M_variant._M_sequence._M_address = &__seq;
|
||||
#ifdef __GXX_RTTI
|
||||
_M_variant._M_sequence._M_type = &typeid(_Sequence);
|
||||
#else
|
||||
_M_variant._M_sequence._M_type = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_M_print_field(const _Error_formatter* __formatter,
|
||||
const char* __name) const;
|
||||
|
||||
void
|
||||
_M_print_description(const _Error_formatter* __formatter) const;
|
||||
};
|
||||
|
||||
friend struct _Parameter;
|
||||
|
||||
public:
|
||||
template<typename _Iterator>
|
||||
const _Error_formatter&
|
||||
_M_iterator(const _Iterator& __it, const char* __name = 0) const
|
||||
{
|
||||
if (_M_num_parameters < std::size_t(__max_parameters))
|
||||
_M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
|
||||
_Is_iterator());
|
||||
return *this;
|
||||
}
|
||||
|
||||
const _Error_formatter&
|
||||
_M_integer(long __value, const char* __name = 0) const
|
||||
{
|
||||
if (_M_num_parameters < std::size_t(__max_parameters))
|
||||
_M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const _Error_formatter&
|
||||
_M_string(const char* __value, const char* __name = 0) const
|
||||
{
|
||||
if (_M_num_parameters < std::size_t(__max_parameters))
|
||||
_M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _Sequence>
|
||||
const _Error_formatter&
|
||||
_M_sequence(const _Sequence& __seq, const char* __name = 0) const
|
||||
{
|
||||
if (_M_num_parameters < std::size_t(__max_parameters))
|
||||
_M_parameters[_M_num_parameters++] = _Parameter(__seq, __name,
|
||||
_Is_sequence());
|
||||
return *this;
|
||||
}
|
||||
|
||||
const _Error_formatter&
|
||||
_M_message(const char* __text) const
|
||||
{ _M_text = __text; return *this; }
|
||||
|
||||
const _Error_formatter&
|
||||
_M_message(_Debug_msg_id __id) const throw ();
|
||||
|
||||
_GLIBCXX_NORETURN void
|
||||
_M_error() const;
|
||||
|
||||
private:
|
||||
_Error_formatter(const char* __file, std::size_t __line)
|
||||
: _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0),
|
||||
_M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false)
|
||||
{ _M_get_max_length(); }
|
||||
|
||||
template<typename _Tp>
|
||||
void
|
||||
_M_format_word(char*, int, const char*, _Tp) const throw ();
|
||||
|
||||
void
|
||||
_M_print_word(const char* __word) const;
|
||||
|
||||
void
|
||||
_M_print_string(const char* __string) const;
|
||||
|
||||
void
|
||||
_M_get_max_length() const throw ();
|
||||
|
||||
enum { __max_parameters = 9 };
|
||||
|
||||
const char* _M_file;
|
||||
std::size_t _M_line;
|
||||
mutable _Parameter _M_parameters[__max_parameters];
|
||||
mutable std::size_t _M_num_parameters;
|
||||
mutable const char* _M_text;
|
||||
mutable std::size_t _M_max_length;
|
||||
enum { _M_indent = 4 } ;
|
||||
mutable std::size_t _M_column;
|
||||
mutable bool _M_first_line;
|
||||
mutable bool _M_wordwrap;
|
||||
|
||||
public:
|
||||
static _Error_formatter
|
||||
_M_at(const char* __file, std::size_t __line)
|
||||
{ return _Error_formatter(__file, __line); }
|
||||
};
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
801
contrib/sdk/sources/libstdc++-v3/include/debug/forward_list
Normal file
801
contrib/sdk/sources/libstdc++-v3/include/debug/forward_list
Normal file
@@ -0,0 +1,801 @@
|
||||
// <forward_list> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2010-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/forward_list
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_FORWARD_LIST
|
||||
#define _GLIBCXX_DEBUG_FORWARD_LIST 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include <forward_list>
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::forward_list with safety/checking/debug instrumentation.
|
||||
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
|
||||
class forward_list
|
||||
: public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>,
|
||||
public __gnu_debug::_Safe_sequence<forward_list<_Tp, _Alloc> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;
|
||||
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
|
||||
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
|
||||
rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
|
||||
|
||||
typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
|
||||
|
||||
public:
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator,
|
||||
forward_list> iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
|
||||
forward_list> const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
|
||||
typedef _Tp value_type;
|
||||
typedef _Alloc allocator_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
|
||||
// 23.2.3.1 construct/copy/destroy:
|
||||
explicit
|
||||
forward_list(const _Alloc& __al = _Alloc())
|
||||
: _Base(__al) { }
|
||||
|
||||
forward_list(const forward_list& __list, const _Alloc& __al)
|
||||
: _Base(__list, __al)
|
||||
{ }
|
||||
|
||||
forward_list(forward_list&& __list, const _Alloc& __al)
|
||||
: _Base(std::move(__list._M_base()), __al)
|
||||
{
|
||||
if (__list.get_allocator() == __al)
|
||||
this->_M_swap(__list);
|
||||
else
|
||||
__list._M_invalidate_all();
|
||||
}
|
||||
|
||||
explicit
|
||||
forward_list(size_type __n, const _Alloc& __al = _Alloc())
|
||||
: _Base(__n, __al)
|
||||
{ }
|
||||
|
||||
forward_list(size_type __n, const _Tp& __value,
|
||||
const _Alloc& __al = _Alloc())
|
||||
: _Base(__n, __value, __al)
|
||||
{ }
|
||||
|
||||
template<typename _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
forward_list(_InputIterator __first, _InputIterator __last,
|
||||
const _Alloc& __al = _Alloc())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __al)
|
||||
{ }
|
||||
|
||||
forward_list(const forward_list& __list)
|
||||
: _Base(__list)
|
||||
{ }
|
||||
|
||||
forward_list(forward_list&& __list) noexcept
|
||||
: _Base(std::move(__list._M_base()))
|
||||
{
|
||||
this->_M_swap(__list);
|
||||
}
|
||||
|
||||
forward_list(std::initializer_list<_Tp> __il,
|
||||
const _Alloc& __al = _Alloc())
|
||||
: _Base(__il, __al)
|
||||
{ }
|
||||
|
||||
~forward_list() noexcept
|
||||
{ }
|
||||
|
||||
forward_list&
|
||||
operator=(const forward_list& __list)
|
||||
{
|
||||
static_cast<_Base&>(*this) = __list;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
forward_list&
|
||||
operator=(forward_list&& __list)
|
||||
noexcept(_Node_alloc_traits::_S_nothrow_move())
|
||||
{
|
||||
__glibcxx_check_self_move_assign(__list);
|
||||
bool xfer_memory = _Node_alloc_traits::_S_propagate_on_move_assign()
|
||||
|| __list.get_allocator() == this->get_allocator();
|
||||
static_cast<_Base&>(*this) = std::move(__list);
|
||||
if (xfer_memory)
|
||||
this->_M_swap(__list);
|
||||
else
|
||||
this->_M_invalidate_all();
|
||||
__list._M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
forward_list&
|
||||
operator=(std::initializer_list<_Tp> __il)
|
||||
{
|
||||
static_cast<_Base&>(*this) = __il;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
void
|
||||
assign(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::assign(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
void
|
||||
assign(size_type __n, const _Tp& __val)
|
||||
{
|
||||
_Base::assign(__n, __val);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
void
|
||||
assign(std::initializer_list<_Tp> __il)
|
||||
{
|
||||
_Base::assign(__il);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
|
||||
iterator
|
||||
before_begin() noexcept
|
||||
{ return iterator(_Base::before_begin(), this); }
|
||||
|
||||
const_iterator
|
||||
before_begin() const noexcept
|
||||
{ return const_iterator(_Base::before_begin(), this); }
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::cbegin(), this); }
|
||||
|
||||
const_iterator
|
||||
cbefore_begin() const noexcept
|
||||
{ return const_iterator(_Base::cbefore_begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::cend(), this); }
|
||||
|
||||
using _Base::empty;
|
||||
using _Base::max_size;
|
||||
|
||||
// element access:
|
||||
|
||||
reference
|
||||
front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
// modifiers:
|
||||
|
||||
using _Base::emplace_front;
|
||||
using _Base::push_front;
|
||||
|
||||
void
|
||||
pop_front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
this->_M_invalidate_if([this](_Base_const_iterator __it)
|
||||
{ return __it == this->_M_base().cbegin(); });
|
||||
_Base::pop_front();
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_after(const_iterator __pos, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
return iterator(_Base::emplace_after(__pos.base(),
|
||||
std::forward<_Args>(__args)...),
|
||||
this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert_after(const_iterator __pos, const _Tp& __val)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
return iterator(_Base::insert_after(__pos.base(), __val), this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert_after(const_iterator __pos, _Tp&& __val)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
return iterator(_Base::insert_after(__pos.base(), std::move(__val)),
|
||||
this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert_after(const_iterator __pos, size_type __n, const _Tp& __val)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
return iterator(_Base::insert_after(__pos.base(), __n, __val),
|
||||
this);
|
||||
}
|
||||
|
||||
template<typename _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
iterator
|
||||
insert_after(const_iterator __pos,
|
||||
_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_insert_range_after(__pos, __first, __last);
|
||||
return iterator(_Base::insert_after(__pos.base(),
|
||||
__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last)),
|
||||
this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert_after(const_iterator __pos, std::initializer_list<_Tp> __il)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
return iterator(_Base::insert_after(__pos.base(), __il), this);
|
||||
}
|
||||
|
||||
private:
|
||||
_Base_iterator
|
||||
_M_erase_after(_Base_const_iterator __pos)
|
||||
{
|
||||
_Base_const_iterator __next = std::next(__pos);
|
||||
this->_M_invalidate_if([__next](_Base_const_iterator __it)
|
||||
{ return __it == __next; });
|
||||
return _Base::erase_after(__pos);
|
||||
}
|
||||
public:
|
||||
iterator
|
||||
erase_after(const_iterator __pos)
|
||||
{
|
||||
__glibcxx_check_erase_after(__pos);
|
||||
return iterator(_M_erase_after(__pos.base()), this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase_after(const_iterator __pos, const_iterator __last)
|
||||
{
|
||||
__glibcxx_check_erase_range_after(__pos, __last);
|
||||
for (_Base_const_iterator __victim = std::next(__pos.base());
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range2)
|
||||
._M_sequence(*this, "this")
|
||||
._M_iterator(__pos, "pos")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
}
|
||||
return iterator(_Base::erase_after(__pos.base(), __last.base()), this);
|
||||
}
|
||||
|
||||
void
|
||||
swap(forward_list& __list)
|
||||
noexcept(_Node_alloc_traits::_S_nothrow_swap())
|
||||
{
|
||||
if (!_Node_alloc_traits::_S_propagate_on_swap())
|
||||
__glibcxx_check_equal_allocs(__list);
|
||||
_Base::swap(__list);
|
||||
this->_M_swap(__list);
|
||||
}
|
||||
|
||||
void
|
||||
resize(size_type __sz)
|
||||
{
|
||||
this->_M_detach_singular();
|
||||
|
||||
// if __sz < size(), invalidate all iterators in [begin+__sz, end()
|
||||
_Base_iterator __victim = _Base::begin();
|
||||
_Base_iterator __end = _Base::end();
|
||||
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
|
||||
++__victim;
|
||||
|
||||
for (; __victim != __end; ++__victim)
|
||||
{
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
_Base::resize(__sz);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
this->_M_revalidate_singular();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
resize(size_type __sz, const value_type& __val)
|
||||
{
|
||||
this->_M_detach_singular();
|
||||
|
||||
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
|
||||
_Base_iterator __victim = _Base::begin();
|
||||
_Base_iterator __end = _Base::end();
|
||||
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
|
||||
++__victim;
|
||||
|
||||
for (; __victim != __end; ++__victim)
|
||||
{
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
_Base::resize(__sz, __val);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
this->_M_revalidate_singular();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
// 23.2.3.5 forward_list operations:
|
||||
void
|
||||
splice_after(const_iterator __pos, forward_list&& __list)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
_GLIBCXX_DEBUG_VERIFY(&__list != this,
|
||||
_M_message(__gnu_debug::__msg_self_splice)
|
||||
._M_sequence(*this, "this"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
|
||||
_M_message(__gnu_debug::__msg_splice_alloc)
|
||||
._M_sequence(*this)
|
||||
._M_sequence(__list, "__list"));
|
||||
this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
|
||||
{
|
||||
return __it != __list._M_base().cbefore_begin()
|
||||
&& __it != __list._M_base().end();
|
||||
});
|
||||
_Base::splice_after(__pos.base(), std::move(__list._M_base()));
|
||||
}
|
||||
|
||||
void
|
||||
splice_after(const_iterator __pos, forward_list& __list)
|
||||
{ splice_after(__pos, std::move(__list)); }
|
||||
|
||||
void
|
||||
splice_after(const_iterator __pos, forward_list&& __list,
|
||||
const_iterator __i)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
_GLIBCXX_DEBUG_VERIFY(__i._M_before_dereferenceable(),
|
||||
_M_message(__gnu_debug::__msg_splice_bad)
|
||||
._M_iterator(__i, "__i"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__list),
|
||||
_M_message(__gnu_debug::__msg_splice_other)
|
||||
._M_iterator(__i, "__i")
|
||||
._M_sequence(__list, "__list"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
|
||||
_M_message(__gnu_debug::__msg_splice_alloc)
|
||||
._M_sequence(*this)
|
||||
._M_sequence(__list, "__list"));
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 250. splicing invalidates iterators
|
||||
_Base_const_iterator __next = std::next(__i.base());
|
||||
this->_M_transfer_from_if(__list, [__next](_Base_const_iterator __it)
|
||||
{ return __it == __next; });
|
||||
_Base::splice_after(__pos.base(), std::move(__list._M_base()),
|
||||
__i.base());
|
||||
}
|
||||
|
||||
void
|
||||
splice_after(const_iterator __pos, forward_list& __list,
|
||||
const_iterator __i)
|
||||
{ splice_after(__pos, std::move(__list), __i); }
|
||||
|
||||
void
|
||||
splice_after(const_iterator __pos, forward_list&& __list,
|
||||
const_iterator __before, const_iterator __last)
|
||||
{
|
||||
__glibcxx_check_insert_after(__pos);
|
||||
__glibcxx_check_valid_range(__before, __last);
|
||||
_GLIBCXX_DEBUG_VERIFY(__before._M_attached_to(&__list),
|
||||
_M_message(__gnu_debug::__msg_splice_other)
|
||||
._M_sequence(__list, "list")
|
||||
._M_iterator(__before, "before"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__before._M_dereferenceable()
|
||||
|| __before._M_is_before_begin(),
|
||||
_M_message(__gnu_debug::__msg_valid_range2)
|
||||
._M_sequence(__list, "list")
|
||||
._M_iterator(__before, "before")
|
||||
._M_iterator(__last, "last"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__before != __last,
|
||||
_M_message(__gnu_debug::__msg_valid_range2)
|
||||
._M_sequence(__list, "list")
|
||||
._M_iterator(__before, "before")
|
||||
._M_iterator(__last, "last"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
|
||||
_M_message(__gnu_debug::__msg_splice_alloc)
|
||||
._M_sequence(*this)
|
||||
._M_sequence(__list, "__list"));
|
||||
|
||||
for (_Base_const_iterator __tmp = std::next(__before.base());
|
||||
__tmp != __last.base(); ++__tmp)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__tmp != __list._M_base().end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range2)
|
||||
._M_sequence(__list, "list")
|
||||
._M_iterator(__before, "before")
|
||||
._M_iterator(__last, "last"));
|
||||
_GLIBCXX_DEBUG_VERIFY(&__list != this || __tmp != __pos.base(),
|
||||
_M_message(__gnu_debug::__msg_splice_overlap)
|
||||
._M_iterator(__tmp, "position")
|
||||
._M_iterator(__before, "before")
|
||||
._M_iterator(__last, "last"));
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 250. splicing invalidates iterators
|
||||
this->_M_transfer_from_if(__list, [__tmp](_Base_const_iterator __it)
|
||||
{ return __it == __tmp; });
|
||||
}
|
||||
|
||||
_Base::splice_after(__pos.base(), std::move(__list._M_base()),
|
||||
__before.base(), __last.base());
|
||||
}
|
||||
|
||||
void
|
||||
splice_after(const_iterator __pos, forward_list& __list,
|
||||
const_iterator __before, const_iterator __last)
|
||||
{ splice_after(__pos, std::move(__list), __before, __last); }
|
||||
|
||||
void
|
||||
remove(const _Tp& __val)
|
||||
{
|
||||
_Base_iterator __x = _Base::before_begin();
|
||||
_Base_iterator __old = __x++;
|
||||
while (__x != _Base::end())
|
||||
{
|
||||
if (*__x == __val)
|
||||
__x = _M_erase_after(__old);
|
||||
else
|
||||
__old = __x++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Pred>
|
||||
void
|
||||
remove_if(_Pred __pred)
|
||||
{
|
||||
_Base_iterator __x = _Base::before_begin();
|
||||
_Base_iterator __old = __x++;
|
||||
while (__x != _Base::end())
|
||||
{
|
||||
if (__pred(*__x))
|
||||
__x = _M_erase_after(__old);
|
||||
else
|
||||
__old = __x++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unique()
|
||||
{
|
||||
_Base_iterator __first = _Base::begin();
|
||||
_Base_iterator __last = _Base::end();
|
||||
if (__first == __last)
|
||||
return;
|
||||
_Base_iterator __next = std::next(__first);
|
||||
while (__next != __last)
|
||||
{
|
||||
if (*__first == *__next)
|
||||
__next = _M_erase_after(__first);
|
||||
else
|
||||
__first = __next++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _BinPred>
|
||||
void
|
||||
unique(_BinPred __binary_pred)
|
||||
{
|
||||
_Base_iterator __first = _Base::begin();
|
||||
_Base_iterator __last = _Base::end();
|
||||
if (__first == __last)
|
||||
return;
|
||||
_Base_iterator __next = std::next(__first);
|
||||
while (__next != __last)
|
||||
{
|
||||
if (__binary_pred(*__first, *__next))
|
||||
__next = _M_erase_after(__first);
|
||||
else
|
||||
__first = __next++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
merge(forward_list&& __list)
|
||||
{
|
||||
if (this != &__list)
|
||||
{
|
||||
__glibcxx_check_sorted(_Base::begin(), _Base::end());
|
||||
__glibcxx_check_sorted(__list._M_base().begin(),
|
||||
__list._M_base().end());
|
||||
this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
|
||||
{
|
||||
return __it != __list._M_base().cbefore_begin()
|
||||
&& __it != __list._M_base().cend();
|
||||
});
|
||||
_Base::merge(std::move(__list._M_base()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
merge(forward_list& __list)
|
||||
{ merge(std::move(__list)); }
|
||||
|
||||
template<typename _Comp>
|
||||
void
|
||||
merge(forward_list&& __list, _Comp __comp)
|
||||
{
|
||||
if (this != &__list)
|
||||
{
|
||||
__glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp);
|
||||
__glibcxx_check_sorted_pred(__list._M_base().begin(),
|
||||
__list._M_base().end(), __comp);
|
||||
this->_M_transfer_from_if(__list,
|
||||
[&__list](_Base_const_iterator __it)
|
||||
{
|
||||
return __it != __list._M_base().cbefore_begin()
|
||||
&& __it != __list._M_base().cend();
|
||||
});
|
||||
_Base::merge(std::move(__list._M_base()), __comp);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Comp>
|
||||
void
|
||||
merge(forward_list& __list, _Comp __comp)
|
||||
{ merge(std::move(__list), __comp); }
|
||||
|
||||
using _Base::sort;
|
||||
using _Base::reverse;
|
||||
|
||||
_Base&
|
||||
_M_base() noexcept { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const noexcept { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
this->_M_invalidate_if([this](_Base_const_iterator __it)
|
||||
{
|
||||
return __it != this->_M_base().cbefore_begin()
|
||||
&& __it != this->_M_base().cend();
|
||||
});
|
||||
}
|
||||
typedef __gnu_debug::_Safe_iterator_base _Safe_iterator_base;
|
||||
static void
|
||||
_M_swap_aux(forward_list& __lhs,
|
||||
_Safe_iterator_base*& __lhs_iterators,
|
||||
forward_list& __rhs,
|
||||
_Safe_iterator_base*& __rhs_iterators);
|
||||
void _M_swap(forward_list& __list);
|
||||
};
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
void
|
||||
forward_list<_Tp, _Alloc>::
|
||||
_M_swap_aux(forward_list<_Tp, _Alloc>& __lhs,
|
||||
__gnu_debug::_Safe_iterator_base*& __lhs_iterators,
|
||||
forward_list<_Tp, _Alloc>& __rhs,
|
||||
__gnu_debug::_Safe_iterator_base*& __rhs_iterators)
|
||||
{
|
||||
using __gnu_debug::_Safe_iterator_base;
|
||||
_Safe_iterator_base* __bbegin_its = 0;
|
||||
_Safe_iterator_base* __last_bbegin = 0;
|
||||
for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
|
||||
{
|
||||
// Even iterator are casted to const_iterator, not a problem.
|
||||
const_iterator* __victim = static_cast<const_iterator*>(__iter);
|
||||
__iter = __iter->_M_next;
|
||||
if (__victim->base() == __rhs._M_base().cbefore_begin())
|
||||
{
|
||||
__victim->_M_unlink();
|
||||
if (__lhs_iterators == __victim)
|
||||
__lhs_iterators = __victim->_M_next;
|
||||
if (__bbegin_its)
|
||||
{
|
||||
__victim->_M_next = __bbegin_its;
|
||||
__bbegin_its->_M_prior = __victim;
|
||||
}
|
||||
else
|
||||
__last_bbegin = __victim;
|
||||
__bbegin_its = __victim;
|
||||
}
|
||||
else
|
||||
__victim->_M_sequence = &__lhs;
|
||||
}
|
||||
|
||||
if (__bbegin_its)
|
||||
{
|
||||
if (__rhs_iterators)
|
||||
{
|
||||
__rhs_iterators->_M_prior = __last_bbegin;
|
||||
__last_bbegin->_M_next = __rhs_iterators;
|
||||
}
|
||||
__rhs_iterators = __bbegin_its;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special forward_list _M_swap version that do not swap the
|
||||
* before-begin ownership.*/
|
||||
template<typename _Tp, typename _Alloc>
|
||||
void
|
||||
forward_list<_Tp, _Alloc>::
|
||||
_M_swap(forward_list<_Tp, _Alloc>& __list)
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
|
||||
std::swap(this->_M_iterators, __list._M_iterators);
|
||||
std::swap(this->_M_const_iterators, __list._M_const_iterators);
|
||||
// Useless, always 1 on forward_list
|
||||
//std::swap(this->_M_version, __list._M_version);
|
||||
_Safe_iterator_base* __this_its = this->_M_iterators;
|
||||
_M_swap_aux(__list, __list._M_iterators, *this, this->_M_iterators);
|
||||
_Safe_iterator_base* __this_const_its = this->_M_const_iterators;
|
||||
_M_swap_aux(__list, __list._M_const_iterators, *this,
|
||||
this->_M_const_iterators);
|
||||
_M_swap_aux(*this, __this_its, __list, __list._M_iterators);
|
||||
_M_swap_aux(*this, __this_const_its, __list, __list._M_const_iterators);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
bool
|
||||
operator==(const forward_list<_Tp, _Alloc>& __lx,
|
||||
const forward_list<_Tp, _Alloc>& __ly)
|
||||
{ return __lx._M_base() == __ly._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<(const forward_list<_Tp, _Alloc>& __lx,
|
||||
const forward_list<_Tp, _Alloc>& __ly)
|
||||
{ return __lx._M_base() < __ly._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const forward_list<_Tp, _Alloc>& __lx,
|
||||
const forward_list<_Tp, _Alloc>& __ly)
|
||||
{ return !(__lx == __ly); }
|
||||
|
||||
/// Based on operator<
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>(const forward_list<_Tp, _Alloc>& __lx,
|
||||
const forward_list<_Tp, _Alloc>& __ly)
|
||||
{ return (__ly < __lx); }
|
||||
|
||||
/// Based on operator<
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>=(const forward_list<_Tp, _Alloc>& __lx,
|
||||
const forward_list<_Tp, _Alloc>& __ly)
|
||||
{ return !(__lx < __ly); }
|
||||
|
||||
/// Based on operator<
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<=(const forward_list<_Tp, _Alloc>& __lx,
|
||||
const forward_list<_Tp, _Alloc>& __ly)
|
||||
{ return !(__ly < __lx); }
|
||||
|
||||
/// See std::forward_list::swap().
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline void
|
||||
swap(forward_list<_Tp, _Alloc>& __lx,
|
||||
forward_list<_Tp, _Alloc>& __ly)
|
||||
{ __lx.swap(__ly); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<class _Tp, class _Alloc>
|
||||
struct _BeforeBeginHelper<std::__debug::forward_list<_Tp, _Alloc> >
|
||||
{
|
||||
typedef std::__debug::forward_list<_Tp, _Alloc> _Sequence;
|
||||
typedef typename _Sequence::const_iterator _It;
|
||||
typedef typename _It::iterator_type _BaseIt;
|
||||
|
||||
static bool
|
||||
_S_Is(_BaseIt __it, const _Sequence* __seq)
|
||||
{ return __it == __seq->_M_base().cbefore_begin(); }
|
||||
|
||||
static bool
|
||||
_S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq)
|
||||
{ return _S_Is(__it, __seq); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
550
contrib/sdk/sources/libstdc++-v3/include/debug/functions.h
Normal file
550
contrib/sdk/sources/libstdc++-v3/include/debug/functions.h
Normal file
@@ -0,0 +1,550 @@
|
||||
// Debugging support implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/functions.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
|
||||
#define _GLIBCXX_DEBUG_FUNCTIONS_H 1
|
||||
|
||||
#include <bits/c++config.h>
|
||||
#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and
|
||||
// _Iter_base
|
||||
#include <bits/cpp_type_traits.h> // for __is_integer
|
||||
#include <debug/formatter.h>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
class _Safe_iterator;
|
||||
|
||||
// An arbitrary iterator pointer is not singular.
|
||||
inline bool
|
||||
__check_singular_aux(const void*) { return false; }
|
||||
|
||||
// We may have an iterator that derives from _Safe_iterator_base but isn't
|
||||
// a _Safe_iterator.
|
||||
template<typename _Iterator>
|
||||
inline bool
|
||||
__check_singular(_Iterator& __x)
|
||||
{ return __check_singular_aux(&__x); }
|
||||
|
||||
/** Non-NULL pointers are nonsingular. */
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
__check_singular(const _Tp* __ptr)
|
||||
{ return __ptr == 0; }
|
||||
|
||||
/** Safe iterators know if they are singular. */
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
__check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x)
|
||||
{ return __x._M_singular(); }
|
||||
|
||||
/** Assume that some arbitrary iterator is dereferenceable, because we
|
||||
can't prove that it isn't. */
|
||||
template<typename _Iterator>
|
||||
inline bool
|
||||
__check_dereferenceable(_Iterator&)
|
||||
{ return true; }
|
||||
|
||||
/** Non-NULL pointers are dereferenceable. */
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
__check_dereferenceable(const _Tp* __ptr)
|
||||
{ return __ptr; }
|
||||
|
||||
/** Safe iterators know if they are singular. */
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
__check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
|
||||
{ return __x._M_dereferenceable(); }
|
||||
|
||||
/** If the distance between two random access iterators is
|
||||
* nonnegative, assume the range is valid.
|
||||
*/
|
||||
template<typename _RandomAccessIterator>
|
||||
inline bool
|
||||
__valid_range_aux2(const _RandomAccessIterator& __first,
|
||||
const _RandomAccessIterator& __last,
|
||||
std::random_access_iterator_tag)
|
||||
{ return __last - __first >= 0; }
|
||||
|
||||
/** Can't test for a valid range with input iterators, because
|
||||
* iteration may be destructive. So we just assume that the range
|
||||
* is valid.
|
||||
*/
|
||||
template<typename _InputIterator>
|
||||
inline bool
|
||||
__valid_range_aux2(const _InputIterator&, const _InputIterator&,
|
||||
std::input_iterator_tag)
|
||||
{ return true; }
|
||||
|
||||
/** We say that integral types for a valid range, and defer to other
|
||||
* routines to realize what to do with integral types instead of
|
||||
* iterators.
|
||||
*/
|
||||
template<typename _Integral>
|
||||
inline bool
|
||||
__valid_range_aux(const _Integral&, const _Integral&, std::__true_type)
|
||||
{ return true; }
|
||||
|
||||
/** We have iterators, so figure out what kind of iterators that are
|
||||
* to see if we can check the range ahead of time.
|
||||
*/
|
||||
template<typename _InputIterator>
|
||||
inline bool
|
||||
__valid_range_aux(const _InputIterator& __first,
|
||||
const _InputIterator& __last, std::__false_type)
|
||||
{ return __valid_range_aux2(__first, __last,
|
||||
std::__iterator_category(__first)); }
|
||||
|
||||
/** Don't know what these iterators are, or if they are even
|
||||
* iterators (we may get an integral type for InputIterator), so
|
||||
* see if they are integral and pass them on to the next phase
|
||||
* otherwise.
|
||||
*/
|
||||
template<typename _InputIterator>
|
||||
inline bool
|
||||
__valid_range(const _InputIterator& __first, const _InputIterator& __last)
|
||||
{
|
||||
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
|
||||
return __valid_range_aux(__first, __last, _Integral());
|
||||
}
|
||||
|
||||
/** Safe iterators know how to check if they form a valid range. */
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
__valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __last)
|
||||
{ return __first._M_valid_range(__last); }
|
||||
|
||||
/** Safe local iterators know how to check if they form a valid range. */
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
__valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_local_iterator<_Iterator, _Sequence>& __last)
|
||||
{ return __first._M_valid_range(__last); }
|
||||
|
||||
/* Checks that [first, last) is a valid range, and then returns
|
||||
* __first. This routine is useful when we can't use a separate
|
||||
* assertion statement because, e.g., we are in a constructor.
|
||||
*/
|
||||
template<typename _InputIterator>
|
||||
inline _InputIterator
|
||||
__check_valid_range(const _InputIterator& __first,
|
||||
const _InputIterator& __last
|
||||
__attribute__((__unused__)))
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
return __first;
|
||||
}
|
||||
|
||||
/** Checks that __s is non-NULL or __n == 0, and then returns __s. */
|
||||
template<typename _CharT, typename _Integer>
|
||||
inline const _CharT*
|
||||
__check_string(const _CharT* __s,
|
||||
const _Integer& __n __attribute__((__unused__)))
|
||||
{
|
||||
#ifdef _GLIBCXX_DEBUG_PEDANTIC
|
||||
__glibcxx_assert(__s != 0 || __n == 0);
|
||||
#endif
|
||||
return __s;
|
||||
}
|
||||
|
||||
/** Checks that __s is non-NULL and then returns __s. */
|
||||
template<typename _CharT>
|
||||
inline const _CharT*
|
||||
__check_string(const _CharT* __s)
|
||||
{
|
||||
#ifdef _GLIBCXX_DEBUG_PEDANTIC
|
||||
__glibcxx_assert(__s != 0);
|
||||
#endif
|
||||
return __s;
|
||||
}
|
||||
|
||||
// Can't check if an input iterator sequence is sorted, because we
|
||||
// can't step through the sequence.
|
||||
template<typename _InputIterator>
|
||||
inline bool
|
||||
__check_sorted_aux(const _InputIterator&, const _InputIterator&,
|
||||
std::input_iterator_tag)
|
||||
{ return true; }
|
||||
|
||||
// Can verify if a forward iterator sequence is in fact sorted using
|
||||
// std::__is_sorted
|
||||
template<typename _ForwardIterator>
|
||||
inline bool
|
||||
__check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
if (__first == __last)
|
||||
return true;
|
||||
|
||||
_ForwardIterator __next = __first;
|
||||
for (++__next; __next != __last; __first = __next, ++__next)
|
||||
if (*__next < *__first)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// For performance reason, as the iterator range has been validated, check on
|
||||
// random access safe iterators is done using the base iterator.
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
__check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __last,
|
||||
std::random_access_iterator_tag __tag)
|
||||
{ return __check_sorted_aux(__first.base(), __last.base(), __tag); }
|
||||
|
||||
// Can't check if an input iterator sequence is sorted, because we can't step
|
||||
// through the sequence.
|
||||
template<typename _InputIterator, typename _Predicate>
|
||||
inline bool
|
||||
__check_sorted_aux(const _InputIterator&, const _InputIterator&,
|
||||
_Predicate, std::input_iterator_tag)
|
||||
{ return true; }
|
||||
|
||||
// Can verify if a forward iterator sequence is in fact sorted using
|
||||
// std::__is_sorted
|
||||
template<typename _ForwardIterator, typename _Predicate>
|
||||
inline bool
|
||||
__check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
|
||||
_Predicate __pred, std::forward_iterator_tag)
|
||||
{
|
||||
if (__first == __last)
|
||||
return true;
|
||||
|
||||
_ForwardIterator __next = __first;
|
||||
for (++__next; __next != __last; __first = __next, ++__next)
|
||||
if (__pred(*__next, *__first))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// For performance reason, as the iterator range has been validated, check on
|
||||
// random access safe iterators is done using the base iterator.
|
||||
template<typename _Iterator, typename _Sequence,
|
||||
typename _Predicate>
|
||||
inline bool
|
||||
__check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __last,
|
||||
_Predicate __pred,
|
||||
std::random_access_iterator_tag __tag)
|
||||
{ return __check_sorted_aux(__first.base(), __last.base(), __pred, __tag); }
|
||||
|
||||
// Determine if a sequence is sorted.
|
||||
template<typename _InputIterator>
|
||||
inline bool
|
||||
__check_sorted(const _InputIterator& __first, const _InputIterator& __last)
|
||||
{
|
||||
// Verify that the < operator for elements in the sequence is a
|
||||
// StrictWeakOrdering by checking that it is irreflexive.
|
||||
__glibcxx_assert(__first == __last || !(*__first < *__first));
|
||||
|
||||
return __check_sorted_aux(__first, __last,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
|
||||
template<typename _InputIterator, typename _Predicate>
|
||||
inline bool
|
||||
__check_sorted(const _InputIterator& __first, const _InputIterator& __last,
|
||||
_Predicate __pred)
|
||||
{
|
||||
// Verify that the predicate is StrictWeakOrdering by checking that it
|
||||
// is irreflexive.
|
||||
__glibcxx_assert(__first == __last || !__pred(*__first, *__first));
|
||||
|
||||
return __check_sorted_aux(__first, __last, __pred,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
|
||||
template<typename _InputIterator>
|
||||
inline bool
|
||||
__check_sorted_set_aux(const _InputIterator& __first,
|
||||
const _InputIterator& __last,
|
||||
std::__true_type)
|
||||
{ return __check_sorted(__first, __last); }
|
||||
|
||||
template<typename _InputIterator>
|
||||
inline bool
|
||||
__check_sorted_set_aux(const _InputIterator&,
|
||||
const _InputIterator&,
|
||||
std::__false_type)
|
||||
{ return true; }
|
||||
|
||||
template<typename _InputIterator, typename _Predicate>
|
||||
inline bool
|
||||
__check_sorted_set_aux(const _InputIterator& __first,
|
||||
const _InputIterator& __last,
|
||||
_Predicate __pred, std::__true_type)
|
||||
{ return __check_sorted(__first, __last, __pred); }
|
||||
|
||||
template<typename _InputIterator, typename _Predicate>
|
||||
inline bool
|
||||
__check_sorted_set_aux(const _InputIterator&,
|
||||
const _InputIterator&, _Predicate,
|
||||
std::__false_type)
|
||||
{ return true; }
|
||||
|
||||
// ... special variant used in std::merge, std::includes, std::set_*.
|
||||
template<typename _InputIterator1, typename _InputIterator2>
|
||||
inline bool
|
||||
__check_sorted_set(const _InputIterator1& __first,
|
||||
const _InputIterator1& __last,
|
||||
const _InputIterator2&)
|
||||
{
|
||||
typedef typename std::iterator_traits<_InputIterator1>::value_type
|
||||
_ValueType1;
|
||||
typedef typename std::iterator_traits<_InputIterator2>::value_type
|
||||
_ValueType2;
|
||||
|
||||
typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
|
||||
_SameType;
|
||||
return __check_sorted_set_aux(__first, __last, _SameType());
|
||||
}
|
||||
|
||||
template<typename _InputIterator1, typename _InputIterator2,
|
||||
typename _Predicate>
|
||||
inline bool
|
||||
__check_sorted_set(const _InputIterator1& __first,
|
||||
const _InputIterator1& __last,
|
||||
const _InputIterator2&, _Predicate __pred)
|
||||
{
|
||||
typedef typename std::iterator_traits<_InputIterator1>::value_type
|
||||
_ValueType1;
|
||||
typedef typename std::iterator_traits<_InputIterator2>::value_type
|
||||
_ValueType2;
|
||||
|
||||
typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
|
||||
_SameType;
|
||||
return __check_sorted_set_aux(__first, __last, __pred, _SameType());
|
||||
}
|
||||
|
||||
template<typename _ForwardIterator, typename _Tp>
|
||||
inline bool
|
||||
__check_partitioned_lower_aux(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
while (__first != __last && *__first < __value)
|
||||
++__first;
|
||||
if (__first != __last)
|
||||
{
|
||||
++__first;
|
||||
while (__first != __last && !(*__first < __value))
|
||||
++__first;
|
||||
}
|
||||
return __first == __last;
|
||||
}
|
||||
|
||||
// For performance reason, as the iterator range has been validated, check on
|
||||
// random access safe iterators is done using the base iterator.
|
||||
template<typename _Iterator, typename _Sequence, typename _Tp>
|
||||
inline bool
|
||||
__check_partitioned_lower_aux(
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __last,
|
||||
const _Tp& __value,
|
||||
std::random_access_iterator_tag __tag)
|
||||
{
|
||||
return __check_partitioned_lower_aux(__first.base(), __last.base(),
|
||||
__value, __tag);
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 270. Binary search requirements overly strict
|
||||
// Determine if a sequence is partitioned w.r.t. this element.
|
||||
template<typename _ForwardIterator, typename _Tp>
|
||||
inline bool
|
||||
__check_partitioned_lower(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value)
|
||||
{
|
||||
return __check_partitioned_lower_aux(__first, __last, __value,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
|
||||
template<typename _ForwardIterator, typename _Tp>
|
||||
inline bool
|
||||
__check_partitioned_upper_aux(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
while (__first != __last && !(__value < *__first))
|
||||
++__first;
|
||||
if (__first != __last)
|
||||
{
|
||||
++__first;
|
||||
while (__first != __last && __value < *__first)
|
||||
++__first;
|
||||
}
|
||||
return __first == __last;
|
||||
}
|
||||
|
||||
// For performance reason, as the iterator range has been validated, check on
|
||||
// random access safe iterators is done using the base iterator.
|
||||
template<typename _Iterator, typename _Sequence, typename _Tp>
|
||||
inline bool
|
||||
__check_partitioned_upper_aux(
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __last,
|
||||
const _Tp& __value,
|
||||
std::random_access_iterator_tag __tag)
|
||||
{
|
||||
return __check_partitioned_upper_aux(__first.base(), __last.base(),
|
||||
__value, __tag);
|
||||
}
|
||||
|
||||
template<typename _ForwardIterator, typename _Tp>
|
||||
inline bool
|
||||
__check_partitioned_upper(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value)
|
||||
{
|
||||
return __check_partitioned_upper_aux(__first, __last, __value,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
|
||||
template<typename _ForwardIterator, typename _Tp, typename _Pred>
|
||||
inline bool
|
||||
__check_partitioned_lower_aux(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value,
|
||||
_Pred __pred,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
while (__first != __last && bool(__pred(*__first, __value)))
|
||||
++__first;
|
||||
if (__first != __last)
|
||||
{
|
||||
++__first;
|
||||
while (__first != __last && !bool(__pred(*__first, __value)))
|
||||
++__first;
|
||||
}
|
||||
return __first == __last;
|
||||
}
|
||||
|
||||
// For performance reason, as the iterator range has been validated, check on
|
||||
// random access safe iterators is done using the base iterator.
|
||||
template<typename _Iterator, typename _Sequence,
|
||||
typename _Tp, typename _Pred>
|
||||
inline bool
|
||||
__check_partitioned_lower_aux(
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __last,
|
||||
const _Tp& __value, _Pred __pred,
|
||||
std::random_access_iterator_tag __tag)
|
||||
{
|
||||
return __check_partitioned_lower_aux(__first.base(), __last.base(),
|
||||
__value, __pred, __tag);
|
||||
}
|
||||
|
||||
// Determine if a sequence is partitioned w.r.t. this element.
|
||||
template<typename _ForwardIterator, typename _Tp, typename _Pred>
|
||||
inline bool
|
||||
__check_partitioned_lower(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value,
|
||||
_Pred __pred)
|
||||
{
|
||||
return __check_partitioned_lower_aux(__first, __last, __value, __pred,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
|
||||
template<typename _ForwardIterator, typename _Tp, typename _Pred>
|
||||
inline bool
|
||||
__check_partitioned_upper_aux(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value,
|
||||
_Pred __pred,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
while (__first != __last && !bool(__pred(__value, *__first)))
|
||||
++__first;
|
||||
if (__first != __last)
|
||||
{
|
||||
++__first;
|
||||
while (__first != __last && bool(__pred(__value, *__first)))
|
||||
++__first;
|
||||
}
|
||||
return __first == __last;
|
||||
}
|
||||
|
||||
// For performance reason, as the iterator range has been validated, check on
|
||||
// random access safe iterators is done using the base iterator.
|
||||
template<typename _Iterator, typename _Sequence,
|
||||
typename _Tp, typename _Pred>
|
||||
inline bool
|
||||
__check_partitioned_upper_aux(
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __first,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __last,
|
||||
const _Tp& __value, _Pred __pred,
|
||||
std::random_access_iterator_tag __tag)
|
||||
{
|
||||
return __check_partitioned_upper_aux(__first.base(), __last.base(),
|
||||
__value, __pred, __tag);
|
||||
}
|
||||
|
||||
template<typename _ForwardIterator, typename _Tp, typename _Pred>
|
||||
inline bool
|
||||
__check_partitioned_upper(_ForwardIterator __first,
|
||||
_ForwardIterator __last, const _Tp& __value,
|
||||
_Pred __pred)
|
||||
{
|
||||
return __check_partitioned_upper_aux(__first, __last, __value, __pred,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
|
||||
// Helper struct to detect random access safe iterators.
|
||||
template<typename _Iterator>
|
||||
struct __is_safe_random_iterator
|
||||
{
|
||||
enum { __value = 0 };
|
||||
typedef std::__false_type __type;
|
||||
};
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
|
||||
: std::__are_same<std::random_access_iterator_tag,
|
||||
typename std::iterator_traits<_Iterator>::
|
||||
iterator_category>
|
||||
{ };
|
||||
|
||||
template<typename _Iterator>
|
||||
struct _Siter_base
|
||||
: std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value>
|
||||
{ };
|
||||
|
||||
/** Helper function to extract base iterator of random access safe iterator
|
||||
in order to reduce performance impact of debug mode. Limited to random
|
||||
access iterator because it is the only category for which it is possible
|
||||
to check for correct iterators order in the __valid_range function
|
||||
thanks to the < operator.
|
||||
*/
|
||||
template<typename _Iterator>
|
||||
inline typename _Siter_base<_Iterator>::iterator_type
|
||||
__base(_Iterator __it)
|
||||
{ return _Siter_base<_Iterator>::_S_base(__it); }
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
757
contrib/sdk/sources/libstdc++-v3/include/debug/list
Normal file
757
contrib/sdk/sources/libstdc++-v3/include/debug/list
Normal file
@@ -0,0 +1,757 @@
|
||||
// Debugging list implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/list
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_LIST
|
||||
#define _GLIBCXX_DEBUG_LIST 1
|
||||
|
||||
#include <list>
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::list with safety/checking/debug instrumentation.
|
||||
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
|
||||
class list
|
||||
: public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
|
||||
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
|
||||
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
|
||||
public:
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator, list>
|
||||
iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list>
|
||||
const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
|
||||
typedef _Tp value_type;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// 23.2.2.1 construct/copy/destroy:
|
||||
explicit
|
||||
list(const _Allocator& __a = _Allocator())
|
||||
: _Base(__a) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
explicit
|
||||
list(size_type __n)
|
||||
: _Base(__n) { }
|
||||
|
||||
list(size_type __n, const _Tp& __value,
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__n, __value, __a) { }
|
||||
#else
|
||||
explicit
|
||||
list(size_type __n, const _Tp& __value = _Tp(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__n, __value, __a) { }
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
list(_InputIterator __first, _InputIterator __last,
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __a)
|
||||
{ }
|
||||
|
||||
list(const list& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
list(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
list(list&& __x) noexcept
|
||||
: _Base(std::move(__x))
|
||||
{ this->_M_swap(__x); }
|
||||
|
||||
list(initializer_list<value_type> __l,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __a) { }
|
||||
#endif
|
||||
|
||||
~list() _GLIBCXX_NOEXCEPT { }
|
||||
|
||||
list&
|
||||
operator=(const list& __x)
|
||||
{
|
||||
static_cast<_Base&>(*this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
list&
|
||||
operator=(list&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
list&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
static_cast<_Base&>(*this) = __l;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
assign(initializer_list<value_type> __l)
|
||||
{
|
||||
_Base::assign(__l);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
void
|
||||
assign(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::assign(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
void
|
||||
assign(size_type __n, const _Tp& __t)
|
||||
{
|
||||
_Base::assign(__n, __t);
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
iterator
|
||||
begin() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
// 23.2.2.2 capacity:
|
||||
using _Base::empty;
|
||||
using _Base::size;
|
||||
using _Base::max_size;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
resize(size_type __sz)
|
||||
{
|
||||
this->_M_detach_singular();
|
||||
|
||||
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
|
||||
_Base_iterator __victim = _Base::begin();
|
||||
_Base_iterator __end = _Base::end();
|
||||
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
|
||||
++__victim;
|
||||
|
||||
for (; __victim != __end; ++__victim)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
_Base::resize(__sz);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
this->_M_revalidate_singular();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
resize(size_type __sz, const _Tp& __c)
|
||||
{
|
||||
this->_M_detach_singular();
|
||||
|
||||
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
|
||||
_Base_iterator __victim = _Base::begin();
|
||||
_Base_iterator __end = _Base::end();
|
||||
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
|
||||
++__victim;
|
||||
|
||||
for (; __victim != __end; ++__victim)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
_Base::resize(__sz, __c);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
this->_M_revalidate_singular();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void
|
||||
resize(size_type __sz, _Tp __c = _Tp())
|
||||
{
|
||||
this->_M_detach_singular();
|
||||
|
||||
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
|
||||
_Base_iterator __victim = _Base::begin();
|
||||
_Base_iterator __end = _Base::end();
|
||||
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
|
||||
++__victim;
|
||||
|
||||
for (; __victim != __end; ++__victim)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
_Base::resize(__sz, __c);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
this->_M_revalidate_singular();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// element access:
|
||||
reference
|
||||
front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
reference
|
||||
back()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::back();
|
||||
}
|
||||
|
||||
const_reference
|
||||
back() const
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::back();
|
||||
}
|
||||
|
||||
// 23.2.2.3 modifiers:
|
||||
using _Base::push_front;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
using _Base::emplace_front;
|
||||
#endif
|
||||
|
||||
void
|
||||
pop_front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
this->_M_invalidate_if(_Equal(_Base::begin()));
|
||||
_Base::pop_front();
|
||||
}
|
||||
|
||||
using _Base::push_back;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
using _Base::emplace_back;
|
||||
#endif
|
||||
|
||||
void
|
||||
pop_back()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
this->_M_invalidate_if(_Equal(--_Base::end()));
|
||||
_Base::pop_back();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace(iterator __position, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::emplace(__position.base(),
|
||||
std::forward<_Args>(__args)...), this);
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator
|
||||
insert(iterator __position, const _Tp& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(), __x), this);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
insert(iterator __position, _Tp&& __x)
|
||||
{ return emplace(__position, std::move(__x)); }
|
||||
|
||||
void
|
||||
insert(iterator __p, initializer_list<value_type> __l)
|
||||
{
|
||||
__glibcxx_check_insert(__p);
|
||||
_Base::insert(__p.base(), __l);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
insert(iterator __position, size_type __n, const _Tp& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
_Base::insert(__position.base(), __n, __x);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
void
|
||||
insert(iterator __position, _InputIterator __first,
|
||||
_InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_insert_range(__position, __first, __last);
|
||||
_Base::insert(__position.base(), __gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
}
|
||||
|
||||
private:
|
||||
_Base_iterator
|
||||
_M_erase(_Base_iterator __position)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__position));
|
||||
return _Base::erase(__position);
|
||||
}
|
||||
public:
|
||||
iterator
|
||||
erase(iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
return iterator(_M_erase(__position.base()), this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __position, iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__position, __last);
|
||||
for (_Base_iterator __victim = __position.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__position, "position")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
return iterator(_Base::erase(__position.base(), __last.base()), this);
|
||||
}
|
||||
|
||||
void
|
||||
swap(list& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
// 23.2.2.4 list operations:
|
||||
void
|
||||
#if __cplusplus >= 201103L
|
||||
splice(iterator __position, list&& __x)
|
||||
#else
|
||||
splice(iterator __position, list& __x)
|
||||
#endif
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(&__x != this,
|
||||
_M_message(__gnu_debug::__msg_self_splice)
|
||||
._M_sequence(*this, "this"));
|
||||
this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
|
||||
_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()));
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
splice(iterator __position, list& __x)
|
||||
{ splice(__position, std::move(__x)); }
|
||||
#endif
|
||||
|
||||
void
|
||||
#if __cplusplus >= 201103L
|
||||
splice(iterator __position, list&& __x, iterator __i)
|
||||
#else
|
||||
splice(iterator __position, list& __x, iterator __i)
|
||||
#endif
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
|
||||
// We used to perform the splice_alloc check: not anymore, redundant
|
||||
// after implementing the relevant bits of N1599.
|
||||
|
||||
_GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
|
||||
_M_message(__gnu_debug::__msg_splice_bad)
|
||||
._M_iterator(__i, "__i"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
|
||||
_M_message(__gnu_debug::__msg_splice_other)
|
||||
._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 250. splicing invalidates iterators
|
||||
this->_M_transfer_from_if(__x, _Equal(__i.base()));
|
||||
_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
|
||||
__i.base());
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
splice(iterator __position, list& __x, iterator __i)
|
||||
{ splice(__position, std::move(__x), __i); }
|
||||
#endif
|
||||
|
||||
void
|
||||
#if __cplusplus >= 201103L
|
||||
splice(iterator __position, list&& __x, iterator __first,
|
||||
iterator __last)
|
||||
#else
|
||||
splice(iterator __position, list& __x, iterator __first,
|
||||
iterator __last)
|
||||
#endif
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
|
||||
_M_message(__gnu_debug::__msg_splice_other)
|
||||
._M_sequence(__x, "x")
|
||||
._M_iterator(__first, "first"));
|
||||
|
||||
// We used to perform the splice_alloc check: not anymore, redundant
|
||||
// after implementing the relevant bits of N1599.
|
||||
|
||||
for (_Base_iterator __tmp = __first.base();
|
||||
__tmp != __last.base(); ++__tmp)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
_GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
|
||||
_M_message(__gnu_debug::__msg_splice_overlap)
|
||||
._M_iterator(__tmp, "position")
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 250. splicing invalidates iterators
|
||||
this->_M_transfer_from_if(__x, _Equal(__tmp));
|
||||
}
|
||||
|
||||
_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
|
||||
__first.base(), __last.base());
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
splice(iterator __position, list& __x, iterator __first, iterator __last)
|
||||
{ splice(__position, std::move(__x), __first, __last); }
|
||||
#endif
|
||||
|
||||
void
|
||||
remove(const _Tp& __value)
|
||||
{
|
||||
for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
|
||||
{
|
||||
if (*__x == __value)
|
||||
__x = _M_erase(__x);
|
||||
else
|
||||
++__x;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Predicate>
|
||||
void
|
||||
remove_if(_Predicate __pred)
|
||||
{
|
||||
for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
|
||||
{
|
||||
if (__pred(*__x))
|
||||
__x = _M_erase(__x);
|
||||
else
|
||||
++__x;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unique()
|
||||
{
|
||||
_Base_iterator __first = _Base::begin();
|
||||
_Base_iterator __last = _Base::end();
|
||||
if (__first == __last)
|
||||
return;
|
||||
_Base_iterator __next = __first; ++__next;
|
||||
while (__next != __last)
|
||||
{
|
||||
if (*__first == *__next)
|
||||
__next = _M_erase(__next);
|
||||
else
|
||||
__first = __next++;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _BinaryPredicate>
|
||||
void
|
||||
unique(_BinaryPredicate __binary_pred)
|
||||
{
|
||||
_Base_iterator __first = _Base::begin();
|
||||
_Base_iterator __last = _Base::end();
|
||||
if (__first == __last)
|
||||
return;
|
||||
_Base_iterator __next = __first; ++__next;
|
||||
while (__next != __last)
|
||||
{
|
||||
if (__binary_pred(*__first, *__next))
|
||||
__next = _M_erase(__next);
|
||||
else
|
||||
__first = __next++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if __cplusplus >= 201103L
|
||||
merge(list&& __x)
|
||||
#else
|
||||
merge(list& __x)
|
||||
#endif
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 300. list::merge() specification incomplete
|
||||
if (this != &__x)
|
||||
{
|
||||
__glibcxx_check_sorted(_Base::begin(), _Base::end());
|
||||
__glibcxx_check_sorted(__x.begin().base(), __x.end().base());
|
||||
this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
|
||||
_Base::merge(_GLIBCXX_MOVE(__x._M_base()));
|
||||
}
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
merge(list& __x)
|
||||
{ merge(std::move(__x)); }
|
||||
#endif
|
||||
|
||||
template<class _Compare>
|
||||
void
|
||||
#if __cplusplus >= 201103L
|
||||
merge(list&& __x, _Compare __comp)
|
||||
#else
|
||||
merge(list& __x, _Compare __comp)
|
||||
#endif
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 300. list::merge() specification incomplete
|
||||
if (this != &__x)
|
||||
{
|
||||
__glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
|
||||
__comp);
|
||||
__glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
|
||||
__comp);
|
||||
this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
|
||||
_Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
|
||||
}
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Compare>
|
||||
void
|
||||
merge(list& __x, _Compare __comp)
|
||||
{ merge(std::move(__x), __comp); }
|
||||
#endif
|
||||
|
||||
void
|
||||
sort() { _Base::sort(); }
|
||||
|
||||
template<typename _StrictWeakOrdering>
|
||||
void
|
||||
sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
|
||||
|
||||
using _Base::reverse;
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
this->_M_invalidate_if(_Not_equal(_Base::end()));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator==(const list<_Tp, _Alloc>& __lhs,
|
||||
const list<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() == __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const list<_Tp, _Alloc>& __lhs,
|
||||
const list<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() != __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<(const list<_Tp, _Alloc>& __lhs,
|
||||
const list<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() < __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<=(const list<_Tp, _Alloc>& __lhs,
|
||||
const list<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() <= __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>=(const list<_Tp, _Alloc>& __lhs,
|
||||
const list<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() >= __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>(const list<_Tp, _Alloc>& __lhs,
|
||||
const list<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() > __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline void
|
||||
swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
|
||||
{ __lhs.swap(__rhs); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif
|
349
contrib/sdk/sources/libstdc++-v3/include/debug/macros.h
Normal file
349
contrib/sdk/sources/libstdc++-v3/include/debug/macros.h
Normal file
@@ -0,0 +1,349 @@
|
||||
// Debugging support implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/macros.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_MACROS_H
|
||||
#define _GLIBCXX_DEBUG_MACROS_H 1
|
||||
|
||||
/**
|
||||
* Macros used by the implementation to verify certain
|
||||
* properties. These macros may only be used directly by the debug
|
||||
* wrappers. Note that these are macros (instead of the more obviously
|
||||
* @a correct choice of making them functions) because we need line and
|
||||
* file information at the call site, to minimize the distance between
|
||||
* the user error and where the error is reported.
|
||||
*
|
||||
*/
|
||||
#define _GLIBCXX_DEBUG_VERIFY_AT(_Condition,_ErrorMessage,_File,_Line) \
|
||||
do \
|
||||
{ \
|
||||
if (! (_Condition)) \
|
||||
__gnu_debug::_Error_formatter::_M_at(_File, _Line) \
|
||||
._ErrorMessage._M_error(); \
|
||||
} while (false)
|
||||
|
||||
#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \
|
||||
_GLIBCXX_DEBUG_VERIFY_AT(_Condition,_ErrorMessage,__FILE__,__LINE__)
|
||||
|
||||
// Verify that [_First, _Last) forms a valid iterator range.
|
||||
#define __glibcxx_check_valid_range(_First,_Last) \
|
||||
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__valid_range(_First, _Last), \
|
||||
_M_message(__gnu_debug::__msg_valid_range) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last))
|
||||
|
||||
// Verify that [_First, _Last) forms a non-empty iterator range.
|
||||
#define __glibcxx_check_non_empty_range(_First,_Last) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_First != _Last, \
|
||||
_M_message(__gnu_debug::__msg_non_empty_range) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last))
|
||||
|
||||
/** Verify that we can insert into *this with the iterator _Position.
|
||||
* Insertion into a container at a specific position requires that
|
||||
* the iterator be nonsingular, either dereferenceable or past-the-end,
|
||||
* and that it reference the sequence we are inserting into. Note that
|
||||
* this macro is only valid when the container is a_Safe_sequence and
|
||||
* the iterator is a _Safe_iterator.
|
||||
*/
|
||||
#define __glibcxx_check_insert(_Position) \
|
||||
_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \
|
||||
_M_message(__gnu_debug::__msg_insert_singular) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position)); \
|
||||
_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
|
||||
_M_message(__gnu_debug::__msg_insert_different) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position))
|
||||
|
||||
/** Verify that we can insert into *this after the iterator _Position.
|
||||
* Insertion into a container after a specific position requires that
|
||||
* the iterator be nonsingular, either dereferenceable or before-begin,
|
||||
* and that it reference the sequence we are inserting into. Note that
|
||||
* this macro is only valid when the container is a_Safe_sequence and
|
||||
* the iterator is a _Safe_iterator.
|
||||
*/
|
||||
#define __glibcxx_check_insert_after(_Position) \
|
||||
__glibcxx_check_insert(_Position); \
|
||||
_GLIBCXX_DEBUG_VERIFY(!_Position._M_is_end(), \
|
||||
_M_message(__gnu_debug::__msg_insert_after_end) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position))
|
||||
|
||||
/** Verify that we can insert the values in the iterator range
|
||||
* [_First, _Last) into *this with the iterator _Position. Insertion
|
||||
* into a container at a specific position requires that the iterator
|
||||
* be nonsingular (i.e., either dereferenceable or past-the-end),
|
||||
* that it reference the sequence we are inserting into, and that the
|
||||
* iterator range [_First, Last) is a valid (possibly empty)
|
||||
* range. Note that this macro is only valid when the container is a
|
||||
* _Safe_sequence and the iterator is a _Safe_iterator.
|
||||
*
|
||||
* @todo We would like to be able to check for noninterference of
|
||||
* _Position and the range [_First, _Last), but that can't (in
|
||||
* general) be done.
|
||||
*/
|
||||
#define __glibcxx_check_insert_range(_Position,_First,_Last) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
__glibcxx_check_insert(_Position)
|
||||
|
||||
/** Verify that we can insert the values in the iterator range
|
||||
* [_First, _Last) into *this after the iterator _Position. Insertion
|
||||
* into a container after a specific position requires that the iterator
|
||||
* be nonsingular (i.e., either dereferenceable or past-the-end),
|
||||
* that it reference the sequence we are inserting into, and that the
|
||||
* iterator range [_First, Last) is a valid (possibly empty)
|
||||
* range. Note that this macro is only valid when the container is a
|
||||
* _Safe_sequence and the iterator is a _Safe_iterator.
|
||||
*
|
||||
* @todo We would like to be able to check for noninterference of
|
||||
* _Position and the range [_First, _Last), but that can't (in
|
||||
* general) be done.
|
||||
*/
|
||||
#define __glibcxx_check_insert_range_after(_Position,_First,_Last) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
__glibcxx_check_insert_after(_Position)
|
||||
|
||||
/** Verify that we can erase the element referenced by the iterator
|
||||
* _Position. We can erase the element if the _Position iterator is
|
||||
* dereferenceable and references this sequence.
|
||||
*/
|
||||
#define __glibcxx_check_erase(_Position) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \
|
||||
_M_message(__gnu_debug::__msg_erase_bad) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position)); \
|
||||
_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
|
||||
_M_message(__gnu_debug::__msg_erase_different) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position))
|
||||
|
||||
/** Verify that we can erase the element after the iterator
|
||||
* _Position. We can erase the element if the _Position iterator is
|
||||
* before a dereferenceable one and references this sequence.
|
||||
*/
|
||||
#define __glibcxx_check_erase_after(_Position) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_Position._M_before_dereferenceable(), \
|
||||
_M_message(__gnu_debug::__msg_erase_after_bad) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position)); \
|
||||
_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
|
||||
_M_message(__gnu_debug::__msg_erase_different) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position))
|
||||
|
||||
/** Verify that we can erase the elements in the iterator range
|
||||
* [_First, _Last). We can erase the elements if [_First, _Last) is a
|
||||
* valid iterator range within this sequence.
|
||||
*/
|
||||
#define __glibcxx_check_erase_range(_First,_Last) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \
|
||||
_M_message(__gnu_debug::__msg_erase_different) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last))
|
||||
|
||||
/** Verify that we can erase the elements in the iterator range
|
||||
* (_First, _Last). We can erase the elements if (_First, _Last) is a
|
||||
* valid iterator range within this sequence.
|
||||
*/
|
||||
#define __glibcxx_check_erase_range_after(_First,_Last) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_First._M_can_compare(_Last), \
|
||||
_M_message(__gnu_debug::__msg_erase_different) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last)); \
|
||||
_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \
|
||||
_M_message(__gnu_debug::__msg_erase_different) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_First, #_First)); \
|
||||
_GLIBCXX_DEBUG_VERIFY(_First != _Last, \
|
||||
_M_message(__gnu_debug::__msg_valid_range2) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last)); \
|
||||
_GLIBCXX_DEBUG_VERIFY(_First._M_incrementable(), \
|
||||
_M_message(__gnu_debug::__msg_valid_range2) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last)); \
|
||||
_GLIBCXX_DEBUG_VERIFY(!_Last._M_is_before_begin(), \
|
||||
_M_message(__gnu_debug::__msg_valid_range2) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last)) \
|
||||
|
||||
// Verify that the subscript _N is less than the container's size.
|
||||
#define __glibcxx_check_subscript(_N) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \
|
||||
_M_message(__gnu_debug::__msg_subscript_oob) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_integer(_N, #_N) \
|
||||
._M_integer(this->size(), "size"))
|
||||
|
||||
// Verify that the bucket _N is less than the container's buckets count.
|
||||
#define __glibcxx_check_bucket_index(_N) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_N < this->bucket_count(), \
|
||||
_M_message(__gnu_debug::__msg_bucket_index_oob) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_integer(_N, #_N) \
|
||||
._M_integer(this->bucket_count(), "size"))
|
||||
|
||||
// Verify that the container is nonempty
|
||||
#define __glibcxx_check_nonempty() \
|
||||
_GLIBCXX_DEBUG_VERIFY(! this->empty(), \
|
||||
_M_message(__gnu_debug::__msg_empty) \
|
||||
._M_sequence(*this, "this"))
|
||||
|
||||
// Verify that the iterator range [_First, _Last) is sorted
|
||||
#define __glibcxx_check_sorted(_First,_Last) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last), \
|
||||
_M_message(__gnu_debug::__msg_unsorted) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last))
|
||||
|
||||
/** Verify that the iterator range [_First, _Last) is sorted by the
|
||||
predicate _Pred. */
|
||||
#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last, _Pred), \
|
||||
_M_message(__gnu_debug::__msg_unsorted_pred) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last) \
|
||||
._M_string(#_Pred))
|
||||
|
||||
// Special variant for std::merge, std::includes, std::set_*
|
||||
#define __glibcxx_check_sorted_set(_First1,_Last1,_First2) \
|
||||
__glibcxx_check_valid_range(_First1,_Last1); \
|
||||
_GLIBCXX_DEBUG_VERIFY( \
|
||||
__gnu_debug::__check_sorted_set(_First1, _Last1, _First2), \
|
||||
_M_message(__gnu_debug::__msg_unsorted) \
|
||||
._M_iterator(_First1, #_First1) \
|
||||
._M_iterator(_Last1, #_Last1))
|
||||
|
||||
// Likewise with a _Pred.
|
||||
#define __glibcxx_check_sorted_set_pred(_First1,_Last1,_First2,_Pred) \
|
||||
__glibcxx_check_valid_range(_First1,_Last1); \
|
||||
_GLIBCXX_DEBUG_VERIFY( \
|
||||
__gnu_debug::__check_sorted_set(_First1, _Last1, _First2, _Pred), \
|
||||
_M_message(__gnu_debug::__msg_unsorted_pred) \
|
||||
._M_iterator(_First1, #_First1) \
|
||||
._M_iterator(_Last1, #_Last1) \
|
||||
._M_string(#_Pred))
|
||||
|
||||
/** Verify that the iterator range [_First, _Last) is partitioned
|
||||
w.r.t. the value _Value. */
|
||||
#define __glibcxx_check_partitioned_lower(_First,_Last,_Value) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
|
||||
_Value), \
|
||||
_M_message(__gnu_debug::__msg_unpartitioned) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last) \
|
||||
._M_string(#_Value))
|
||||
|
||||
#define __glibcxx_check_partitioned_upper(_First,_Last,_Value) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
|
||||
_Value), \
|
||||
_M_message(__gnu_debug::__msg_unpartitioned) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last) \
|
||||
._M_string(#_Value))
|
||||
|
||||
/** Verify that the iterator range [_First, _Last) is partitioned
|
||||
w.r.t. the value _Value and predicate _Pred. */
|
||||
#define __glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
|
||||
_Value, _Pred), \
|
||||
_M_message(__gnu_debug::__msg_unpartitioned_pred) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last) \
|
||||
._M_string(#_Pred) \
|
||||
._M_string(#_Value))
|
||||
|
||||
/** Verify that the iterator range [_First, _Last) is partitioned
|
||||
w.r.t. the value _Value and predicate _Pred. */
|
||||
#define __glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
|
||||
__glibcxx_check_valid_range(_First,_Last); \
|
||||
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
|
||||
_Value, _Pred), \
|
||||
_M_message(__gnu_debug::__msg_unpartitioned_pred) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last) \
|
||||
._M_string(#_Pred) \
|
||||
._M_string(#_Value))
|
||||
|
||||
// Verify that the iterator range [_First, _Last) is a heap
|
||||
#define __glibcxx_check_heap(_First,_Last) \
|
||||
_GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First), \
|
||||
__gnu_debug::__base(_Last)), \
|
||||
_M_message(__gnu_debug::__msg_not_heap) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last))
|
||||
|
||||
/** Verify that the iterator range [_First, _Last) is a heap
|
||||
w.r.t. the predicate _Pred. */
|
||||
#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \
|
||||
_GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First), \
|
||||
__gnu_debug::__base(_Last), \
|
||||
_Pred), \
|
||||
_M_message(__gnu_debug::__msg_not_heap_pred) \
|
||||
._M_iterator(_First, #_First) \
|
||||
._M_iterator(_Last, #_Last) \
|
||||
._M_string(#_Pred))
|
||||
|
||||
// Verify that the container is not self move assigned
|
||||
#define __glibcxx_check_self_move_assign(_Other) \
|
||||
_GLIBCXX_DEBUG_VERIFY(this != &_Other, \
|
||||
_M_message(__gnu_debug::__msg_self_move_assign) \
|
||||
._M_sequence(*this, "this"))
|
||||
|
||||
// Verify that load factor is position
|
||||
#define __glibcxx_check_max_load_factor(_F) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \
|
||||
_M_message(__gnu_debug::__msg_valid_load_factor) \
|
||||
._M_sequence(*this, "this"))
|
||||
|
||||
#define __glibcxx_check_equal_allocs(_Other) \
|
||||
_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \
|
||||
_M_message(__gnu_debug::__msg_equal_allocs) \
|
||||
._M_sequence(*this, "this"))
|
||||
|
||||
#ifdef _GLIBCXX_DEBUG_PEDANTIC
|
||||
# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
|
||||
# define __glibcxx_check_string_len(_String,_Len) \
|
||||
_GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
|
||||
#else
|
||||
# define __glibcxx_check_string(_String)
|
||||
# define __glibcxx_check_string_len(_String,_Len)
|
||||
#endif
|
||||
|
||||
#endif
|
36
contrib/sdk/sources/libstdc++-v3/include/debug/map
Normal file
36
contrib/sdk/sources/libstdc++-v3/include/debug/map
Normal file
@@ -0,0 +1,36 @@
|
||||
// Debugging map/multimap implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/map
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_MAP
|
||||
#define _GLIBCXX_DEBUG_MAP 1
|
||||
|
||||
#include <map>
|
||||
#include <debug/map.h>
|
||||
#include <debug/multimap.h>
|
||||
|
||||
#endif
|
491
contrib/sdk/sources/libstdc++-v3/include/debug/map.h
Normal file
491
contrib/sdk/sources/libstdc++-v3/include/debug/map.h
Normal file
@@ -0,0 +1,491 @@
|
||||
// Debugging map implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/map.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_MAP_H
|
||||
#define _GLIBCXX_DEBUG_MAP_H 1
|
||||
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
#include <utility>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::map with safety/checking/debug instrumentation.
|
||||
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
|
||||
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
|
||||
class map
|
||||
: public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> _Base;
|
||||
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
|
||||
public:
|
||||
// types:
|
||||
typedef _Key key_type;
|
||||
typedef _Tp mapped_type;
|
||||
typedef std::pair<const _Key, _Tp> value_type;
|
||||
typedef _Compare key_compare;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator, map>
|
||||
iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, map>
|
||||
const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// 23.3.1.1 construct/copy/destroy:
|
||||
explicit map(const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__comp, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
map(_InputIterator __first, _InputIterator __last,
|
||||
const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last),
|
||||
__comp, __a) { }
|
||||
|
||||
map(const map& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
map(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
map(map&& __x)
|
||||
noexcept(is_nothrow_copy_constructible<_Compare>::value)
|
||||
: _Base(std::move(__x))
|
||||
{ this->_M_swap(__x); }
|
||||
|
||||
map(initializer_list<value_type> __l,
|
||||
const _Compare& __c = _Compare(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __c, __a) { }
|
||||
#endif
|
||||
|
||||
~map() _GLIBCXX_NOEXCEPT { }
|
||||
|
||||
map&
|
||||
operator=(const map& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
map&
|
||||
operator=(map&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
map&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 133. map missing get_allocator()
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
iterator
|
||||
begin() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
// capacity:
|
||||
using _Base::empty;
|
||||
using _Base::size;
|
||||
using _Base::max_size;
|
||||
|
||||
// 23.3.1.2 element access:
|
||||
using _Base::operator[];
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 464. Suggestion for new member functions in standard containers.
|
||||
using _Base::at;
|
||||
|
||||
// modifiers:
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename... _Args>
|
||||
std::pair<iterator, bool>
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
auto __res = _Base::emplace(std::forward<_Args>(__args)...);
|
||||
return std::pair<iterator, bool>(iterator(__res.first, this),
|
||||
__res.second);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __pos, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__pos);
|
||||
return iterator(_Base::emplace_hint(__pos.base(),
|
||||
std::forward<_Args>(__args)...),
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool>
|
||||
insert(const value_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
|
||||
return std::pair<iterator, bool>(iterator(__res.first, this),
|
||||
__res.second);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
std::pair<iterator, bool>
|
||||
insert(_Pair&& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, bool> __res
|
||||
= _Base::insert(std::forward<_Pair>(__x));
|
||||
return std::pair<iterator, bool>(iterator(__res.first, this),
|
||||
__res.second);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
insert(std::initializer_list<value_type> __list)
|
||||
{ _Base::insert(__list); }
|
||||
#endif
|
||||
|
||||
iterator
|
||||
#if __cplusplus >= 201103L
|
||||
insert(const_iterator __position, const value_type& __x)
|
||||
#else
|
||||
insert(iterator __position, const value_type& __x)
|
||||
#endif
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(), __x), this);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
iterator
|
||||
insert(const_iterator __position, _Pair&& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(),
|
||||
std::forward<_Pair>(__x)), this);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return iterator(_Base::erase(__position.base()), this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __position)
|
||||
{ return erase(const_iterator(__position)); }
|
||||
#else
|
||||
void
|
||||
erase(iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
_Base::erase(__position.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
size_type
|
||||
erase(const key_type& __x)
|
||||
{
|
||||
_Base_iterator __victim = _Base::find(__x);
|
||||
if (__victim == _Base::end())
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
_Base::erase(__victim);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
return iterator(_Base::erase(__first.base(), __last.base()), this);
|
||||
}
|
||||
#else
|
||||
void
|
||||
erase(iterator __first, iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
_Base::erase(__first.base(), __last.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
swap(map& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
this->_M_invalidate_all();
|
||||
_Base::clear();
|
||||
}
|
||||
|
||||
// observers:
|
||||
using _Base::key_comp;
|
||||
using _Base::value_comp;
|
||||
|
||||
// 23.3.1.3 map operations:
|
||||
iterator
|
||||
find(const key_type& __x)
|
||||
{ return iterator(_Base::find(__x), this); }
|
||||
|
||||
const_iterator
|
||||
find(const key_type& __x) const
|
||||
{ return const_iterator(_Base::find(__x), this); }
|
||||
|
||||
using _Base::count;
|
||||
|
||||
iterator
|
||||
lower_bound(const key_type& __x)
|
||||
{ return iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
const_iterator
|
||||
lower_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
iterator
|
||||
upper_bound(const key_type& __x)
|
||||
{ return iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
const_iterator
|
||||
upper_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
std::pair<iterator,iterator>
|
||||
equal_range(const key_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
std::pair<const_iterator,const_iterator>
|
||||
equal_range(const key_type& __x) const
|
||||
{
|
||||
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
|
||||
this->_M_invalidate_if(_Not_equal(_M_base().end()));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() == __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() != __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() < __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() <= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() >= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() > __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline void
|
||||
swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
map<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ __lhs.swap(__rhs); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif
|
474
contrib/sdk/sources/libstdc++-v3/include/debug/multimap.h
Normal file
474
contrib/sdk/sources/libstdc++-v3/include/debug/multimap.h
Normal file
@@ -0,0 +1,474 @@
|
||||
// Debugging multimap implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/multimap.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_MULTIMAP_H
|
||||
#define _GLIBCXX_DEBUG_MULTIMAP_H 1
|
||||
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
#include <utility>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::multimap with safety/checking/debug instrumentation.
|
||||
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
|
||||
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
|
||||
class multimap
|
||||
: public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<multimap<_Key, _Tp,
|
||||
_Compare, _Allocator> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
|
||||
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
|
||||
public:
|
||||
// types:
|
||||
typedef _Key key_type;
|
||||
typedef _Tp mapped_type;
|
||||
typedef std::pair<const _Key, _Tp> value_type;
|
||||
typedef _Compare key_compare;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator, multimap>
|
||||
iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
|
||||
multimap> const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// 23.3.1.1 construct/copy/destroy:
|
||||
explicit multimap(const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__comp, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
multimap(_InputIterator __first, _InputIterator __last,
|
||||
const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last),
|
||||
__comp, __a) { }
|
||||
|
||||
multimap(const multimap& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
multimap(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
multimap(multimap&& __x)
|
||||
noexcept(is_nothrow_copy_constructible<_Compare>::value)
|
||||
: _Base(std::move(__x))
|
||||
{ this->_M_swap(__x); }
|
||||
|
||||
multimap(initializer_list<value_type> __l,
|
||||
const _Compare& __c = _Compare(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __c, __a) { }
|
||||
#endif
|
||||
|
||||
~multimap() _GLIBCXX_NOEXCEPT { }
|
||||
|
||||
multimap&
|
||||
operator=(const multimap& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
multimap&
|
||||
operator=(multimap&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
multimap&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
iterator
|
||||
begin() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
// capacity:
|
||||
using _Base::empty;
|
||||
using _Base::size;
|
||||
using _Base::max_size;
|
||||
|
||||
// modifiers:
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __pos, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__pos);
|
||||
return iterator(_Base::emplace_hint(__pos.base(),
|
||||
std::forward<_Args>(__args)...),
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator
|
||||
insert(const value_type& __x)
|
||||
{ return iterator(_Base::insert(__x), this); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
iterator
|
||||
insert(_Pair&& __x)
|
||||
{ return iterator(_Base::insert(std::forward<_Pair>(__x)), this); }
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
insert(std::initializer_list<value_type> __list)
|
||||
{ _Base::insert(__list); }
|
||||
#endif
|
||||
|
||||
iterator
|
||||
#if __cplusplus >= 201103L
|
||||
insert(const_iterator __position, const value_type& __x)
|
||||
#else
|
||||
insert(iterator __position, const value_type& __x)
|
||||
#endif
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(), __x), this);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
iterator
|
||||
insert(const_iterator __position, _Pair&& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(),
|
||||
std::forward<_Pair>(__x)), this);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return iterator(_Base::erase(__position.base()), this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __position)
|
||||
{ return erase(const_iterator(__position)); }
|
||||
#else
|
||||
void
|
||||
erase(iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
_Base::erase(__position.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
size_type
|
||||
erase(const key_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __victims =
|
||||
_Base::equal_range(__x);
|
||||
size_type __count = 0;
|
||||
_Base_iterator __victim = __victims.first;
|
||||
while (__victim != __victims.second)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
_Base::erase(__victim++);
|
||||
++__count;
|
||||
}
|
||||
return __count;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
return iterator(_Base::erase(__first.base(), __last.base()), this);
|
||||
}
|
||||
#else
|
||||
void
|
||||
erase(iterator __first, iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
_Base::erase(__first.base(), __last.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
swap(multimap& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
this->_M_invalidate_all();
|
||||
_Base::clear();
|
||||
}
|
||||
|
||||
// observers:
|
||||
using _Base::key_comp;
|
||||
using _Base::value_comp;
|
||||
|
||||
// 23.3.1.3 multimap operations:
|
||||
iterator
|
||||
find(const key_type& __x)
|
||||
{ return iterator(_Base::find(__x), this); }
|
||||
|
||||
const_iterator
|
||||
find(const key_type& __x) const
|
||||
{ return const_iterator(_Base::find(__x), this); }
|
||||
|
||||
using _Base::count;
|
||||
|
||||
iterator
|
||||
lower_bound(const key_type& __x)
|
||||
{ return iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
const_iterator
|
||||
lower_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
iterator
|
||||
upper_bound(const key_type& __x)
|
||||
{ return iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
const_iterator
|
||||
upper_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
std::pair<iterator,iterator>
|
||||
equal_range(const key_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
std::pair<const_iterator,const_iterator>
|
||||
equal_range(const key_type& __x) const
|
||||
{
|
||||
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
|
||||
this->_M_invalidate_if(_Not_equal(_Base::end()));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() == __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() != __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() < __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() <= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() >= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() > __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Compare, typename _Allocator>
|
||||
inline void
|
||||
swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
|
||||
multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
|
||||
{ __lhs.swap(__rhs); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif
|
460
contrib/sdk/sources/libstdc++-v3/include/debug/multiset.h
Normal file
460
contrib/sdk/sources/libstdc++-v3/include/debug/multiset.h
Normal file
@@ -0,0 +1,460 @@
|
||||
// Debugging multiset implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/multiset.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_MULTISET_H
|
||||
#define _GLIBCXX_DEBUG_MULTISET_H 1
|
||||
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
#include <utility>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::multiset with safety/checking/debug instrumentation.
|
||||
template<typename _Key, typename _Compare = std::less<_Key>,
|
||||
typename _Allocator = std::allocator<_Key> >
|
||||
class multiset
|
||||
: public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base;
|
||||
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
|
||||
public:
|
||||
// types:
|
||||
typedef _Key key_type;
|
||||
typedef _Key value_type;
|
||||
typedef _Compare key_compare;
|
||||
typedef _Compare value_compare;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator, multiset>
|
||||
iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
|
||||
multiset> const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// 23.3.3.1 construct/copy/destroy:
|
||||
explicit multiset(const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__comp, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
multiset(_InputIterator __first, _InputIterator __last,
|
||||
const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last),
|
||||
__comp, __a) { }
|
||||
|
||||
multiset(const multiset& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
multiset(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
multiset(multiset&& __x)
|
||||
noexcept(is_nothrow_copy_constructible<_Compare>::value)
|
||||
: _Base(std::move(__x))
|
||||
{ this->_M_swap(__x); }
|
||||
|
||||
multiset(initializer_list<value_type> __l,
|
||||
const _Compare& __comp = _Compare(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __comp, __a) { }
|
||||
#endif
|
||||
|
||||
~multiset() _GLIBCXX_NOEXCEPT { }
|
||||
|
||||
multiset&
|
||||
operator=(const multiset& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
multiset&
|
||||
operator=(multiset&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
multiset&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
iterator
|
||||
begin() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
// capacity:
|
||||
using _Base::empty;
|
||||
using _Base::size;
|
||||
using _Base::max_size;
|
||||
|
||||
// modifiers:
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __pos, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__pos);
|
||||
return iterator(_Base::emplace_hint(__pos.base(),
|
||||
std::forward<_Args>(__args)...),
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator
|
||||
insert(const value_type& __x)
|
||||
{ return iterator(_Base::insert(__x), this); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
insert(value_type&& __x)
|
||||
{ return iterator(_Base::insert(std::move(__x)), this); }
|
||||
#endif
|
||||
|
||||
iterator
|
||||
insert(const_iterator __position, const value_type& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(), __x), this);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
insert(const_iterator __position, value_type&& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(), std::move(__x)),
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
insert(initializer_list<value_type> __l)
|
||||
{ _Base::insert(__l); }
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return iterator(_Base::erase(__position.base()), this);
|
||||
}
|
||||
#else
|
||||
void
|
||||
erase(iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
_Base::erase(__position.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
size_type
|
||||
erase(const key_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __victims =
|
||||
_Base::equal_range(__x);
|
||||
size_type __count = 0;
|
||||
_Base_iterator __victim = __victims.first;
|
||||
while (__victim != __victims.second)
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
_Base::erase(__victim++);
|
||||
++__count;
|
||||
}
|
||||
return __count;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
return iterator(_Base::erase(__first.base(), __last.base()), this);
|
||||
}
|
||||
#else
|
||||
void
|
||||
erase(iterator __first, iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
_Base::erase(__first.base(), __last.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
swap(multiset& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
this->_M_invalidate_all();
|
||||
_Base::clear();
|
||||
}
|
||||
|
||||
// observers:
|
||||
using _Base::key_comp;
|
||||
using _Base::value_comp;
|
||||
|
||||
// multiset operations:
|
||||
iterator
|
||||
find(const key_type& __x)
|
||||
{ return iterator(_Base::find(__x), this); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
const_iterator
|
||||
find(const key_type& __x) const
|
||||
{ return const_iterator(_Base::find(__x), this); }
|
||||
|
||||
using _Base::count;
|
||||
|
||||
iterator
|
||||
lower_bound(const key_type& __x)
|
||||
{ return iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
const_iterator
|
||||
lower_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
iterator
|
||||
upper_bound(const key_type& __x)
|
||||
{ return iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
const_iterator
|
||||
upper_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
std::pair<iterator,iterator>
|
||||
equal_range(const key_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
std::pair<const_iterator,const_iterator>
|
||||
equal_range(const key_type& __x) const
|
||||
{
|
||||
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
|
||||
this->_M_invalidate_if(_Not_equal(_Base::end()));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator==(const multiset<_Key, _Compare, _Allocator>& __lhs,
|
||||
const multiset<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() == __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator!=(const multiset<_Key, _Compare, _Allocator>& __lhs,
|
||||
const multiset<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() != __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<(const multiset<_Key, _Compare, _Allocator>& __lhs,
|
||||
const multiset<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() < __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<=(const multiset<_Key, _Compare, _Allocator>& __lhs,
|
||||
const multiset<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() <= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>=(const multiset<_Key, _Compare, _Allocator>& __lhs,
|
||||
const multiset<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() >= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>(const multiset<_Key, _Compare, _Allocator>& __lhs,
|
||||
const multiset<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() > __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
void
|
||||
swap(multiset<_Key, _Compare, _Allocator>& __x,
|
||||
multiset<_Key, _Compare, _Allocator>& __y)
|
||||
{ return __x.swap(__y); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif
|
254
contrib/sdk/sources/libstdc++-v3/include/debug/safe_base.h
Normal file
254
contrib/sdk/sources/libstdc++-v3/include/debug/safe_base.h
Normal file
@@ -0,0 +1,254 @@
|
||||
// Safe sequence/iterator base implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_base.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_BASE_H
|
||||
#define _GLIBCXX_DEBUG_SAFE_BASE_H 1
|
||||
|
||||
#include <ext/concurrence.h>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
class _Safe_sequence_base;
|
||||
|
||||
/** \brief Basic functionality for a @a safe iterator.
|
||||
*
|
||||
* The %_Safe_iterator_base base class implements the functionality
|
||||
* of a safe iterator that is not specific to a particular iterator
|
||||
* type. It contains a pointer back to the sequence it references
|
||||
* along with iterator version information and pointers to form a
|
||||
* doubly-linked list of iterators referenced by the container.
|
||||
*
|
||||
* This class must not perform any operations that can throw an
|
||||
* exception, or the exception guarantees of derived iterators will
|
||||
* be broken.
|
||||
*/
|
||||
class _Safe_iterator_base
|
||||
{
|
||||
public:
|
||||
/** The sequence this iterator references; may be NULL to indicate
|
||||
a singular iterator. */
|
||||
_Safe_sequence_base* _M_sequence;
|
||||
|
||||
/** The version number of this iterator. The sentinel value 0 is
|
||||
* used to indicate an invalidated iterator (i.e., one that is
|
||||
* singular because of an operation on the container). This
|
||||
* version number must equal the version number in the sequence
|
||||
* referenced by _M_sequence for the iterator to be
|
||||
* non-singular.
|
||||
*/
|
||||
unsigned int _M_version;
|
||||
|
||||
/** Pointer to the previous iterator in the sequence's list of
|
||||
iterators. Only valid when _M_sequence != NULL. */
|
||||
_Safe_iterator_base* _M_prior;
|
||||
|
||||
/** Pointer to the next iterator in the sequence's list of
|
||||
iterators. Only valid when _M_sequence != NULL. */
|
||||
_Safe_iterator_base* _M_next;
|
||||
|
||||
protected:
|
||||
/** Initializes the iterator and makes it singular. */
|
||||
_Safe_iterator_base()
|
||||
: _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
|
||||
{ }
|
||||
|
||||
/** Initialize the iterator to reference the sequence pointed to
|
||||
* by @p __seq. @p __constant is true when we are initializing a
|
||||
* constant iterator, and false if it is a mutable iterator. Note
|
||||
* that @p __seq may be NULL, in which case the iterator will be
|
||||
* singular. Otherwise, the iterator will reference @p __seq and
|
||||
* be nonsingular.
|
||||
*/
|
||||
_Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant)
|
||||
: _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
|
||||
{ this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); }
|
||||
|
||||
/** Initializes the iterator to reference the same sequence that
|
||||
@p __x does. @p __constant is true if this is a constant
|
||||
iterator, and false if it is mutable. */
|
||||
_Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant)
|
||||
: _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
|
||||
{ this->_M_attach(__x._M_sequence, __constant); }
|
||||
|
||||
_Safe_iterator_base&
|
||||
operator=(const _Safe_iterator_base&);
|
||||
|
||||
explicit
|
||||
_Safe_iterator_base(const _Safe_iterator_base&);
|
||||
|
||||
~_Safe_iterator_base() { this->_M_detach(); }
|
||||
|
||||
/** For use in _Safe_iterator. */
|
||||
__gnu_cxx::__mutex& _M_get_mutex() throw ();
|
||||
|
||||
public:
|
||||
/** Attaches this iterator to the given sequence, detaching it
|
||||
* from whatever sequence it was attached to originally. If the
|
||||
* new sequence is the NULL pointer, the iterator is left
|
||||
* unattached.
|
||||
*/
|
||||
void _M_attach(_Safe_sequence_base* __seq, bool __constant);
|
||||
|
||||
/** Likewise, but not thread-safe. */
|
||||
void _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
|
||||
|
||||
/** Detach the iterator for whatever sequence it is attached to,
|
||||
* if any.
|
||||
*/
|
||||
void _M_detach();
|
||||
|
||||
/** Likewise, but not thread-safe. */
|
||||
void _M_detach_single() throw ();
|
||||
|
||||
/** Determines if we are attached to the given sequence. */
|
||||
bool _M_attached_to(const _Safe_sequence_base* __seq) const
|
||||
{ return _M_sequence == __seq; }
|
||||
|
||||
/** Is this iterator singular? */
|
||||
_GLIBCXX_PURE bool _M_singular() const throw ();
|
||||
|
||||
/** Can we compare this iterator to the given iterator @p __x?
|
||||
Returns true if both iterators are nonsingular and reference
|
||||
the same sequence. */
|
||||
_GLIBCXX_PURE bool _M_can_compare(const _Safe_iterator_base& __x) const throw ();
|
||||
|
||||
/** Invalidate the iterator, making it singular. */
|
||||
void
|
||||
_M_invalidate()
|
||||
{ _M_version = 0; }
|
||||
|
||||
/** Reset all member variables */
|
||||
void
|
||||
_M_reset() throw ();
|
||||
|
||||
/** Unlink itself */
|
||||
void
|
||||
_M_unlink() throw ()
|
||||
{
|
||||
if (_M_prior)
|
||||
_M_prior->_M_next = _M_next;
|
||||
if (_M_next)
|
||||
_M_next->_M_prior = _M_prior;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base class that supports tracking of iterators that
|
||||
* reference a sequence.
|
||||
*
|
||||
* The %_Safe_sequence_base class provides basic support for
|
||||
* tracking iterators into a sequence. Sequences that track
|
||||
* iterators must derived from %_Safe_sequence_base publicly, so
|
||||
* that safe iterators (which inherit _Safe_iterator_base) can
|
||||
* attach to them. This class contains two linked lists of
|
||||
* iterators, one for constant iterators and one for mutable
|
||||
* iterators, and a version number that allows very fast
|
||||
* invalidation of all iterators that reference the container.
|
||||
*
|
||||
* This class must ensure that no operation on it may throw an
|
||||
* exception, otherwise @a safe sequences may fail to provide the
|
||||
* exception-safety guarantees required by the C++ standard.
|
||||
*/
|
||||
class _Safe_sequence_base
|
||||
{
|
||||
public:
|
||||
/// The list of mutable iterators that reference this container
|
||||
_Safe_iterator_base* _M_iterators;
|
||||
|
||||
/// The list of constant iterators that reference this container
|
||||
_Safe_iterator_base* _M_const_iterators;
|
||||
|
||||
/// The container version number. This number may never be 0.
|
||||
mutable unsigned int _M_version;
|
||||
|
||||
protected:
|
||||
// Initialize with a version number of 1 and no iterators
|
||||
_Safe_sequence_base()
|
||||
: _M_iterators(0), _M_const_iterators(0), _M_version(1)
|
||||
{ }
|
||||
|
||||
/** Notify all iterators that reference this sequence that the
|
||||
sequence is being destroyed. */
|
||||
~_Safe_sequence_base()
|
||||
{ this->_M_detach_all(); }
|
||||
|
||||
/** Detach all iterators, leaving them singular. */
|
||||
void
|
||||
_M_detach_all();
|
||||
|
||||
/** Detach all singular iterators.
|
||||
* @post for all iterators i attached to this sequence,
|
||||
* i->_M_version == _M_version.
|
||||
*/
|
||||
void
|
||||
_M_detach_singular();
|
||||
|
||||
/** Revalidates all attached singular iterators. This method may
|
||||
* be used to validate iterators that were invalidated before
|
||||
* (but for some reason, such as an exception, need to become
|
||||
* valid again).
|
||||
*/
|
||||
void
|
||||
_M_revalidate_singular();
|
||||
|
||||
/** Swap this sequence with the given sequence. This operation
|
||||
* also swaps ownership of the iterators, so that when the
|
||||
* operation is complete all iterators that originally referenced
|
||||
* one container now reference the other container.
|
||||
*/
|
||||
void
|
||||
_M_swap(_Safe_sequence_base& __x);
|
||||
|
||||
/** For use in _Safe_sequence. */
|
||||
__gnu_cxx::__mutex& _M_get_mutex() throw ();
|
||||
|
||||
public:
|
||||
/** Invalidates all iterators. */
|
||||
void
|
||||
_M_invalidate_all() const
|
||||
{ if (++_M_version == 0) _M_version = 1; }
|
||||
|
||||
/** Attach an iterator to this sequence. */
|
||||
void
|
||||
_M_attach(_Safe_iterator_base* __it, bool __constant);
|
||||
|
||||
/** Likewise but not thread safe. */
|
||||
void
|
||||
_M_attach_single(_Safe_iterator_base* __it, bool __constant) throw ();
|
||||
|
||||
/** Detach an iterator from this sequence */
|
||||
void
|
||||
_M_detach(_Safe_iterator_base* __it);
|
||||
|
||||
/** Likewise but not thread safe. */
|
||||
void
|
||||
_M_detach_single(_Safe_iterator_base* __it) throw ();
|
||||
};
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
719
contrib/sdk/sources/libstdc++-v3/include/debug/safe_iterator.h
Normal file
719
contrib/sdk/sources/libstdc++-v3/include/debug/safe_iterator.h
Normal file
@@ -0,0 +1,719 @@
|
||||
// Safe iterator implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_iterator.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
|
||||
#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
|
||||
|
||||
#include <debug/debug.h>
|
||||
#include <debug/macros.h>
|
||||
#include <debug/functions.h>
|
||||
#include <debug/safe_base.h>
|
||||
#include <bits/stl_pair.h>
|
||||
#include <ext/type_traits.h>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
/** Helper struct to deal with sequence offering a before_begin
|
||||
* iterator.
|
||||
**/
|
||||
template <typename _Sequence>
|
||||
struct _BeforeBeginHelper
|
||||
{
|
||||
typedef typename _Sequence::const_iterator _It;
|
||||
typedef typename _It::iterator_type _BaseIt;
|
||||
|
||||
static bool
|
||||
_S_Is(_BaseIt, const _Sequence*)
|
||||
{ return false; }
|
||||
|
||||
static bool
|
||||
_S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq)
|
||||
{ return __it == __seq->_M_base().begin(); }
|
||||
};
|
||||
|
||||
/** Iterators that derive from _Safe_iterator_base but that aren't
|
||||
* _Safe_iterators can be determined singular or non-singular via
|
||||
* _Safe_iterator_base.
|
||||
*/
|
||||
inline bool
|
||||
__check_singular_aux(const _Safe_iterator_base* __x)
|
||||
{ return __x->_M_singular(); }
|
||||
|
||||
/** The precision to which we can calculate the distance between
|
||||
* two iterators.
|
||||
*/
|
||||
enum _Distance_precision
|
||||
{
|
||||
__dp_equality, //< Can compare iterator equality, only
|
||||
__dp_sign, //< Can determine equality and ordering
|
||||
__dp_exact //< Can determine distance precisely
|
||||
};
|
||||
|
||||
/** Determine the distance between two iterators with some known
|
||||
* precision.
|
||||
*/
|
||||
template<typename _Iterator1, typename _Iterator2>
|
||||
inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
|
||||
_Distance_precision>
|
||||
__get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
|
||||
std::random_access_iterator_tag)
|
||||
{ return std::make_pair(__rhs - __lhs, __dp_exact); }
|
||||
|
||||
template<typename _Iterator1, typename _Iterator2>
|
||||
inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
|
||||
_Distance_precision>
|
||||
__get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
|
||||
std::forward_iterator_tag)
|
||||
{ return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
|
||||
|
||||
template<typename _Iterator1, typename _Iterator2>
|
||||
inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
|
||||
_Distance_precision>
|
||||
__get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
|
||||
{
|
||||
typedef typename std::iterator_traits<_Iterator1>::iterator_category
|
||||
_Category;
|
||||
return __get_distance(__lhs, __rhs, _Category());
|
||||
}
|
||||
|
||||
/** \brief Safe iterator wrapper.
|
||||
*
|
||||
* The class template %_Safe_iterator is a wrapper around an
|
||||
* iterator that tracks the iterator's movement among sequences and
|
||||
* checks that operations performed on the "safe" iterator are
|
||||
* legal. In additional to the basic iterator operations (which are
|
||||
* validated, and then passed to the underlying iterator),
|
||||
* %_Safe_iterator has member functions for iterator invalidation,
|
||||
* attaching/detaching the iterator from sequences, and querying
|
||||
* the iterator's state.
|
||||
*/
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
class _Safe_iterator : public _Safe_iterator_base
|
||||
{
|
||||
typedef _Safe_iterator _Self;
|
||||
|
||||
/// The underlying iterator
|
||||
_Iterator _M_current;
|
||||
|
||||
/// Determine if this is a constant iterator.
|
||||
bool
|
||||
_M_constant() const
|
||||
{
|
||||
typedef typename _Sequence::const_iterator const_iterator;
|
||||
return std::__are_same<const_iterator, _Safe_iterator>::__value;
|
||||
}
|
||||
|
||||
typedef std::iterator_traits<_Iterator> _Traits;
|
||||
|
||||
public:
|
||||
typedef _Iterator iterator_type;
|
||||
typedef typename _Traits::iterator_category iterator_category;
|
||||
typedef typename _Traits::value_type value_type;
|
||||
typedef typename _Traits::difference_type difference_type;
|
||||
typedef typename _Traits::reference reference;
|
||||
typedef typename _Traits::pointer pointer;
|
||||
|
||||
/// @post the iterator is singular and unattached
|
||||
_Safe_iterator() : _M_current() { }
|
||||
|
||||
/**
|
||||
* @brief Safe iterator construction from an unsafe iterator and
|
||||
* its sequence.
|
||||
*
|
||||
* @pre @p seq is not NULL
|
||||
* @post this is not singular
|
||||
*/
|
||||
_Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
|
||||
: _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
|
||||
_M_message(__msg_init_singular)
|
||||
._M_iterator(*this, "this"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy construction.
|
||||
*/
|
||||
_Safe_iterator(const _Safe_iterator& __x)
|
||||
: _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x._M_current == _Iterator(),
|
||||
_M_message(__msg_init_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
/**
|
||||
* @brief Move construction.
|
||||
* @post __x is singular and unattached
|
||||
*/
|
||||
_Safe_iterator(_Safe_iterator&& __x) : _M_current()
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x._M_current == _Iterator(),
|
||||
_M_message(__msg_init_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
std::swap(_M_current, __x._M_current);
|
||||
this->_M_attach(__x._M_sequence);
|
||||
__x._M_detach();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Converting constructor from a mutable iterator to a
|
||||
* constant iterator.
|
||||
*/
|
||||
template<typename _MutableIterator>
|
||||
_Safe_iterator(
|
||||
const _Safe_iterator<_MutableIterator,
|
||||
typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
|
||||
typename _Sequence::iterator::iterator_type>::__value),
|
||||
_Sequence>::__type>& __x)
|
||||
: _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
_M_message(__msg_init_const_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment.
|
||||
*/
|
||||
_Safe_iterator&
|
||||
operator=(const _Safe_iterator& __x)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x._M_current == _Iterator(),
|
||||
_M_message(__msg_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
_M_current = __x._M_current;
|
||||
this->_M_attach(__x._M_sequence);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
/**
|
||||
* @brief Move assignment.
|
||||
* @post __x is singular and unattached
|
||||
*/
|
||||
_Safe_iterator&
|
||||
operator=(_Safe_iterator&& __x)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this != &__x,
|
||||
_M_message(__msg_self_move_assign)
|
||||
._M_iterator(*this, "this"));
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x._M_current == _Iterator(),
|
||||
_M_message(__msg_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
_M_current = __x._M_current;
|
||||
_M_attach(__x._M_sequence);
|
||||
__x._M_detach();
|
||||
__x._M_current = _Iterator();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Iterator dereference.
|
||||
* @pre iterator is dereferenceable
|
||||
*/
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
|
||||
_M_message(__msg_bad_deref)
|
||||
._M_iterator(*this, "this"));
|
||||
return *_M_current;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterator dereference.
|
||||
* @pre iterator is dereferenceable
|
||||
* @todo Make this correct w.r.t. iterators that return proxies
|
||||
* @todo Use addressof() instead of & operator
|
||||
*/
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
|
||||
_M_message(__msg_bad_deref)
|
||||
._M_iterator(*this, "this"));
|
||||
return &*_M_current;
|
||||
}
|
||||
|
||||
// ------ Input iterator requirements ------
|
||||
/**
|
||||
* @brief Iterator preincrement
|
||||
* @pre iterator is incrementable
|
||||
*/
|
||||
_Safe_iterator&
|
||||
operator++()
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
|
||||
_M_message(__msg_bad_inc)
|
||||
._M_iterator(*this, "this"));
|
||||
++_M_current;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterator postincrement
|
||||
* @pre iterator is incrementable
|
||||
*/
|
||||
_Safe_iterator
|
||||
operator++(int)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
|
||||
_M_message(__msg_bad_inc)
|
||||
._M_iterator(*this, "this"));
|
||||
_Safe_iterator __tmp(*this);
|
||||
++_M_current;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
// ------ Bidirectional iterator requirements ------
|
||||
/**
|
||||
* @brief Iterator predecrement
|
||||
* @pre iterator is decrementable
|
||||
*/
|
||||
_Safe_iterator&
|
||||
operator--()
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
|
||||
_M_message(__msg_bad_dec)
|
||||
._M_iterator(*this, "this"));
|
||||
--_M_current;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterator postdecrement
|
||||
* @pre iterator is decrementable
|
||||
*/
|
||||
_Safe_iterator
|
||||
operator--(int)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
|
||||
_M_message(__msg_bad_dec)
|
||||
._M_iterator(*this, "this"));
|
||||
_Safe_iterator __tmp(*this);
|
||||
--_M_current;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
// ------ Random access iterator requirements ------
|
||||
reference
|
||||
operator[](const difference_type& __n) const
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
|
||||
&& this->_M_can_advance(__n+1),
|
||||
_M_message(__msg_iter_subscript_oob)
|
||||
._M_iterator(*this)._M_integer(__n));
|
||||
|
||||
return _M_current[__n];
|
||||
}
|
||||
|
||||
_Safe_iterator&
|
||||
operator+=(const difference_type& __n)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
|
||||
_M_message(__msg_advance_oob)
|
||||
._M_iterator(*this)._M_integer(__n));
|
||||
_M_current += __n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_Safe_iterator
|
||||
operator+(const difference_type& __n) const
|
||||
{
|
||||
_Safe_iterator __tmp(*this);
|
||||
__tmp += __n;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_Safe_iterator&
|
||||
operator-=(const difference_type& __n)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
|
||||
_M_message(__msg_retreat_oob)
|
||||
._M_iterator(*this)._M_integer(__n));
|
||||
_M_current += -__n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_Safe_iterator
|
||||
operator-(const difference_type& __n) const
|
||||
{
|
||||
_Safe_iterator __tmp(*this);
|
||||
__tmp -= __n;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
// ------ Utilities ------
|
||||
/**
|
||||
* @brief Return the underlying iterator
|
||||
*/
|
||||
_Iterator
|
||||
base() const { return _M_current; }
|
||||
|
||||
/**
|
||||
* @brief Conversion to underlying non-debug iterator to allow
|
||||
* better interaction with non-debug containers.
|
||||
*/
|
||||
operator _Iterator() const { return _M_current; }
|
||||
|
||||
/** Attach iterator to the given sequence. */
|
||||
void
|
||||
_M_attach(_Safe_sequence_base* __seq)
|
||||
{
|
||||
_Safe_iterator_base::_M_attach(__seq, _M_constant());
|
||||
}
|
||||
|
||||
/** Likewise, but not thread-safe. */
|
||||
void
|
||||
_M_attach_single(_Safe_sequence_base* __seq)
|
||||
{
|
||||
_Safe_iterator_base::_M_attach_single(__seq, _M_constant());
|
||||
}
|
||||
|
||||
/// Is the iterator dereferenceable?
|
||||
bool
|
||||
_M_dereferenceable() const
|
||||
{ return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
|
||||
|
||||
/// Is the iterator before a dereferenceable one?
|
||||
bool
|
||||
_M_before_dereferenceable() const
|
||||
{
|
||||
if (this->_M_incrementable())
|
||||
{
|
||||
_Iterator __base = base();
|
||||
return ++__base != _M_get_sequence()->_M_base().end();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Is the iterator incrementable?
|
||||
bool
|
||||
_M_incrementable() const
|
||||
{ return !this->_M_singular() && !_M_is_end(); }
|
||||
|
||||
// Is the iterator decrementable?
|
||||
bool
|
||||
_M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
|
||||
|
||||
// Can we advance the iterator @p __n steps (@p __n may be negative)
|
||||
bool
|
||||
_M_can_advance(const difference_type& __n) const;
|
||||
|
||||
// Is the iterator range [*this, __rhs) valid?
|
||||
template<typename _Other>
|
||||
bool
|
||||
_M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
|
||||
|
||||
// The sequence this iterator references.
|
||||
const _Sequence*
|
||||
_M_get_sequence() const
|
||||
{ return static_cast<const _Sequence*>(_M_sequence); }
|
||||
|
||||
/// Is this iterator equal to the sequence's begin() iterator?
|
||||
bool _M_is_begin() const
|
||||
{ return base() == _M_get_sequence()->_M_base().begin(); }
|
||||
|
||||
/// Is this iterator equal to the sequence's end() iterator?
|
||||
bool _M_is_end() const
|
||||
{ return base() == _M_get_sequence()->_M_base().end(); }
|
||||
|
||||
/// Is this iterator equal to the sequence's before_begin() iterator if
|
||||
/// any?
|
||||
bool _M_is_before_begin() const
|
||||
{
|
||||
return _BeforeBeginHelper<_Sequence>::_S_Is(base(), _M_get_sequence());
|
||||
}
|
||||
|
||||
/// Is this iterator equal to the sequence's before_begin() iterator if
|
||||
/// any or begin() otherwise?
|
||||
bool _M_is_beginnest() const
|
||||
{
|
||||
return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(base(),
|
||||
_M_get_sequence());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() == __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() == __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() != __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() != __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() < __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() < __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() <= __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() <= __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() > __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() > __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() >= __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_order_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_order_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() >= __rhs.base();
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// According to the resolution of DR179 not only the various comparison
|
||||
// operators but also operator- must accept mixed iterator/const_iterator
|
||||
// parameters.
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
|
||||
operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_distance_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_distance_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() - __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
|
||||
operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_distance_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_distance_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() - __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline _Safe_iterator<_Iterator, _Sequence>
|
||||
operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
|
||||
const _Safe_iterator<_Iterator, _Sequence>& __i)
|
||||
{ return __i + __n; }
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#include <debug/safe_iterator.tcc>
|
||||
|
||||
#endif
|
106
contrib/sdk/sources/libstdc++-v3/include/debug/safe_iterator.tcc
Normal file
106
contrib/sdk/sources/libstdc++-v3/include/debug/safe_iterator.tcc
Normal file
@@ -0,0 +1,106 @@
|
||||
// Debugging iterator implementation (out of line) -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_iterator.tcc
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC
|
||||
#define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
bool
|
||||
_Safe_iterator<_Iterator, _Sequence>::
|
||||
_M_can_advance(const difference_type& __n) const
|
||||
{
|
||||
typedef typename _Sequence::const_iterator const_debug_iterator;
|
||||
typedef typename const_debug_iterator::iterator_type const_iterator;
|
||||
|
||||
if (this->_M_singular())
|
||||
return false;
|
||||
if (__n == 0)
|
||||
return true;
|
||||
if (__n < 0)
|
||||
{
|
||||
const_iterator __begin = _M_get_sequence()->_M_base().begin();
|
||||
std::pair<difference_type, _Distance_precision> __dist =
|
||||
__get_distance(__begin, base());
|
||||
bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n)
|
||||
|| (__dist.second != __dp_exact && __dist.first > 0));
|
||||
return __ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
const_iterator __end = _M_get_sequence()->_M_base().end();
|
||||
std::pair<difference_type, _Distance_precision> __dist =
|
||||
__get_distance(base(), __end);
|
||||
bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n)
|
||||
|| (__dist.second != __dp_exact && __dist.first > 0));
|
||||
return __ok;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
template<typename _Other>
|
||||
bool
|
||||
_Safe_iterator<_Iterator, _Sequence>::
|
||||
_M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const
|
||||
{
|
||||
if (!_M_can_compare(__rhs))
|
||||
return false;
|
||||
|
||||
/* Determine if we can order the iterators without the help of
|
||||
the container */
|
||||
std::pair<difference_type, _Distance_precision> __dist =
|
||||
__get_distance(base(), __rhs.base());
|
||||
switch (__dist.second) {
|
||||
case __dp_equality:
|
||||
if (__dist.first == 0)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case __dp_sign:
|
||||
case __dp_exact:
|
||||
return __dist.first >= 0;
|
||||
}
|
||||
|
||||
/* We can only test for equality, but check if one of the
|
||||
iterators is at an extreme. */
|
||||
/* Optim for classic [begin, it) or [it, end) ranges, limit checks
|
||||
* when code is valid. Note, for the special case of forward_list,
|
||||
* before_begin replaces the role of begin. */
|
||||
if (_M_is_beginnest() || __rhs._M_is_end())
|
||||
return true;
|
||||
if (_M_is_end() || __rhs._M_is_beginnest())
|
||||
return false;
|
||||
|
||||
// Assume that this is a valid range; we can't check anything else
|
||||
return true;
|
||||
}
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
||||
|
@@ -0,0 +1,369 @@
|
||||
// Safe iterator implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_local_iterator.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H
|
||||
#define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 1
|
||||
|
||||
#include <debug/debug.h>
|
||||
#include <debug/macros.h>
|
||||
#include <debug/functions.h>
|
||||
#include <debug/safe_unordered_base.h>
|
||||
#include <ext/type_traits.h>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
/** \brief Safe iterator wrapper.
|
||||
*
|
||||
* The class template %_Safe_local_iterator is a wrapper around an
|
||||
* iterator that tracks the iterator's movement among sequences and
|
||||
* checks that operations performed on the "safe" iterator are
|
||||
* legal. In additional to the basic iterator operations (which are
|
||||
* validated, and then passed to the underlying iterator),
|
||||
* %_Safe_local_iterator has member functions for iterator invalidation,
|
||||
* attaching/detaching the iterator from sequences, and querying
|
||||
* the iterator's state.
|
||||
*/
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
class _Safe_local_iterator : public _Safe_local_iterator_base
|
||||
{
|
||||
typedef _Safe_local_iterator _Self;
|
||||
typedef typename _Sequence::size_type size_type;
|
||||
|
||||
/// The underlying iterator
|
||||
_Iterator _M_current;
|
||||
|
||||
/// The bucket this local iterator belongs to
|
||||
size_type _M_bucket;
|
||||
|
||||
/// Determine if this is a constant iterator.
|
||||
bool
|
||||
_M_constant() const
|
||||
{
|
||||
typedef typename _Sequence::const_local_iterator const_iterator;
|
||||
return std::__are_same<const_iterator, _Safe_local_iterator>::__value;
|
||||
}
|
||||
|
||||
typedef std::iterator_traits<_Iterator> _Traits;
|
||||
|
||||
public:
|
||||
typedef _Iterator iterator_type;
|
||||
typedef typename _Traits::iterator_category iterator_category;
|
||||
typedef typename _Traits::value_type value_type;
|
||||
typedef typename _Traits::difference_type difference_type;
|
||||
typedef typename _Traits::reference reference;
|
||||
typedef typename _Traits::pointer pointer;
|
||||
|
||||
/// @post the iterator is singular and unattached
|
||||
_Safe_local_iterator() : _M_current() { }
|
||||
|
||||
/**
|
||||
* @brief Safe iterator construction from an unsafe iterator and
|
||||
* its sequence.
|
||||
*
|
||||
* @pre @p seq is not NULL
|
||||
* @post this is not singular
|
||||
*/
|
||||
_Safe_local_iterator(const _Iterator& __i, size_type __bucket,
|
||||
const _Sequence* __seq)
|
||||
: _Safe_local_iterator_base(__seq, _M_constant()), _M_current(__i),
|
||||
_M_bucket(__bucket)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
|
||||
_M_message(__msg_init_singular)
|
||||
._M_iterator(*this, "this"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy construction.
|
||||
*/
|
||||
_Safe_local_iterator(const _Safe_local_iterator& __x)
|
||||
: _Safe_local_iterator_base(__x, _M_constant()),
|
||||
_M_current(__x._M_current), _M_bucket(__x._M_bucket)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x._M_current == _Iterator(),
|
||||
_M_message(__msg_init_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting constructor from a mutable iterator to a
|
||||
* constant iterator.
|
||||
*/
|
||||
template<typename _MutableIterator>
|
||||
_Safe_local_iterator(
|
||||
const _Safe_local_iterator<_MutableIterator,
|
||||
typename __gnu_cxx::__enable_if<std::__are_same<
|
||||
_MutableIterator,
|
||||
typename _Sequence::local_iterator::iterator_type>::__value,
|
||||
_Sequence>::__type>& __x)
|
||||
: _Safe_local_iterator_base(__x, _M_constant()),
|
||||
_M_current(__x.base()), _M_bucket(__x._M_bucket)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x.base() == _Iterator(),
|
||||
_M_message(__msg_init_const_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment.
|
||||
*/
|
||||
_Safe_local_iterator&
|
||||
operator=(const _Safe_local_iterator& __x)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
|
||||
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|
||||
|| __x._M_current == _Iterator(),
|
||||
_M_message(__msg_copy_singular)
|
||||
._M_iterator(*this, "this")
|
||||
._M_iterator(__x, "other"));
|
||||
_M_current = __x._M_current;
|
||||
_M_bucket = __x._M_bucket;
|
||||
this->_M_attach(__x._M_sequence);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterator dereference.
|
||||
* @pre iterator is dereferenceable
|
||||
*/
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
|
||||
_M_message(__msg_bad_deref)
|
||||
._M_iterator(*this, "this"));
|
||||
return *_M_current;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterator dereference.
|
||||
* @pre iterator is dereferenceable
|
||||
* @todo Make this correct w.r.t. iterators that return proxies
|
||||
* @todo Use addressof() instead of & operator
|
||||
*/
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
|
||||
_M_message(__msg_bad_deref)
|
||||
._M_iterator(*this, "this"));
|
||||
return &*_M_current;
|
||||
}
|
||||
|
||||
// ------ Input iterator requirements ------
|
||||
/**
|
||||
* @brief Iterator preincrement
|
||||
* @pre iterator is incrementable
|
||||
*/
|
||||
_Safe_local_iterator&
|
||||
operator++()
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
|
||||
_M_message(__msg_bad_inc)
|
||||
._M_iterator(*this, "this"));
|
||||
++_M_current;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterator postincrement
|
||||
* @pre iterator is incrementable
|
||||
*/
|
||||
_Safe_local_iterator
|
||||
operator++(int)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
|
||||
_M_message(__msg_bad_inc)
|
||||
._M_iterator(*this, "this"));
|
||||
_Safe_local_iterator __tmp(*this);
|
||||
++_M_current;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
// ------ Utilities ------
|
||||
/**
|
||||
* @brief Return the underlying iterator
|
||||
*/
|
||||
_Iterator
|
||||
base() const { return _M_current; }
|
||||
|
||||
/**
|
||||
* @brief Return the bucket
|
||||
*/
|
||||
size_type
|
||||
bucket() const { return _M_bucket; }
|
||||
|
||||
/**
|
||||
* @brief Conversion to underlying non-debug iterator to allow
|
||||
* better interaction with non-debug containers.
|
||||
*/
|
||||
operator _Iterator() const { return _M_current; }
|
||||
|
||||
/** Attach iterator to the given sequence. */
|
||||
void
|
||||
_M_attach(_Safe_sequence_base* __seq)
|
||||
{ _Safe_iterator_base::_M_attach(__seq, _M_constant()); }
|
||||
|
||||
/** Likewise, but not thread-safe. */
|
||||
void
|
||||
_M_attach_single(_Safe_sequence_base* __seq)
|
||||
{ _Safe_iterator_base::_M_attach_single(__seq, _M_constant()); }
|
||||
|
||||
/// Is the iterator dereferenceable?
|
||||
bool
|
||||
_M_dereferenceable() const
|
||||
{ return !this->_M_singular() && !_M_is_end(); }
|
||||
|
||||
/// Is the iterator incrementable?
|
||||
bool
|
||||
_M_incrementable() const
|
||||
{ return !this->_M_singular() && !_M_is_end(); }
|
||||
|
||||
// Is the iterator range [*this, __rhs) valid?
|
||||
template<typename _Other>
|
||||
bool
|
||||
_M_valid_range(const _Safe_local_iterator<_Other,
|
||||
_Sequence>& __rhs) const;
|
||||
|
||||
// The sequence this iterator references.
|
||||
const _Sequence*
|
||||
_M_get_sequence() const
|
||||
{ return static_cast<const _Sequence*>(_M_sequence); }
|
||||
|
||||
/// Is this iterator equal to the sequence's begin() iterator?
|
||||
bool _M_is_begin() const
|
||||
{ return base() == _M_get_sequence()->_M_base().begin(_M_bucket); }
|
||||
|
||||
/// Is this iterator equal to the sequence's end() iterator?
|
||||
bool _M_is_end() const
|
||||
{ return base() == _M_get_sequence()->_M_base().end(_M_bucket); }
|
||||
|
||||
/// Is this iterator part of the same bucket as the other one?
|
||||
template <typename _Other>
|
||||
bool _M_in_same_bucket(const _Safe_local_iterator<_Other,
|
||||
_Sequence>& __other) const
|
||||
{ return _M_bucket == __other.bucket(); }
|
||||
};
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator==(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
|
||||
_M_message(__msg_local_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() == __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator==(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
|
||||
_M_message(__msg_local_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() == __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
|
||||
inline bool
|
||||
operator!=(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
|
||||
const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
|
||||
_M_message(__msg_local_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() != __rhs.base();
|
||||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
inline bool
|
||||
operator!=(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
|
||||
const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
|
||||
_M_message(__msg_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
|
||||
_M_message(__msg_compare_different)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
|
||||
_M_message(__msg_local_iter_compare_bad)
|
||||
._M_iterator(__lhs, "lhs")
|
||||
._M_iterator(__rhs, "rhs"));
|
||||
return __lhs.base() != __rhs.base();
|
||||
}
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#include <debug/safe_local_iterator.tcc>
|
||||
|
||||
#endif
|
@@ -0,0 +1,75 @@
|
||||
// Debugging iterator implementation (out of line) -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_local_iterator.tcc
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_TCC
|
||||
#define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_TCC 1
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
template<typename _Other>
|
||||
bool
|
||||
_Safe_local_iterator<_Iterator, _Sequence>::
|
||||
_M_valid_range(const _Safe_local_iterator<_Other, _Sequence>& __rhs) const
|
||||
{
|
||||
if (!_M_can_compare(__rhs))
|
||||
return false;
|
||||
if (_M_bucket != __rhs._M_bucket)
|
||||
return false;
|
||||
|
||||
/* Determine if we can order the iterators without the help of
|
||||
the container */
|
||||
std::pair<difference_type, _Distance_precision> __dist =
|
||||
__get_distance(base(), __rhs.base());
|
||||
switch (__dist.second)
|
||||
{
|
||||
case __dp_equality:
|
||||
if (__dist.first == 0)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case __dp_sign:
|
||||
case __dp_exact:
|
||||
return __dist.first >= 0;
|
||||
}
|
||||
|
||||
/* We can only test for equality, but check if one of the
|
||||
iterators is at an extreme. */
|
||||
/* Optim for classic [begin, it) or [it, end) ranges, limit checks
|
||||
* when code is valid. */
|
||||
if (_M_is_begin() || __rhs._M_is_end())
|
||||
return true;
|
||||
if (_M_is_end() || __rhs._M_is_begin())
|
||||
return false;
|
||||
|
||||
// Assume that this is a valid range; we can't check anything else
|
||||
return true;
|
||||
}
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
134
contrib/sdk/sources/libstdc++-v3/include/debug/safe_sequence.h
Normal file
134
contrib/sdk/sources/libstdc++-v3/include/debug/safe_sequence.h
Normal file
@@ -0,0 +1,134 @@
|
||||
// Safe sequence implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_sequence.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H
|
||||
#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1
|
||||
|
||||
#include <debug/debug.h>
|
||||
#include <debug/macros.h>
|
||||
#include <debug/functions.h>
|
||||
#include <debug/safe_base.h>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<typename _Iterator, typename _Sequence>
|
||||
class _Safe_iterator;
|
||||
|
||||
/** A simple function object that returns true if the passed-in
|
||||
* value is not equal to the stored value. It saves typing over
|
||||
* using both bind1st and not_equal.
|
||||
*/
|
||||
template<typename _Type>
|
||||
class _Not_equal_to
|
||||
{
|
||||
_Type __value;
|
||||
|
||||
public:
|
||||
explicit _Not_equal_to(const _Type& __v) : __value(__v) { }
|
||||
|
||||
bool
|
||||
operator()(const _Type& __x) const
|
||||
{ return __value != __x; }
|
||||
};
|
||||
|
||||
/** A simple function object that returns true if the passed-in
|
||||
* value is equal to the stored value. */
|
||||
template <typename _Type>
|
||||
class _Equal_to
|
||||
{
|
||||
_Type __value;
|
||||
|
||||
public:
|
||||
explicit _Equal_to(const _Type& __v) : __value(__v) { }
|
||||
|
||||
bool
|
||||
operator()(const _Type& __x) const
|
||||
{ return __value == __x; }
|
||||
};
|
||||
|
||||
/** A function object that returns true when the given random access
|
||||
iterator is at least @c n steps away from the given iterator. */
|
||||
template<typename _Iterator>
|
||||
class _After_nth_from
|
||||
{
|
||||
typedef typename std::iterator_traits<_Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
_Iterator _M_base;
|
||||
difference_type _M_n;
|
||||
|
||||
public:
|
||||
_After_nth_from(const difference_type& __n, const _Iterator& __base)
|
||||
: _M_base(__base), _M_n(__n) { }
|
||||
|
||||
bool
|
||||
operator()(const _Iterator& __x) const
|
||||
{ return __x - _M_base >= _M_n; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base class for constructing a @a safe sequence type that
|
||||
* tracks iterators that reference it.
|
||||
*
|
||||
* The class template %_Safe_sequence simplifies the construction of
|
||||
* @a safe sequences that track the iterators that reference the
|
||||
* sequence, so that the iterators are notified of changes in the
|
||||
* sequence that may affect their operation, e.g., if the container
|
||||
* invalidates its iterators or is destructed. This class template
|
||||
* may only be used by deriving from it and passing the name of the
|
||||
* derived class as its template parameter via the curiously
|
||||
* recurring template pattern. The derived class must have @c
|
||||
* iterator and @c const_iterator types that are instantiations of
|
||||
* class template _Safe_iterator for this sequence. Iterators will
|
||||
* then be tracked automatically.
|
||||
*/
|
||||
template<typename _Sequence>
|
||||
class _Safe_sequence : public _Safe_sequence_base
|
||||
{
|
||||
public:
|
||||
/** Invalidates all iterators @c x that reference this sequence,
|
||||
are not singular, and for which @c __pred(x) returns @c
|
||||
true. @c __pred will be invoked with the normal iterators nested
|
||||
in the safe ones. */
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_M_invalidate_if(_Predicate __pred);
|
||||
|
||||
/** Transfers all iterators @c x that reference @c from sequence,
|
||||
are not singular, and for which @c __pred(x) returns @c
|
||||
true. @c __pred will be invoked with the normal iterators nested
|
||||
in the safe ones. */
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred);
|
||||
};
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#include <debug/safe_sequence.tcc>
|
||||
|
||||
#endif
|
150
contrib/sdk/sources/libstdc++-v3/include/debug/safe_sequence.tcc
Normal file
150
contrib/sdk/sources/libstdc++-v3/include/debug/safe_sequence.tcc
Normal file
@@ -0,0 +1,150 @@
|
||||
// Safe sequence implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2010-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_sequence.tcc
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_TCC
|
||||
#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_TCC 1
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<typename _Sequence>
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_Safe_sequence<_Sequence>::
|
||||
_M_invalidate_if(_Predicate __pred)
|
||||
{
|
||||
typedef typename _Sequence::iterator iterator;
|
||||
typedef typename _Sequence::const_iterator const_iterator;
|
||||
|
||||
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
|
||||
for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
|
||||
{
|
||||
iterator* __victim = static_cast<iterator*>(__iter);
|
||||
__iter = __iter->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
|
||||
{
|
||||
const_iterator* __victim = static_cast<const_iterator*>(__iter2);
|
||||
__iter2 = __iter2->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Sequence>
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_Safe_sequence<_Sequence>::
|
||||
_M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred)
|
||||
{
|
||||
typedef typename _Sequence::iterator iterator;
|
||||
typedef typename _Sequence::const_iterator const_iterator;
|
||||
|
||||
_Safe_iterator_base* __transfered_iterators = 0;
|
||||
_Safe_iterator_base* __transfered_const_iterators = 0;
|
||||
_Safe_iterator_base* __last_iterator = 0;
|
||||
_Safe_iterator_base* __last_const_iterator = 0;
|
||||
{
|
||||
// We lock __from first and detach iterator(s) to transfer
|
||||
__gnu_cxx::__scoped_lock sentry(__from._M_get_mutex());
|
||||
|
||||
for (_Safe_iterator_base* __iter = __from._M_iterators; __iter;)
|
||||
{
|
||||
iterator* __victim = static_cast<iterator*>(__iter);
|
||||
__iter = __iter->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_detach_single();
|
||||
if (__transfered_iterators)
|
||||
{
|
||||
__victim->_M_next = __transfered_iterators;
|
||||
__transfered_iterators->_M_prior = __victim;
|
||||
}
|
||||
else
|
||||
__last_iterator = __victim;
|
||||
__victim->_M_sequence = this;
|
||||
__victim->_M_version = this->_M_version;
|
||||
__transfered_iterators = __victim;
|
||||
}
|
||||
}
|
||||
|
||||
for (_Safe_iterator_base* __iter2 = __from._M_const_iterators;
|
||||
__iter2;)
|
||||
{
|
||||
const_iterator* __victim = static_cast<const_iterator*>(__iter2);
|
||||
__iter2 = __iter2->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_detach_single();
|
||||
if (__transfered_const_iterators)
|
||||
{
|
||||
__victim->_M_next = __transfered_const_iterators;
|
||||
__transfered_const_iterators->_M_prior = __victim;
|
||||
}
|
||||
else
|
||||
__last_const_iterator = __victim;
|
||||
__victim->_M_sequence = this;
|
||||
__victim->_M_version = this->_M_version;
|
||||
__transfered_const_iterators = __victim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can lock *this and add the transfered iterators if any
|
||||
if (__last_iterator || __last_const_iterator)
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
|
||||
if (__last_iterator)
|
||||
{
|
||||
if (this->_M_iterators)
|
||||
{
|
||||
this->_M_iterators->_M_prior = __last_iterator;
|
||||
__last_iterator->_M_next = this->_M_iterators;
|
||||
}
|
||||
this->_M_iterators = __transfered_iterators;
|
||||
}
|
||||
if (__last_const_iterator)
|
||||
{
|
||||
if (this->_M_const_iterators)
|
||||
{
|
||||
this->_M_const_iterators->_M_prior = __last_const_iterator;
|
||||
__last_const_iterator->_M_next = this->_M_const_iterators;
|
||||
}
|
||||
this->_M_const_iterators = __transfered_const_iterators;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
@@ -0,0 +1,175 @@
|
||||
// Safe container/iterator base implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_unordered_base.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_BASE_H
|
||||
#define _GLIBCXX_DEBUG_SAFE_UNORDERED_BASE_H 1
|
||||
|
||||
#include <debug/safe_base.h>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
class _Safe_unordered_container_base;
|
||||
|
||||
/** \brief Basic functionality for a @a safe iterator.
|
||||
*
|
||||
* The %_Safe_local_iterator_base base class implements the functionality
|
||||
* of a safe local iterator that is not specific to a particular iterator
|
||||
* type. It contains a pointer back to the container it references
|
||||
* along with iterator version information and pointers to form a
|
||||
* doubly-linked list of local iterators referenced by the container.
|
||||
*
|
||||
* This class must not perform any operations that can throw an
|
||||
* exception, or the exception guarantees of derived iterators will
|
||||
* be broken.
|
||||
*/
|
||||
class _Safe_local_iterator_base : public _Safe_iterator_base
|
||||
{
|
||||
protected:
|
||||
/** Initializes the iterator and makes it singular. */
|
||||
_Safe_local_iterator_base()
|
||||
{ }
|
||||
|
||||
/** Initialize the iterator to reference the container pointed to
|
||||
* by @p __seq. @p __constant is true when we are initializing a
|
||||
* constant local iterator, and false if it is a mutable local iterator.
|
||||
* Note that @p __seq may be NULL, in which case the iterator will be
|
||||
* singular. Otherwise, the iterator will reference @p __seq and
|
||||
* be nonsingular.
|
||||
*/
|
||||
_Safe_local_iterator_base(const _Safe_sequence_base* __seq, bool __constant)
|
||||
{ this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); }
|
||||
|
||||
/** Initializes the iterator to reference the same container that
|
||||
@p __x does. @p __constant is true if this is a constant
|
||||
iterator, and false if it is mutable. */
|
||||
_Safe_local_iterator_base(const _Safe_local_iterator_base& __x,
|
||||
bool __constant)
|
||||
{ this->_M_attach(__x._M_sequence, __constant); }
|
||||
|
||||
_Safe_local_iterator_base&
|
||||
operator=(const _Safe_local_iterator_base&);
|
||||
|
||||
explicit
|
||||
_Safe_local_iterator_base(const _Safe_local_iterator_base&);
|
||||
|
||||
~_Safe_local_iterator_base() { this->_M_detach(); }
|
||||
|
||||
_Safe_unordered_container_base*
|
||||
_M_get_container() const _GLIBCXX_NOEXCEPT;
|
||||
|
||||
public:
|
||||
/** Attaches this iterator to the given container, detaching it
|
||||
* from whatever container it was attached to originally. If the
|
||||
* new container is the NULL pointer, the iterator is left
|
||||
* unattached.
|
||||
*/
|
||||
void _M_attach(_Safe_sequence_base* __seq, bool __constant);
|
||||
|
||||
/** Likewise, but not thread-safe. */
|
||||
void _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
|
||||
|
||||
/** Detach the iterator for whatever container it is attached to,
|
||||
* if any.
|
||||
*/
|
||||
void _M_detach();
|
||||
|
||||
/** Likewise, but not thread-safe. */
|
||||
void _M_detach_single() throw ();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base class that supports tracking of local iterators that
|
||||
* reference an unordered container.
|
||||
*
|
||||
* The %_Safe_unordered_container_base class provides basic support for
|
||||
* tracking iterators into an unordered container. Containers that track
|
||||
* iterators must derived from %_Safe_unordered_container_base publicly, so
|
||||
* that safe iterators (which inherit _Safe_iterator_base) can
|
||||
* attach to them. This class contains four linked lists of
|
||||
* iterators, one for constant iterators, one for mutable
|
||||
* iterators, one for constant local iterators, one for mutable local
|
||||
* iterators and a version number that allows very fast
|
||||
* invalidation of all iterators that reference the container.
|
||||
*
|
||||
* This class must ensure that no operation on it may throw an
|
||||
* exception, otherwise @a safe containers may fail to provide the
|
||||
* exception-safety guarantees required by the C++ standard.
|
||||
*/
|
||||
class _Safe_unordered_container_base : public _Safe_sequence_base
|
||||
{
|
||||
typedef _Safe_sequence_base _Base;
|
||||
public:
|
||||
/// The list of mutable local iterators that reference this container
|
||||
_Safe_iterator_base* _M_local_iterators;
|
||||
|
||||
/// The list of constant local iterators that reference this container
|
||||
_Safe_iterator_base* _M_const_local_iterators;
|
||||
|
||||
protected:
|
||||
// Initialize with a version number of 1 and no iterators
|
||||
_Safe_unordered_container_base()
|
||||
: _M_local_iterators(0), _M_const_local_iterators(0)
|
||||
{ }
|
||||
|
||||
/** Notify all iterators that reference this container that the
|
||||
container is being destroyed. */
|
||||
~_Safe_unordered_container_base()
|
||||
{ this->_M_detach_all(); }
|
||||
|
||||
/** Detach all iterators, leaving them singular. */
|
||||
void
|
||||
_M_detach_all();
|
||||
|
||||
/** Swap this container with the given container. This operation
|
||||
* also swaps ownership of the iterators, so that when the
|
||||
* operation is complete all iterators that originally referenced
|
||||
* one container now reference the other container.
|
||||
*/
|
||||
void
|
||||
_M_swap(_Safe_unordered_container_base& __x);
|
||||
|
||||
public:
|
||||
/** Attach an iterator to this container. */
|
||||
void
|
||||
_M_attach_local(_Safe_iterator_base* __it, bool __constant);
|
||||
|
||||
/** Likewise but not thread safe. */
|
||||
void
|
||||
_M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ();
|
||||
|
||||
/** Detach an iterator from this container */
|
||||
void
|
||||
_M_detach_local(_Safe_iterator_base* __it);
|
||||
|
||||
/** Likewise but not thread safe. */
|
||||
void
|
||||
_M_detach_local_single(_Safe_iterator_base* __it) throw ();
|
||||
};
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
@@ -0,0 +1,81 @@
|
||||
// Safe container implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_unordered_container.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H
|
||||
#define _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H 1
|
||||
|
||||
#include <debug/debug.h>
|
||||
#include <debug/macros.h>
|
||||
#include <debug/functions.h>
|
||||
#include <debug/safe_unordered_base.h>
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
/**
|
||||
* @brief Base class for constructing a @a safe unordered container type
|
||||
* that tracks iterators that reference it.
|
||||
*
|
||||
* The class template %_Safe_unordered_container simplifies the
|
||||
* construction of @a safe unordered containers that track the iterators
|
||||
* that reference the container, so that the iterators are notified of
|
||||
* changes in the container that may affect their operation, e.g., if
|
||||
* the container invalidates its iterators or is destructed. This class
|
||||
* template may only be used by deriving from it and passing the name
|
||||
* of the derived class as its template parameter via the curiously
|
||||
* recurring template pattern. The derived class must have @c
|
||||
* iterator and @c const_iterator types that are instantiations of
|
||||
* class template _Safe_iterator for this container and @c local_iterator
|
||||
* and @c const_local_iterator types that are instantiations of class
|
||||
* template _Safe_local_iterator for this container. Iterators will
|
||||
* then be tracked automatically.
|
||||
*/
|
||||
template<typename _Container>
|
||||
class _Safe_unordered_container : public _Safe_unordered_container_base
|
||||
{
|
||||
public:
|
||||
/** Invalidates all iterators @c x that reference this container,
|
||||
are not singular, and for which @c __pred(x) returns @c
|
||||
true. @c __pred will be invoked with the normal iterators nested
|
||||
in the safe ones. */
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_M_invalidate_if(_Predicate __pred);
|
||||
|
||||
/** Invalidates all local iterators @c x that reference this container,
|
||||
are not singular, and for which @c __pred(x) returns @c
|
||||
true. @c __pred will be invoked with the normal ilocal iterators
|
||||
nested in the safe ones. */
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_M_invalidate_local_if(_Predicate __pred);
|
||||
};
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#include <debug/safe_unordered_container.tcc>
|
||||
|
||||
#endif
|
@@ -0,0 +1,100 @@
|
||||
// Safe container implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/safe_unordered_container.tcc
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_TCC
|
||||
#define _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_TCC 1
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<typename _Container>
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_Safe_unordered_container<_Container>::
|
||||
_M_invalidate_if(_Predicate __pred)
|
||||
{
|
||||
typedef typename _Container::iterator iterator;
|
||||
typedef typename _Container::const_iterator const_iterator;
|
||||
|
||||
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
|
||||
for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
|
||||
{
|
||||
iterator* __victim = static_cast<iterator*>(__iter);
|
||||
__iter = __iter->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
|
||||
{
|
||||
const_iterator* __victim = static_cast<const_iterator*>(__iter2);
|
||||
__iter2 = __iter2->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename _Container>
|
||||
template<typename _Predicate>
|
||||
void
|
||||
_Safe_unordered_container<_Container>::
|
||||
_M_invalidate_local_if(_Predicate __pred)
|
||||
{
|
||||
typedef typename _Container::local_iterator local_iterator;
|
||||
typedef typename _Container::const_local_iterator const_local_iterator;
|
||||
|
||||
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
|
||||
for (_Safe_iterator_base* __iter = _M_local_iterators; __iter;)
|
||||
{
|
||||
local_iterator* __victim = static_cast<local_iterator*>(__iter);
|
||||
__iter = __iter->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
for (_Safe_iterator_base* __iter2 = _M_const_local_iterators; __iter2;)
|
||||
{
|
||||
const_local_iterator* __victim =
|
||||
static_cast<const_local_iterator*>(__iter2);
|
||||
__iter2 = __iter2->_M_next;
|
||||
if (!__victim->_M_singular() && __pred(__victim->base()))
|
||||
{
|
||||
__victim->_M_invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace __gnu_debug
|
||||
|
||||
#endif
|
36
contrib/sdk/sources/libstdc++-v3/include/debug/set
Normal file
36
contrib/sdk/sources/libstdc++-v3/include/debug/set
Normal file
@@ -0,0 +1,36 @@
|
||||
// Debugging set/multiset implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/set
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SET
|
||||
#define _GLIBCXX_DEBUG_SET 1
|
||||
|
||||
#include <set>
|
||||
#include <debug/set.h>
|
||||
#include <debug/multiset.h>
|
||||
|
||||
#endif
|
469
contrib/sdk/sources/libstdc++-v3/include/debug/set.h
Normal file
469
contrib/sdk/sources/libstdc++-v3/include/debug/set.h
Normal file
@@ -0,0 +1,469 @@
|
||||
// Debugging set implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/set.h
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_SET_H
|
||||
#define _GLIBCXX_DEBUG_SET_H 1
|
||||
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
#include <utility>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::set with safety/checking/debug instrumentation.
|
||||
template<typename _Key, typename _Compare = std::less<_Key>,
|
||||
typename _Allocator = std::allocator<_Key> >
|
||||
class set
|
||||
: public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base;
|
||||
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
|
||||
public:
|
||||
// types:
|
||||
typedef _Key key_type;
|
||||
typedef _Key value_type;
|
||||
typedef _Compare key_compare;
|
||||
typedef _Compare value_compare;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator, set>
|
||||
iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, set>
|
||||
const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// 23.3.3.1 construct/copy/destroy:
|
||||
explicit set(const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__comp, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
set(_InputIterator __first, _InputIterator __last,
|
||||
const _Compare& __comp = _Compare(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last),
|
||||
__comp, __a) { }
|
||||
|
||||
set(const set& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
set(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
set(set&& __x)
|
||||
noexcept(is_nothrow_copy_constructible<_Compare>::value)
|
||||
: _Base(std::move(__x))
|
||||
{ this->_M_swap(__x); }
|
||||
|
||||
set(initializer_list<value_type> __l,
|
||||
const _Compare& __comp = _Compare(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __comp, __a) { }
|
||||
#endif
|
||||
|
||||
~set() _GLIBCXX_NOEXCEPT { }
|
||||
|
||||
set&
|
||||
operator=(const set& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
set&
|
||||
operator=(set&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
set&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
iterator
|
||||
begin() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
// capacity:
|
||||
using _Base::empty;
|
||||
using _Base::size;
|
||||
using _Base::max_size;
|
||||
|
||||
// modifiers:
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename... _Args>
|
||||
std::pair<iterator, bool>
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
auto __res = _Base::emplace(std::forward<_Args>(__args)...);
|
||||
return std::pair<iterator, bool>(iterator(__res.first, this),
|
||||
__res.second);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __pos, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__pos);
|
||||
return iterator(_Base::emplace_hint(__pos.base(),
|
||||
std::forward<_Args>(__args)...),
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool>
|
||||
insert(const value_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
|
||||
return std::pair<iterator, bool>(iterator(__res.first, this),
|
||||
__res.second);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
std::pair<iterator, bool>
|
||||
insert(value_type&& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, bool> __res
|
||||
= _Base::insert(std::move(__x));
|
||||
return std::pair<iterator, bool>(iterator(__res.first, this),
|
||||
__res.second);
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator
|
||||
insert(const_iterator __position, const value_type& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(), __x), this);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
insert(const_iterator __position, value_type&& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
return iterator(_Base::insert(__position.base(), std::move(__x)),
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
insert(initializer_list<value_type> __l)
|
||||
{ _Base::insert(__l); }
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return iterator(_Base::erase(__position.base()), this);
|
||||
}
|
||||
#else
|
||||
void
|
||||
erase(iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
_Base::erase(__position.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
size_type
|
||||
erase(const key_type& __x)
|
||||
{
|
||||
_Base_iterator __victim = _Base::find(__x);
|
||||
if (__victim == _Base::end())
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
_Base::erase(__victim);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
return iterator(_Base::erase(__first.base(), __last.base()), this);
|
||||
}
|
||||
#else
|
||||
void
|
||||
erase(iterator __first, iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_iterator __victim = __first.base();
|
||||
__victim != __last.base(); ++__victim)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(_Equal(__victim));
|
||||
}
|
||||
_Base::erase(__first.base(), __last.base());
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
swap(set& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
this->_M_invalidate_all();
|
||||
_Base::clear();
|
||||
}
|
||||
|
||||
// observers:
|
||||
using _Base::key_comp;
|
||||
using _Base::value_comp;
|
||||
|
||||
// set operations:
|
||||
iterator
|
||||
find(const key_type& __x)
|
||||
{ return iterator(_Base::find(__x), this); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
const_iterator
|
||||
find(const key_type& __x) const
|
||||
{ return const_iterator(_Base::find(__x), this); }
|
||||
|
||||
using _Base::count;
|
||||
|
||||
iterator
|
||||
lower_bound(const key_type& __x)
|
||||
{ return iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
const_iterator
|
||||
lower_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::lower_bound(__x), this); }
|
||||
|
||||
iterator
|
||||
upper_bound(const key_type& __x)
|
||||
{ return iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
const_iterator
|
||||
upper_bound(const key_type& __x) const
|
||||
{ return const_iterator(_Base::upper_bound(__x), this); }
|
||||
|
||||
std::pair<iterator,iterator>
|
||||
equal_range(const key_type& __x)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 214. set::find() missing const overload
|
||||
std::pair<const_iterator,const_iterator>
|
||||
equal_range(const key_type& __x) const
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __res =
|
||||
_Base::equal_range(__x);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
|
||||
this->_M_invalidate_if(_Not_equal(_M_base().end()));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator==(const set<_Key, _Compare, _Allocator>& __lhs,
|
||||
const set<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() == __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator!=(const set<_Key, _Compare, _Allocator>& __lhs,
|
||||
const set<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() != __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<(const set<_Key, _Compare, _Allocator>& __lhs,
|
||||
const set<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() < __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator<=(const set<_Key, _Compare, _Allocator>& __lhs,
|
||||
const set<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() <= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>=(const set<_Key, _Compare, _Allocator>& __lhs,
|
||||
const set<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() >= __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
inline bool
|
||||
operator>(const set<_Key, _Compare, _Allocator>& __lhs,
|
||||
const set<_Key, _Compare, _Allocator>& __rhs)
|
||||
{ return __lhs._M_base() > __rhs._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Allocator>
|
||||
void
|
||||
swap(set<_Key, _Compare, _Allocator>& __x,
|
||||
set<_Key, _Compare, _Allocator>& __y)
|
||||
{ return __x.swap(__y); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif
|
1161
contrib/sdk/sources/libstdc++-v3/include/debug/string
Normal file
1161
contrib/sdk/sources/libstdc++-v3/include/debug/string
Normal file
File diff suppressed because it is too large
Load Diff
903
contrib/sdk/sources/libstdc++-v3/include/debug/unordered_map
Normal file
903
contrib/sdk/sources/libstdc++-v3/include/debug/unordered_map
Normal file
@@ -0,0 +1,903 @@
|
||||
// Debugging unordered_map/unordered_multimap implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/unordered_map
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
|
||||
#define _GLIBCXX_DEBUG_UNORDERED_MAP 1
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
# include <bits/c++0x_warning.h>
|
||||
#else
|
||||
# include <unordered_map>
|
||||
|
||||
#include <debug/safe_unordered_container.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
#include <debug/safe_local_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::unordered_map with safety/checking/debug instrumentation.
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Hash = std::hash<_Key>,
|
||||
typename _Pred = std::equal_to<_Key>,
|
||||
typename _Alloc = std::allocator<_Key> >
|
||||
class unordered_map
|
||||
: public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
|
||||
public __gnu_debug::_Safe_unordered_container<unordered_map<_Key, _Tp,
|
||||
_Hash, _Pred, _Alloc> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
|
||||
_Pred, _Alloc> _Base;
|
||||
typedef __gnu_debug::_Safe_unordered_container<unordered_map> _Safe_base;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_local_iterator _Base_const_local_iterator;
|
||||
typedef typename _Base::local_iterator _Base_local_iterator;
|
||||
|
||||
public:
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::hasher hasher;
|
||||
typedef typename _Base::key_equal key_equal;
|
||||
typedef typename _Base::allocator_type allocator_type;
|
||||
|
||||
typedef typename _Base::key_type key_type;
|
||||
typedef typename _Base::value_type value_type;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator,
|
||||
unordered_map> iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
|
||||
unordered_map> const_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
|
||||
unordered_map> local_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
|
||||
unordered_map> const_local_iterator;
|
||||
|
||||
explicit
|
||||
unordered_map(size_type __n = 10,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__n, __hf, __eql, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
unordered_map(_InputIterator __first, _InputIterator __last,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __n,
|
||||
__hf, __eql, __a) { }
|
||||
|
||||
unordered_map(const unordered_map& __x) = default;
|
||||
|
||||
unordered_map(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
unordered_map(unordered_map&& __x) = default;
|
||||
|
||||
unordered_map(initializer_list<value_type> __l,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __n, __hf, __eql, __a) { }
|
||||
|
||||
~unordered_map() noexcept { }
|
||||
|
||||
unordered_map&
|
||||
operator=(const unordered_map& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_map&
|
||||
operator=(unordered_map&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_map&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
swap(unordered_map& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
_Safe_base::_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
// local versions
|
||||
local_iterator
|
||||
begin(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
local_iterator
|
||||
end(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
begin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
end(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cbegin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cbegin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cend(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cend(__b), __b, this);
|
||||
}
|
||||
|
||||
size_type
|
||||
bucket_size(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return _Base::bucket_size(__b);
|
||||
}
|
||||
|
||||
float
|
||||
max_load_factor() const noexcept
|
||||
{ return _Base::max_load_factor(); }
|
||||
|
||||
void
|
||||
max_load_factor(float __f)
|
||||
{
|
||||
__glibcxx_check_max_load_factor(__f);
|
||||
_Base::max_load_factor(__f);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
std::pair<iterator, bool>
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
std::pair<_Base_iterator, bool> __res
|
||||
= _Base::emplace(std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return std::make_pair(iterator(__res.first, this), __res.second);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __hint, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::emplace_hint(__hint.base(),
|
||||
std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
std::pair<iterator, bool>
|
||||
insert(const value_type& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
std::pair<_Base_iterator, bool> __res = _Base::insert(__obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return std::make_pair(iterator(__res.first, this), __res.second);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const_iterator __hint, const value_type& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__hint.base(), __obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
std::pair<iterator, bool>
|
||||
insert(_Pair&& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
std::pair<_Base_iterator, bool> __res =
|
||||
_Base::insert(std::forward<_Pair>(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return std::make_pair(iterator(__res.first, this), __res.second);
|
||||
}
|
||||
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
iterator
|
||||
insert(const_iterator __hint, _Pair&& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it =
|
||||
_Base::insert(__hint.base(), std::forward<_Pair>(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
void
|
||||
insert(std::initializer_list<value_type> __l)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::insert(__l);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
}
|
||||
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
}
|
||||
|
||||
iterator
|
||||
find(const key_type& __key)
|
||||
{ return iterator(_Base::find(__key), this); }
|
||||
|
||||
const_iterator
|
||||
find(const key_type& __key) const
|
||||
{ return const_iterator(_Base::find(__key), this); }
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& __key)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __res =
|
||||
_Base::equal_range(__key);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& __key) const
|
||||
{
|
||||
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
|
||||
_Base::equal_range(__key);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
size_type
|
||||
erase(const key_type& __key)
|
||||
{
|
||||
size_type __ret(0);
|
||||
_Base_iterator __victim(_Base::find(__key));
|
||||
if (__victim != _Base::end())
|
||||
{
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::erase(__victim);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
__ret = 1;
|
||||
}
|
||||
return __ret;
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase(__it);
|
||||
_Base_const_iterator __victim = __it.base();
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __next = _Base::erase(__it.base());
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__next, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{ return erase(const_iterator(__it)); }
|
||||
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __tmp = __first.base();
|
||||
__tmp != __last.base(); ++__tmp)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
|
||||
{ return __it == __tmp; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__tmp](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __tmp._M_cur; });
|
||||
}
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __next = _Base::erase(__first.base(), __last.base());
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__next, this);
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() noexcept { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const noexcept { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_locals()
|
||||
{
|
||||
_Base_local_iterator __local_end = _Base::end(0);
|
||||
this->_M_invalidate_local_if(
|
||||
[__local_end](_Base_const_local_iterator __it)
|
||||
{ return __it != __local_end; });
|
||||
}
|
||||
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
_Base_iterator __end = _Base::end();
|
||||
this->_M_invalidate_if([__end](_Base_const_iterator __it)
|
||||
{ return __it != __end; });
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
|
||||
void
|
||||
_M_check_rehashed(size_type __prev_count)
|
||||
{
|
||||
if (__prev_count != this->bucket_count())
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash,
|
||||
typename _Pred, typename _Alloc>
|
||||
inline void
|
||||
swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
|
||||
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
|
||||
{ __x.swap(__y); }
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash,
|
||||
typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return __x._M_base() == __y._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash,
|
||||
typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return !(__x == __y); }
|
||||
|
||||
|
||||
/// Class std::unordered_multimap with safety/checking/debug instrumentation.
|
||||
template<typename _Key, typename _Tp,
|
||||
typename _Hash = std::hash<_Key>,
|
||||
typename _Pred = std::equal_to<_Key>,
|
||||
typename _Alloc = std::allocator<_Key> >
|
||||
class unordered_multimap
|
||||
: public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
|
||||
_Pred, _Alloc>,
|
||||
public __gnu_debug::_Safe_unordered_container<unordered_multimap<_Key,
|
||||
_Tp, _Hash, _Pred, _Alloc> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
|
||||
_Pred, _Alloc> _Base;
|
||||
typedef __gnu_debug::_Safe_unordered_container<unordered_multimap>
|
||||
_Safe_base;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_local_iterator _Base_const_local_iterator;
|
||||
typedef typename _Base::local_iterator _Base_local_iterator;
|
||||
|
||||
public:
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::hasher hasher;
|
||||
typedef typename _Base::key_equal key_equal;
|
||||
typedef typename _Base::allocator_type allocator_type;
|
||||
|
||||
typedef typename _Base::key_type key_type;
|
||||
typedef typename _Base::value_type value_type;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator,
|
||||
unordered_multimap> iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
|
||||
unordered_multimap> const_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<
|
||||
_Base_local_iterator, unordered_multimap> local_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<
|
||||
_Base_const_local_iterator, unordered_multimap> const_local_iterator;
|
||||
|
||||
explicit
|
||||
unordered_multimap(size_type __n = 10,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__n, __hf, __eql, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
unordered_multimap(_InputIterator __first, _InputIterator __last,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __n,
|
||||
__hf, __eql, __a) { }
|
||||
|
||||
unordered_multimap(const unordered_multimap& __x) = default;
|
||||
|
||||
unordered_multimap(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
unordered_multimap(unordered_multimap&& __x) = default;
|
||||
|
||||
unordered_multimap(initializer_list<value_type> __l,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __n, __hf, __eql, __a) { }
|
||||
|
||||
~unordered_multimap() noexcept { }
|
||||
|
||||
unordered_multimap&
|
||||
operator=(const unordered_multimap& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_multimap&
|
||||
operator=(unordered_multimap&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_multimap&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
swap(unordered_multimap& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
_Safe_base::_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
// local versions
|
||||
local_iterator
|
||||
begin(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
local_iterator
|
||||
end(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
begin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
end(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cbegin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cbegin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cend(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cend(__b), __b, this);
|
||||
}
|
||||
|
||||
size_type
|
||||
bucket_size(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return _Base::bucket_size(__b);
|
||||
}
|
||||
|
||||
float
|
||||
max_load_factor() const noexcept
|
||||
{ return _Base::max_load_factor(); }
|
||||
|
||||
void
|
||||
max_load_factor(float __f)
|
||||
{
|
||||
__glibcxx_check_max_load_factor(__f);
|
||||
_Base::max_load_factor(__f);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it
|
||||
= _Base::emplace(std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __hint, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::emplace_hint(__hint.base(),
|
||||
std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const value_type& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const_iterator __hint, const value_type& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__hint.base(), __obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
iterator
|
||||
insert(_Pair&& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(std::forward<_Pair>(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
template<typename _Pair, typename = typename
|
||||
std::enable_if<std::is_constructible<value_type,
|
||||
_Pair&&>::value>::type>
|
||||
iterator
|
||||
insert(const_iterator __hint, _Pair&& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it =
|
||||
_Base::insert(__hint.base(), std::forward<_Pair>(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
void
|
||||
insert(std::initializer_list<value_type> __l)
|
||||
{ _Base::insert(__l); }
|
||||
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
}
|
||||
|
||||
iterator
|
||||
find(const key_type& __key)
|
||||
{ return iterator(_Base::find(__key), this); }
|
||||
|
||||
const_iterator
|
||||
find(const key_type& __key) const
|
||||
{ return const_iterator(_Base::find(__key), this); }
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& __key)
|
||||
{
|
||||
std::pair<_Base_iterator, _Base_iterator> __res =
|
||||
_Base::equal_range(__key);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& __key) const
|
||||
{
|
||||
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
|
||||
_Base::equal_range(__key);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
size_type
|
||||
erase(const key_type& __key)
|
||||
{
|
||||
size_type __ret(0);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
std::pair<_Base_iterator, _Base_iterator> __pair =
|
||||
_Base::equal_range(__key);
|
||||
for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
|
||||
{
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
_Base::erase(__victim++);
|
||||
++__ret;
|
||||
}
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return __ret;
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase(__it);
|
||||
_Base_const_iterator __victim = __it.base();
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __next = _Base::erase(__it.base());
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__next, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{ return erase(const_iterator(__it)); }
|
||||
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __tmp = __first.base();
|
||||
__tmp != __last.base(); ++__tmp)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
|
||||
{ return __it == __tmp; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__tmp](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __tmp._M_cur; });
|
||||
}
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __next = _Base::erase(__first.base(), __last.base());
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__next, this);
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() noexcept { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const noexcept { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_locals()
|
||||
{
|
||||
_Base_local_iterator __local_end = _Base::end(0);
|
||||
this->_M_invalidate_local_if(
|
||||
[__local_end](_Base_const_local_iterator __it)
|
||||
{ return __it != __local_end; });
|
||||
}
|
||||
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
_Base_iterator __end = _Base::end();
|
||||
this->_M_invalidate_if([__end](_Base_const_iterator __it)
|
||||
{ return __it != __end; });
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
|
||||
void
|
||||
_M_check_rehashed(size_type __prev_count)
|
||||
{
|
||||
if (__prev_count != this->bucket_count())
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash,
|
||||
typename _Pred, typename _Alloc>
|
||||
inline void
|
||||
swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
|
||||
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
|
||||
{ __x.swap(__y); }
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash,
|
||||
typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return __x._M_base() == __y._M_base(); }
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash,
|
||||
typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return !(__x == __y); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif // C++11
|
||||
|
||||
#endif
|
885
contrib/sdk/sources/libstdc++-v3/include/debug/unordered_set
Normal file
885
contrib/sdk/sources/libstdc++-v3/include/debug/unordered_set
Normal file
@@ -0,0 +1,885 @@
|
||||
// Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/unordered_set
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_UNORDERED_SET
|
||||
#define _GLIBCXX_DEBUG_UNORDERED_SET 1
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
# include <bits/c++0x_warning.h>
|
||||
#else
|
||||
# include <unordered_set>
|
||||
|
||||
#include <debug/safe_unordered_container.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
#include <debug/safe_local_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::unordered_set with safety/checking/debug instrumentation.
|
||||
template<typename _Value,
|
||||
typename _Hash = std::hash<_Value>,
|
||||
typename _Pred = std::equal_to<_Value>,
|
||||
typename _Alloc = std::allocator<_Value> >
|
||||
class unordered_set
|
||||
: public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
|
||||
public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash,
|
||||
_Pred, _Alloc> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash,
|
||||
_Pred, _Alloc> _Base;
|
||||
typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_local_iterator _Base_const_local_iterator;
|
||||
typedef typename _Base::local_iterator _Base_local_iterator;
|
||||
|
||||
public:
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::hasher hasher;
|
||||
typedef typename _Base::key_equal key_equal;
|
||||
typedef typename _Base::allocator_type allocator_type;
|
||||
|
||||
typedef typename _Base::key_type key_type;
|
||||
typedef typename _Base::value_type value_type;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator,
|
||||
unordered_set> iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
|
||||
unordered_set> const_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
|
||||
unordered_set> local_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
|
||||
unordered_set> const_local_iterator;
|
||||
|
||||
explicit
|
||||
unordered_set(size_type __n = 10,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__n, __hf, __eql, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
unordered_set(_InputIterator __first, _InputIterator __last,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __n,
|
||||
__hf, __eql, __a) { }
|
||||
|
||||
unordered_set(const unordered_set& __x) = default;
|
||||
|
||||
unordered_set(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
unordered_set(unordered_set&& __x) = default;
|
||||
|
||||
unordered_set(initializer_list<value_type> __l,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __n, __hf, __eql, __a) { }
|
||||
|
||||
~unordered_set() noexcept { }
|
||||
|
||||
unordered_set&
|
||||
operator=(const unordered_set& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_set&
|
||||
operator=(unordered_set&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_set&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
swap(unordered_set& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
_Safe_base::_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
// local versions
|
||||
local_iterator
|
||||
begin(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
local_iterator
|
||||
end(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
begin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
end(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cbegin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cbegin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cend(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cend(__b), __b, this);
|
||||
}
|
||||
|
||||
size_type
|
||||
bucket_size(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return _Base::bucket_size(__b);
|
||||
}
|
||||
|
||||
float
|
||||
max_load_factor() const noexcept
|
||||
{ return _Base::max_load_factor(); }
|
||||
|
||||
void
|
||||
max_load_factor(float __f)
|
||||
{
|
||||
__glibcxx_check_max_load_factor(__f);
|
||||
_Base::max_load_factor(__f);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
std::pair<iterator, bool>
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
std::pair<_Base_iterator, bool> __res
|
||||
= _Base::emplace(std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return std::make_pair(iterator(__res.first, this), __res.second);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __hint, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::emplace_hint(__hint.base(),
|
||||
std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
std::pair<iterator, bool>
|
||||
insert(const value_type& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
typedef std::pair<_Base_iterator, bool> __pair_type;
|
||||
__pair_type __res = _Base::insert(__obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return std::make_pair(iterator(__res.first, this), __res.second);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const_iterator __hint, const value_type& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__hint.base(), __obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
std::pair<iterator, bool>
|
||||
insert(value_type&& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
typedef std::pair<typename _Base::iterator, bool> __pair_type;
|
||||
__pair_type __res = _Base::insert(std::move(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return std::make_pair(iterator(__res.first, this), __res.second);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const_iterator __hint, value_type&& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
void
|
||||
insert(std::initializer_list<value_type> __l)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::insert(__l);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
}
|
||||
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
}
|
||||
|
||||
iterator
|
||||
find(const key_type& __key)
|
||||
{ return iterator(_Base::find(__key), this); }
|
||||
|
||||
const_iterator
|
||||
find(const key_type& __key) const
|
||||
{ return const_iterator(_Base::find(__key), this); }
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& __key)
|
||||
{
|
||||
typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
|
||||
__pair_type __res = _Base::equal_range(__key);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& __key) const
|
||||
{
|
||||
std::pair<_Base_const_iterator, _Base_const_iterator>
|
||||
__res = _Base::equal_range(__key);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
size_type
|
||||
erase(const key_type& __key)
|
||||
{
|
||||
size_type __ret(0);
|
||||
_Base_iterator __victim(_Base::find(__key));
|
||||
if (__victim != _Base::end())
|
||||
{
|
||||
this->_M_invalidate_if(
|
||||
[__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::erase(__victim);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
__ret = 1;
|
||||
}
|
||||
return __ret;
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase(__it);
|
||||
_Base_const_iterator __victim = __it.base();
|
||||
this->_M_invalidate_if(
|
||||
[__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __next = _Base::erase(__it.base());
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__next, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{ return erase(const_iterator(__it)); }
|
||||
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __tmp = __first.base();
|
||||
__tmp != __last.base(); ++__tmp)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if(
|
||||
[__tmp](_Base_const_iterator __it)
|
||||
{ return __it == __tmp; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__tmp](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __tmp._M_cur; });
|
||||
}
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __next = _Base::erase(__first.base(),
|
||||
__last.base());
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__next, this);
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() noexcept { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const noexcept { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_locals()
|
||||
{
|
||||
_Base_local_iterator __local_end = _Base::end(0);
|
||||
this->_M_invalidate_local_if(
|
||||
[__local_end](_Base_const_local_iterator __it)
|
||||
{ return __it != __local_end; });
|
||||
}
|
||||
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
_Base_iterator __end = _Base::end();
|
||||
this->_M_invalidate_if(
|
||||
[__end](_Base_const_iterator __it)
|
||||
{ return __it != __end; });
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
|
||||
void
|
||||
_M_check_rehashed(size_type __prev_count)
|
||||
{
|
||||
if (__prev_count != this->bucket_count())
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
|
||||
inline void
|
||||
swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
|
||||
unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
|
||||
{ __x.swap(__y); }
|
||||
|
||||
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return __x._M_base() == __y._M_base(); }
|
||||
|
||||
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return !(__x == __y); }
|
||||
|
||||
|
||||
/// Class std::unordered_multiset with safety/checking/debug instrumentation.
|
||||
template<typename _Value,
|
||||
typename _Hash = std::hash<_Value>,
|
||||
typename _Pred = std::equal_to<_Value>,
|
||||
typename _Alloc = std::allocator<_Value> >
|
||||
class unordered_multiset
|
||||
: public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
|
||||
public __gnu_debug::_Safe_unordered_container<
|
||||
unordered_multiset<_Value, _Hash, _Pred, _Alloc> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash,
|
||||
_Pred, _Alloc> _Base;
|
||||
typedef __gnu_debug::_Safe_unordered_container<unordered_multiset>
|
||||
_Safe_base;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_local_iterator _Base_const_local_iterator;
|
||||
typedef typename _Base::local_iterator _Base_local_iterator;
|
||||
|
||||
public:
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::hasher hasher;
|
||||
typedef typename _Base::key_equal key_equal;
|
||||
typedef typename _Base::allocator_type allocator_type;
|
||||
|
||||
typedef typename _Base::key_type key_type;
|
||||
typedef typename _Base::value_type value_type;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator,
|
||||
unordered_multiset> iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
|
||||
unordered_multiset> const_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<
|
||||
_Base_local_iterator, unordered_multiset> local_iterator;
|
||||
typedef __gnu_debug::_Safe_local_iterator<
|
||||
_Base_const_local_iterator, unordered_multiset> const_local_iterator;
|
||||
|
||||
explicit
|
||||
unordered_multiset(size_type __n = 10,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__n, __hf, __eql, __a) { }
|
||||
|
||||
template<typename _InputIterator>
|
||||
unordered_multiset(_InputIterator __first, _InputIterator __last,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __n,
|
||||
__hf, __eql, __a) { }
|
||||
|
||||
unordered_multiset(const unordered_multiset& __x) = default;
|
||||
|
||||
unordered_multiset(const _Base& __x)
|
||||
: _Base(__x) { }
|
||||
|
||||
unordered_multiset(unordered_multiset&& __x) = default;
|
||||
|
||||
unordered_multiset(initializer_list<value_type> __l,
|
||||
size_type __n = 0,
|
||||
const hasher& __hf = hasher(),
|
||||
const key_equal& __eql = key_equal(),
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __n, __hf, __eql, __a) { }
|
||||
|
||||
~unordered_multiset() noexcept { }
|
||||
|
||||
unordered_multiset&
|
||||
operator=(const unordered_multiset& __x)
|
||||
{
|
||||
*static_cast<_Base*>(this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_multiset&
|
||||
operator=(unordered_multiset&& __x)
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
clear();
|
||||
swap(__x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_multiset&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
this->clear();
|
||||
this->insert(__l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
swap(unordered_multiset& __x)
|
||||
{
|
||||
_Base::swap(__x);
|
||||
_Safe_base::_M_swap(__x);
|
||||
}
|
||||
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
// local versions
|
||||
local_iterator
|
||||
begin(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
local_iterator
|
||||
end(size_type __b)
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
begin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::begin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
end(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::end(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cbegin(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cbegin(__b), __b, this);
|
||||
}
|
||||
|
||||
const_local_iterator
|
||||
cend(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return const_local_iterator(_Base::cend(__b), __b, this);
|
||||
}
|
||||
|
||||
size_type
|
||||
bucket_size(size_type __b) const
|
||||
{
|
||||
__glibcxx_check_bucket_index(__b);
|
||||
return _Base::bucket_size(__b);
|
||||
}
|
||||
|
||||
float
|
||||
max_load_factor() const noexcept
|
||||
{ return _Base::max_load_factor(); }
|
||||
|
||||
void
|
||||
max_load_factor(float __f)
|
||||
{
|
||||
__glibcxx_check_max_load_factor(__f);
|
||||
_Base::max_load_factor(__f);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it
|
||||
= _Base::emplace(std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace_hint(const_iterator __hint, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::emplace_hint(__hint.base(),
|
||||
std::forward<_Args>(__args)...);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const value_type& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const_iterator __hint, const value_type& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__hint.base(), __obj);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(value_type&& __obj)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(std::move(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
insert(const_iterator __hint, value_type&& __obj)
|
||||
{
|
||||
__glibcxx_check_insert(__hint);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
return iterator(__it, this);
|
||||
}
|
||||
|
||||
void
|
||||
insert(std::initializer_list<value_type> __l)
|
||||
{
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::insert(__l);
|
||||
_M_check_rehashed(__bucket_count);
|
||||
}
|
||||
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
insert(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
size_type __bucket_count = this->bucket_count();
|
||||
_Base::insert(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
_M_check_rehashed(__bucket_count);
|
||||
}
|
||||
|
||||
iterator
|
||||
find(const key_type& __key)
|
||||
{ return iterator(_Base::find(__key), this); }
|
||||
|
||||
const_iterator
|
||||
find(const key_type& __key) const
|
||||
{ return const_iterator(_Base::find(__key), this); }
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& __key)
|
||||
{
|
||||
typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
|
||||
__pair_type __res = _Base::equal_range(__key);
|
||||
return std::make_pair(iterator(__res.first, this),
|
||||
iterator(__res.second, this));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& __key) const
|
||||
{
|
||||
std::pair<_Base_const_iterator, _Base_const_iterator>
|
||||
__res = _Base::equal_range(__key);
|
||||
return std::make_pair(const_iterator(__res.first, this),
|
||||
const_iterator(__res.second, this));
|
||||
}
|
||||
|
||||
size_type
|
||||
erase(const key_type& __key)
|
||||
{
|
||||
size_type __ret(0);
|
||||
std::pair<_Base_iterator, _Base_iterator> __pair =
|
||||
_Base::equal_range(__key);
|
||||
for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
|
||||
{
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
_Base::erase(__victim++);
|
||||
++__ret;
|
||||
}
|
||||
return __ret;
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase(__it);
|
||||
_Base_const_iterator __victim = __it.base();
|
||||
this->_M_invalidate_if([__victim](_Base_const_iterator __it)
|
||||
{ return __it == __victim; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__victim](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __victim._M_cur; });
|
||||
return iterator(_Base::erase(__it.base()), this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{ return erase(const_iterator(__it)); }
|
||||
|
||||
iterator
|
||||
erase(const_iterator __first, const_iterator __last)
|
||||
{
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
for (_Base_const_iterator __tmp = __first.base();
|
||||
__tmp != __last.base(); ++__tmp)
|
||||
{
|
||||
_GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
|
||||
_M_message(__gnu_debug::__msg_valid_range)
|
||||
._M_iterator(__first, "first")
|
||||
._M_iterator(__last, "last"));
|
||||
this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
|
||||
{ return __it == __tmp; });
|
||||
this->_M_invalidate_local_if(
|
||||
[__tmp](_Base_const_local_iterator __it)
|
||||
{ return __it._M_cur == __tmp._M_cur; });
|
||||
}
|
||||
return iterator(_Base::erase(__first.base(),
|
||||
__last.base()), this);
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() noexcept { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const noexcept { return *this; }
|
||||
|
||||
private:
|
||||
void
|
||||
_M_invalidate_locals()
|
||||
{
|
||||
_Base_local_iterator __local_end = _Base::end(0);
|
||||
this->_M_invalidate_local_if(
|
||||
[__local_end](_Base_const_local_iterator __it)
|
||||
{ return __it != __local_end; });
|
||||
}
|
||||
|
||||
void
|
||||
_M_invalidate_all()
|
||||
{
|
||||
_Base_iterator __end = _Base::end();
|
||||
this->_M_invalidate_if([__end](_Base_const_iterator __it)
|
||||
{ return __it != __end; });
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
|
||||
void
|
||||
_M_check_rehashed(size_type __prev_count)
|
||||
{
|
||||
if (__prev_count != this->bucket_count())
|
||||
_M_invalidate_locals();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
|
||||
inline void
|
||||
swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
|
||||
unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
|
||||
{ __x.swap(__y); }
|
||||
|
||||
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return __x._M_base() == __y._M_base(); }
|
||||
|
||||
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
|
||||
const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
|
||||
{ return !(__x == __y); }
|
||||
|
||||
} // namespace __debug
|
||||
} // namespace std
|
||||
|
||||
#endif // C++11
|
||||
|
||||
#endif
|
655
contrib/sdk/sources/libstdc++-v3/include/debug/vector
Normal file
655
contrib/sdk/sources/libstdc++-v3/include/debug/vector
Normal file
@@ -0,0 +1,655 @@
|
||||
// Debugging vector implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003-2013 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file debug/vector
|
||||
* This file is a GNU debug extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG_VECTOR
|
||||
#define _GLIBCXX_DEBUG_VECTOR 1
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::vector with safety/checking/debug instrumentation.
|
||||
template<typename _Tp,
|
||||
typename _Allocator = std::allocator<_Tp> >
|
||||
class vector
|
||||
: public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
|
||||
{
|
||||
typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
|
||||
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector>
|
||||
iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector>
|
||||
const_iterator;
|
||||
|
||||
typedef typename _Base::size_type size_type;
|
||||
typedef typename _Base::difference_type difference_type;
|
||||
|
||||
typedef _Tp value_type;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef typename _Base::const_pointer const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// 23.2.4.1 construct/copy/destroy:
|
||||
explicit
|
||||
vector(const _Allocator& __a = _Allocator())
|
||||
: _Base(__a), _M_guaranteed_capacity(0) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
explicit
|
||||
vector(size_type __n, const _Allocator& __a = _Allocator())
|
||||
: _Base(__n, __a), _M_guaranteed_capacity(__n) { }
|
||||
|
||||
vector(size_type __n, const _Tp& __value,
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
|
||||
#else
|
||||
explicit
|
||||
vector(size_type __n, const _Tp& __value = _Tp(),
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
vector(_InputIterator __first, _InputIterator __last,
|
||||
const _Allocator& __a = _Allocator())
|
||||
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
|
||||
__last)),
|
||||
__gnu_debug::__base(__last), __a),
|
||||
_M_guaranteed_capacity(0)
|
||||
{ _M_update_guaranteed_capacity(); }
|
||||
|
||||
vector(const vector& __x)
|
||||
: _Base(__x), _M_guaranteed_capacity(__x.size()) { }
|
||||
|
||||
/// Construction from a release-mode vector
|
||||
vector(const _Base& __x)
|
||||
: _Base(__x), _M_guaranteed_capacity(__x.size()) { }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
vector(vector&& __x) noexcept
|
||||
: _Base(std::move(__x)),
|
||||
_M_guaranteed_capacity(this->size())
|
||||
{
|
||||
this->_M_swap(__x);
|
||||
__x._M_guaranteed_capacity = 0;
|
||||
}
|
||||
|
||||
vector(const vector& __x, const allocator_type& __a)
|
||||
: _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { }
|
||||
|
||||
vector(vector&& __x, const allocator_type& __a)
|
||||
: _Base(std::move(__x), __a),
|
||||
_M_guaranteed_capacity(this->size())
|
||||
{
|
||||
__x._M_invalidate_all();
|
||||
__x._M_guaranteed_capacity = 0;
|
||||
}
|
||||
|
||||
vector(initializer_list<value_type> __l,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _Base(__l, __a),
|
||||
_M_guaranteed_capacity(__l.size()) { }
|
||||
#endif
|
||||
|
||||
~vector() _GLIBCXX_NOEXCEPT { }
|
||||
|
||||
vector&
|
||||
operator=(const vector& __x)
|
||||
{
|
||||
static_cast<_Base&>(*this) = __x;
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
vector&
|
||||
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
|
||||
{
|
||||
__glibcxx_check_self_move_assign(__x);
|
||||
_Base::operator=(std::move(__x));
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
__x._M_invalidate_all();
|
||||
__x._M_guaranteed_capacity = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
vector&
|
||||
operator=(initializer_list<value_type> __l)
|
||||
{
|
||||
static_cast<_Base&>(*this) = __l;
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<typename _InputIterator>
|
||||
#endif
|
||||
void
|
||||
assign(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_valid_range(__first, __last);
|
||||
_Base::assign(__gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
|
||||
void
|
||||
assign(size_type __n, const _Tp& __u)
|
||||
{
|
||||
_Base::assign(__n, __u);
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
assign(initializer_list<value_type> __l)
|
||||
{
|
||||
_Base::assign(__l);
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
#endif
|
||||
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators:
|
||||
iterator
|
||||
begin() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
begin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
iterator
|
||||
end() _GLIBCXX_NOEXCEPT
|
||||
{ return iterator(_Base::end(), this); }
|
||||
|
||||
const_iterator
|
||||
end() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
reverse_iterator
|
||||
rbegin() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
reverse_iterator
|
||||
rend() _GLIBCXX_NOEXCEPT
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const _GLIBCXX_NOEXCEPT
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(_Base::begin(), this); }
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(_Base::end(), this); }
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
// 23.2.4.2 capacity:
|
||||
using _Base::size;
|
||||
using _Base::max_size;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
resize(size_type __sz)
|
||||
{
|
||||
bool __realloc = _M_requires_reallocation(__sz);
|
||||
if (__sz < this->size())
|
||||
this->_M_invalidate_after_nth(__sz);
|
||||
_Base::resize(__sz);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
|
||||
void
|
||||
resize(size_type __sz, const _Tp& __c)
|
||||
{
|
||||
bool __realloc = _M_requires_reallocation(__sz);
|
||||
if (__sz < this->size())
|
||||
this->_M_invalidate_after_nth(__sz);
|
||||
_Base::resize(__sz, __c);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
#else
|
||||
void
|
||||
resize(size_type __sz, _Tp __c = _Tp())
|
||||
{
|
||||
bool __realloc = _M_requires_reallocation(__sz);
|
||||
if (__sz < this->size())
|
||||
this->_M_invalidate_after_nth(__sz);
|
||||
_Base::resize(__sz, __c);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void
|
||||
shrink_to_fit()
|
||||
{
|
||||
if (_Base::_M_shrink_to_fit())
|
||||
{
|
||||
_M_guaranteed_capacity = _Base::capacity();
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
size_type
|
||||
capacity() const _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
#ifdef _GLIBCXX_DEBUG_PEDANTIC
|
||||
return _M_guaranteed_capacity;
|
||||
#else
|
||||
return _Base::capacity();
|
||||
#endif
|
||||
}
|
||||
|
||||
using _Base::empty;
|
||||
|
||||
void
|
||||
reserve(size_type __n)
|
||||
{
|
||||
bool __realloc = _M_requires_reallocation(__n);
|
||||
_Base::reserve(__n);
|
||||
if (__n > _M_guaranteed_capacity)
|
||||
_M_guaranteed_capacity = __n;
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
}
|
||||
|
||||
// element access:
|
||||
reference
|
||||
operator[](size_type __n)
|
||||
{
|
||||
__glibcxx_check_subscript(__n);
|
||||
return _M_base()[__n];
|
||||
}
|
||||
|
||||
const_reference
|
||||
operator[](size_type __n) const
|
||||
{
|
||||
__glibcxx_check_subscript(__n);
|
||||
return _M_base()[__n];
|
||||
}
|
||||
|
||||
using _Base::at;
|
||||
|
||||
reference
|
||||
front()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::front();
|
||||
}
|
||||
|
||||
reference
|
||||
back()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::back();
|
||||
}
|
||||
|
||||
const_reference
|
||||
back() const
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
return _Base::back();
|
||||
}
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 464. Suggestion for new member functions in standard containers.
|
||||
using _Base::data;
|
||||
|
||||
// 23.2.4.3 modifiers:
|
||||
void
|
||||
push_back(const _Tp& __x)
|
||||
{
|
||||
bool __realloc = _M_requires_reallocation(this->size() + 1);
|
||||
_Base::push_back(__x);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Up = _Tp>
|
||||
typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
|
||||
void>::__type
|
||||
push_back(_Tp&& __x)
|
||||
{ emplace_back(std::move(__x)); }
|
||||
|
||||
template<typename... _Args>
|
||||
void
|
||||
emplace_back(_Args&&... __args)
|
||||
{
|
||||
bool __realloc = _M_requires_reallocation(this->size() + 1);
|
||||
_Base::emplace_back(std::forward<_Args>(__args)...);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
pop_back()
|
||||
{
|
||||
__glibcxx_check_nonempty();
|
||||
this->_M_invalidate_if(_Equal(--_Base::end()));
|
||||
_Base::pop_back();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename... _Args>
|
||||
iterator
|
||||
emplace(iterator __position, _Args&&... __args)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
bool __realloc = _M_requires_reallocation(this->size() + 1);
|
||||
difference_type __offset = __position.base() - _Base::begin();
|
||||
_Base_iterator __res = _Base::emplace(__position.base(),
|
||||
std::forward<_Args>(__args)...);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
else
|
||||
this->_M_invalidate_after_nth(__offset);
|
||||
_M_update_guaranteed_capacity();
|
||||
return iterator(__res, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator
|
||||
insert(iterator __position, const _Tp& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
bool __realloc = _M_requires_reallocation(this->size() + 1);
|
||||
difference_type __offset = __position.base() - _Base::begin();
|
||||
_Base_iterator __res = _Base::insert(__position.base(), __x);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
else
|
||||
this->_M_invalidate_after_nth(__offset);
|
||||
_M_update_guaranteed_capacity();
|
||||
return iterator(__res, this);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Up = _Tp>
|
||||
typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
|
||||
iterator>::__type
|
||||
insert(iterator __position, _Tp&& __x)
|
||||
{ return emplace(__position, std::move(__x)); }
|
||||
|
||||
void
|
||||
insert(iterator __position, initializer_list<value_type> __l)
|
||||
{ this->insert(__position, __l.begin(), __l.end()); }
|
||||
#endif
|
||||
|
||||
void
|
||||
insert(iterator __position, size_type __n, const _Tp& __x)
|
||||
{
|
||||
__glibcxx_check_insert(__position);
|
||||
bool __realloc = _M_requires_reallocation(this->size() + __n);
|
||||
difference_type __offset = __position.base() - _Base::begin();
|
||||
_Base::insert(__position.base(), __n, __x);
|
||||
if (__realloc)
|
||||
this->_M_invalidate_all();
|
||||
else
|
||||
this->_M_invalidate_after_nth(__offset);
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<class _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
#else
|
||||
template<class _InputIterator>
|
||||
#endif
|
||||
void
|
||||
insert(iterator __position,
|
||||
_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
__glibcxx_check_insert_range(__position, __first, __last);
|
||||
|
||||
/* Hard to guess if invalidation will occur, because __last
|
||||
- __first can't be calculated in all cases, so we just
|
||||
punt here by checking if it did occur. */
|
||||
_Base_iterator __old_begin = _M_base().begin();
|
||||
difference_type __offset = __position.base() - _Base::begin();
|
||||
_Base::insert(__position.base(), __gnu_debug::__base(__first),
|
||||
__gnu_debug::__base(__last));
|
||||
|
||||
if (_M_base().begin() != __old_begin)
|
||||
this->_M_invalidate_all();
|
||||
else
|
||||
this->_M_invalidate_after_nth(__offset);
|
||||
_M_update_guaranteed_capacity();
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
difference_type __offset = __position.base() - _Base::begin();
|
||||
_Base_iterator __res = _Base::erase(__position.base());
|
||||
this->_M_invalidate_after_nth(__offset);
|
||||
return iterator(__res, this);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __first, iterator __last)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 151. can't currently clear() empty container
|
||||
__glibcxx_check_erase_range(__first, __last);
|
||||
|
||||
if (__first.base() != __last.base())
|
||||
{
|
||||
difference_type __offset = __first.base() - _Base::begin();
|
||||
_Base_iterator __res = _Base::erase(__first.base(),
|
||||
__last.base());
|
||||
this->_M_invalidate_after_nth(__offset);
|
||||
return iterator(__res, this);
|
||||
}
|
||||
else
|
||||
return __first;
|
||||
}
|
||||
|
||||
void
|
||||
swap(vector& __x)
|
||||
#if __cplusplus >= 201103L
|
||||
noexcept(_Alloc_traits::_S_nothrow_swap())
|
||||
#endif
|
||||
{
|
||||
#if __cplusplus >= 201103L
|
||||
if (!_Alloc_traits::_S_propagate_on_swap())
|
||||
__glibcxx_check_equal_allocs(__x);
|
||||
#endif
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
|
||||
}
|
||||
|
||||
void
|
||||
clear() _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
_Base::clear();
|
||||
this->_M_invalidate_all();
|
||||
_M_guaranteed_capacity = 0;
|
||||
}
|
||||
|
||||
_Base&
|
||||
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
const _Base&
|
||||
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
|
||||
|
||||
private:
|
||||
size_type _M_guaranteed_capacity;
|
||||
|
||||
bool
|
||||
_M_requires_reallocation(size_type __elements)
|
||||
{ return __elements > this->capacity(); }
|
||||
|
||||
void
|
||||
_M_update_guaranteed_capacity()
|
||||
{
|
||||
if (this->size() > _M_guaranteed_capacity)
|
||||
_M_guaranteed_capacity = this->size();
|
||||
}
|
||||
|
||||
void
|
||||
_M_invalidate_after_nth(difference_type __n)
|
||||
{
|
||||
typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
|
||||
this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator==(const vector<_Tp, _Alloc>& __lhs,
|
||||
const vector<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() == __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator!=(const vector<_Tp, _Alloc>& __lhs,
|
||||
const vector<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() != __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<(const vector<_Tp, _Alloc>& __lhs,
|
||||
const vector<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() < __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator<=(const vector<_Tp, _Alloc>& __lhs,
|
||||
const vector<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() <= __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>=(const vector<_Tp, _Alloc>& __lhs,
|
||||
const vector<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() >= __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline bool
|
||||
operator>(const vector<_Tp, _Alloc>& __lhs,
|
||||
const vector<_Tp, _Alloc>& __rhs)
|
||||
{ return __lhs._M_base() > __rhs._M_base(); }
|
||||
|
||||
template<typename _Tp, typename _Alloc>
|
||||
inline void
|
||||
swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
|
||||
{ __lhs.swap(__rhs); }
|
||||
|
||||
} // namespace __debug
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// DR 1182.
|
||||
/// std::hash specialization for vector<bool>.
|
||||
template<typename _Alloc>
|
||||
struct hash<__debug::vector<bool, _Alloc>>
|
||||
: public __hash_base<size_t, __debug::vector<bool, _Alloc>>
|
||||
{
|
||||
size_t
|
||||
operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
|
||||
{ return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
|
||||
(__b._M_base()); }
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user