__x.swap(__y); } template void swap(multiset<_Key, _Compare, _Allocator>& __x, multiset<_Key, _Compare, _Allocator>&& __y) { return __x.swap(__y); } #endif } // namespace __debug } // namespace std #endif // Debugging support implementation -*- C++ -*- // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 // 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 2, 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. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @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 #include // for ptrdiff_t #include // for iterator_traits, categories #include // for __is_integer namespace __gnu_debug { template 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 inline bool __check_singular(_Iterator& __x) { return __check_singular_aux(&__x); } /** Non-NULL pointers are nonsingular. */ template inline bool __check_singular(const _Tp* __ptr) { return __ptr == 0; } /** Safe iterators know if they are singular. */ template 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 inline bool __check_dereferenceable(_Iterator&) { return true; } /** Non-NULL pointers are dereferenceable. */ template inline bool __check_dereferenceable(const _Tp* __ptr) { return __ptr; } /** Safe iterators know if they are singular. */ template 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 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 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 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 inline bool __valid_range_aux(const _InputIterator& __first, const _InputIterator& __last, std::__false_type) { typedef typename std::iterator_traits<_InputIterator>::iterator_category _Category; return __valid_range_aux2(__first, __last, _Category()); } /** 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 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 inline bool __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, const _Safe_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 inline _InputIterator __check_valid_range(const _InputIterator& __first, const _InputIterator& __last __attribute__((__unused__))) { _GLIBCXX_DEBUG_ASSERT(__valid_range(__first, __last)); return __first; } /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ template inline const _CharT* __check_string(const _CharT* __s, const _Integer& __n __attribute__((__unused__))) { #ifdef _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); #endif return __s; } /** Checks that __s is non-NULL and then returns __s. */ template inline const _CharT* __check_string(const _CharT* __s) { #ifdef _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG_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 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 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; } // Can't check if an input iterator sequence is sorted, because we can't step // through the sequence. template 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 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; } // Determine if a sequence is sorted. template inline bool __check_sorted(const _InputIterator& __first, const _InputIterator& __last) { typedef typename std::iterator_traits<_InputIterator>::iterator_category _Category; // Verify that the < operator for elements in the sequence is a // StrictWeakOrdering by checking that it is irreflexive. _GLIBCXX_DEBUG_ASSERT(__first == __last || !(*__first < *__first)); return __check_sorted_aux(__first, __last, _Category()); } template inline bool __check_sorted(const _InputIterator& __first, const _InputIterator& __last, _Predicate __pred) { typedef typename std::iterator_traits<_InputIterator>::iterator_category _Category; // Verify that the predicate is StrictWeakOrdering by checking that it // is irreflexive. _GLIBCXX_DEBUG_ASSERT(__first == __last || !__pred(*__first, *__first)); return __check_sorted_aux(__first, __last, __pred, _Category()); } template inline bool __check_sorted_set_aux(const _InputIterator& __first, const _InputIterator& __last, std::__true_type) { return __check_sorted(__first, __last); } template inline bool __check_sorted_set_aux(const _InputIterator&, const _InputIterator&, std::__false_type) { return true; } template inline bool __check_sorted_set_aux(const _InputIterator& __first, const _InputIterator& __last, _Predicate __pred, std::__true_type) { return __check_sorted(__first, __last, __pred); } template 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 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 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()); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 270. Binary search requirements overly strict // Determine if a sequence is partitioned w.r.t. this element. template inline bool __check_partitioned_lower(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { while (__first != __last && *__first < __value) ++__first; while (__first != __last && !(*__first < __value)) ++__first; return __first == __last; } template inline bool __check_partitioned_upper(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { while (__fÎ"Ï"irst != __last && !(__value < *__first)) ++__first; while (__first != __last && __value < *__first) ++__first; return __first == __last; } // Determine if a sequence is partitioned w.r.t. this element. template inline bool __check_partitioned_lower(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Pred __pred) { while (__first != __last && bool(__pred(*__first, __value))) ++__first; while (__first != __last && !bool(__pred(*__first, __value))) ++__first; return __first == __last; } template inline bool __check_partitioned_upper(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Pred __pred) { while (__first != __last && !bool(__pred(__value, *__first))) ++__first; while (__first != __last && bool(__pred(__value, *__first))) ++__first; return __first == __last; } } // namespace __gnu_debug #endif // Safe sequence/iterator base implementation -*- C++ -*- // Copyright (C) 2003, 2004, 2005, 2006 // 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 2, 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. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @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 namespace __gnu_debug { class _Safe_sequence_base; /** \brief Basic functionality for 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(); 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); /** Detach the iterator for whatever sequence it is attached to, * if any. */ void _M_detach(); /** Likewise, but not thread-safe. */ void _M_detach_single(); /** 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? */ bool _M_singular() const; /** Can we compare this iterator to the given iterator @p __x? Returns true if both iterators are nonsingular and reference the same sequence. */ bool _M_can_compare(const _Safe_iterator_base& __x) const; }; /** * @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 "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(); public: /** Invalidates all iterators. */ void _M_invalidate_all() const { if (++_M_version == 0) _M_version = 1; } }; } // namespace __gnu_debug #endif // Safe associated container base class implementation -*- C++ -*- // Copyright (C) 2007 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 2, 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. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @file debug/safe_association.h * This file is a GNU debug extension to the Standard C++ Library. */ #ifndef _GLIBCXX_DEBUG_SAFE_ASSOCIATION_H #define _GLIBCXX_DEBUG_SAFE_ASSOCIATION_H 1 #include #include #include #include #include namespace __gnu_debug { /** * @brief Base class for constructing a "safe" associated container type. * * The class template %_Safe_association simplifies the construction of * "safe" associated containers. */ template class _Safe_association : public _Base { 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 typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __gnu_debug::_Safe_iterator iterator; typedef __gnu_debug::_Safe_iterator const_iterator; _Safe_association() { } explicit _Safe_association(size_type __n) : _Base(__n) { } _Safe_association(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } _Safe_association(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } template _Safe_association(_InputIter __f, _InputIter __l) : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } template _Safe_association(_InputIter __f, _InputIter __l, size_type __n) : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } template _Safe_association(_InputIter __f, _InputIter __l, size_type __n, const hasher& __hf) : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } template _Safe_association(_InputIter __f, _InputIter __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, __eql, __a) { } _Safe_association(const _Base& __x) : _Base(__x) { } _Safe_association(_Safe_association&& __x) : _Base(std::forward<_Base>(__x)) { } using _Base::size; using _Base::max_size; using _Base::empty; using _Base::get_allocator; using _Base::key_eq; using _Base::count; using _Base::bucket_count; using _Base::max_bucket_count; using _Base::bucket; using _Base::bucket_size; using _Base::load_factor; const_iterator begin() const { return const_iterator(_Base::begin(), this); } const_iterator end() const { return const_iterator(_Base::end(), this); } std::pair insert(const value_type& __obj) { typedef std::pair __pair_type; __pair_type __res = _Base::insert(__obj); return std::make_pair(iterator(__res.first, this), __res.second); } void insert(const value_type* __first, const value_type* __last) { __glibcxx_check_valid_range(__first, __last); _Base::insert(__first, __last); } template void insert(_InputIter __first, _InputIter __last) { __glibcxx_check_valid_range(__first, __last); _Base::insert(__first.base(), __last.base()); } const_iterator find(const key_type& __key) const { return const_iterator(_Base::find(__key), this); } std::pair equal_range(const key_type& __key) const { typedef typename _Base::const_iterator _Base_iterator; typedef std::pair<_Base_iterator, _Base_iterator> __pair_type; __pair_type __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); iterator __victim(_Base::find(__key), this); if (__victim != end()) { this->erase(__victim); __ret = 1; } return __ret; } iterator erase(iterator __it) { __glibcxx_check_erase(__it); __it._M_invalidate(); return iterator(_Base::erase(__it.base())); } iterator erase(iterator __first, iterator __last) { __glibcxx_check_erase_range(__first, __last); for (iterator __tmp = __first; __tmp != __last;) { iterator __victim = __tmp++; __victim._M_invalidate(); } return iterator(_Base::erase(__first.base(), __last.base())); } _Base& _M_base() { return *this; } const _Base& _M_base() const { return *this; } }; } // namespace __gnu_debug #endif // Debugging vector implementation -*- C++ -*- // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 // 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 2, 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. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @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 #include #include #include namespace std { namespace __debug { template > class vector : public _GLIBCXX_STD_D::vector<_Tp, _Allocator>, public __gnu_debug::_Safe_sequence > { typedef _GLIBCXX_STD_D::vector<_Tp, _Allocator> _Base; typedef __gnu_debug::_Safe_sequence _Safe_base; typedef typename _Base::const_iterator _Base_const_iterator; typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; public: typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __gnu_debug::_Safe_iterator iterator; typedef __gnu_debug::_Safe_iterator 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 reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; // 23.2.4.1 construct/copy/destroy: explicit vector(const _Allocator& __a = _Allocator()) : _Base(__a), _M_guaranteed_capacity(0) { } explicit vector(size_type __n, const _Tp& __value = _Tp(), const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } template vector(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a), _M_guaranteed_capacity(0) { _M_update_guaranteed_capacity(); } vector(const vector& __x) : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } /// Construction from a release-mode vector vector(const _Base& __x) : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } #ifdef __GXX_EXPERIMENTAL_CXX0X__ vector(vector&& __x) : _Base(std::forward(__x)), _Safe_base(), _M_guaranteed_capacity(this->size()) { this->_M_swap(__x); __x._M_guaranteed_capacity = 0; } #endif ~vector() { } vector& operator=(const vector& __x) { static_cast<_Base&>(*this) = __x; this->_M_invalidate_all(); _M_update_guaranteed_capacity(); return *this; } #ifdef __GXX_EXPERIMENTAL_CXX0X__ vector& operator=(vector&& __x) { // NB: DR 675. clear(); swap(__x); return *this; } #endif template void assign(_InputIterator __first, _InputIterator __last) { __glibcxx_check_valid_range(__first, __last); _Base::assign(__first, __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(); } using _Base::get_allocator; // iterators: iterator begin() { return iterator(_Base::begin(), this); } const_iterator begin() const { return const_iterator(_Base::begin(), this); } iterator end() { return iterator(_Base::end(), this); } const_iterator end() const { return const_iterator(_Base::end(), this); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ const_iterator cbegin() const { return const_iterator(_Base::begin(), this); } const_iterator cend() const { return const_iterator(_Base::end(), this); } const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } #endif // 23.2.4.2 capacity: using _Base::size; using _Base::max_size; void resize(size_type __sz, _Tp __c = _Tp()) { bool __realloc = _M_requires_reallocation(__sz); if (__sz < this->size()) this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); _Base::resize(__sz, __c); if (__realloc) this->_M_invalidate_all(); } using _Base::capacity; 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: #ifndef __GXX_EXPERIMENTAL_CXX0X__ 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(); } #else template void push_back(_Args&&... __args) { bool __realloc = _M_requires_reallocation(this->size() + 1); _Base::push_back(std::forward<_Args>(__args)...); if (__realloc) this->_M_invalidate_all(); _M_update_guaranteed_capacity(); } #endif void pop_back() { __glibcxx_check_nonempty(); iterator __victim = end() - 1; __victim._M_invalidate(); _Base::pop_back(); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ template iterator emplace(iterator __position, _Args&&... __args) { __glibcxx_check_insert(__position); bool __realloc = _M_requires_reallocation(this->size() + 1); difference_type __offset = __position - begin(); typename _Base::iterator __res = _Base::emplace(__position.base(), std::forward<_Args>(__args)...); if (__realloc) this->_M_invalidate_all(); else this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); _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 - begin(); typename _Base::iterator __res = _Base::insert(__position.base(),__x); if (__realloc) this->_M_invalidate_all(); else this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); _M_update_guaranteed_capacity(); return iterator(__res, this); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ iterator insert(iterator __position, _Tp&& __x) { return emplace(__position, std::move(__x)); } #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 - begin(); _Base::insert(__position.base(), __n, __x); if (__realloc) this->_M_invalidate_all(); else this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); _M_update_guaranteed_capacity(); } template 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. */ typename _Base::iterator __old_begin = _M_base().begin(); difference_type __offset = __position - begin(); _Base::insert(__position.base(), __first, __last); if (_M_base().begin() != __old_begin) this->_M_invalidate_all(); else this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); _M_update_guaranteed_capacity(); } iterator erase(iterator __position) { __glibcxx_check_erase(__position); difference_type __offset = __position - begin(); typename _Base::iterator __res = _Base::erase(__position.base()); this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); 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); difference_type __offset = __first - begin(); typename _Base::iterator __res = _Base::erase(__first.base(), __last.base()); this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); return iterator(__res, this); } void #ifdef __GXX_EXPERIMENTAL_CXX0X__ swap(vector&& __x) #else swap(vector& __x) #endif { _Base::swap(__x); this->_M_swap(__x); std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); } void clear() { _Base::clear(); this->_M_invalidate_all(); _M_guaranteed_capacity = 0; } _Base& _M_base() { return *this; } const _Base& _M_base() const { return *this; } private: size_type _M_guaranteed_capacity; bool _M_requires_reallocation(size_type __elements) { #í"î"ifdef _GLIBCXX_DEBUG_PEDANTIC return __elements > this->capacity(); #else return __elements > _M_guaranteed_capacity; #endif } void _M_update_guaranteed_capacity() { if (this->size() > _M_guaranteed_capacity) _M_guaranteed_capacity = this->size(); } }; template inline bool operator==(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() == __rhs._M_base(); } template inline bool operator!=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() != __rhs._M_base(); } template inline bool operator<(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() < __rhs._M_base(); } template inline bool operator<=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() <= __rhs._M_base(); } template inline bool operator>=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() >= __rhs._M_base(); } template inline bool operator>(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() > __rhs._M_base(); } template inline void swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) { __lhs.swap(__rhs); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ template inline void swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs) { __lhs.swap(__rhs); } template inline void swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs) { __lhs.swap(__rhs); } #endif } // namespace __debug } // namespace std #endif // Debugging iterator implementation (out of line) -*- C++ -*- // Copyright (C) 2003, 2004, 2005, 2006, 2007 // 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 2, 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. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @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 bool _Safe_iterator<_Iterator, _Sequence>:: _M_can_advance(const difference_type& __n) const { typedef typename _Sequence::const_iterator const_iterator; if (this->_M_singular()) return false; if (__n == 0) return true; if (__n < 0) { const_iterator __begin = static_cast(_M_sequence)->begin(); std::pair __dist = this->_M_get_distance(__begin, *this); bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n) || (__dist.second != __dp_exact && __dist.first > 0)); return __ok; } else { const_iterator __end = static_cast(_M_sequence)->end(); std::pair __dist = this->_M_get_distance(*this, __end); bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n) || (__dist.second != __dp_exact && __dist.first > 0)); return __ok; } } template template 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 __dist = this->_M_get_distance(*this, __rhs); 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. */ if (_M_is_begin() || __rhs._M_is_end()) return true; else 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; } template void _Safe_iterator<_Iterator, _Sequence>:: _M_invalidate() { __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); _M_invalidate_single(); } template void _Safe_iterator<_Iterator, _Sequence>:: _M_invalidate_single() { typedef typename _Sequence::iterator iterator; typedef typename _Sequence::const_iterator const_iterator; if (!this->_M_singular()) { for (_Safe_iterator_base* __iter = _M_sequence->_M_iterators; __iter; __iter = __iter->_M_next) { iterator* __victim = static_cast(__iter); if (this->base() == __victim->base()) __victim->_M_version = 0; } for (_Safe_iterator_base* __iter2 = _M_sequence->_M_const_iterators; __iter2; __iter2 = __iter2->_M_next) { const_iterator* __victim = static_cast(__iter2); if (__victim->base() == this->base()) __victim->_M_version = 0; } _M_version = 0; } } } // namespace __gnu_debug #endif 9 . ..:èbits: .9 ..;time_members.h< stdtr1c++.h= gthr-tpf.h>extc++.h? os_defines.h@ ctype_base.hActype_noninline.hBctype_inline.hCgthr.hD c++config.hE c++locale.hF cpu_defines.hGc++io.hH gthr-posix.hIc++allocator.hJstdc++.hKgthr-default.hL gthr-single.hM basic_file.hNmessages_members.hOcxxabi_tweaks.hP( atomic_word.h// std::time_get, std::time_put implementation, generic version -*- C++ -*- // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 // 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 2, 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. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @file time_members.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. */ // // ISO C++ 14882: 22.2.5.1.2 - time_get functions // ISO C++ 14882: 22.2.5.3.2 - time_put functions // // Written by Benjamin Kosnik _GLIBCXX_BEGIN_NAMESPACE(std) template __timepunct<_CharT>::__timepunct(size_t __refs) : facet(__refs), _M_data(NULL) { _M_name_timepunct = _S_get_c_name(); _M_initialize_timepunct(); } template __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) : facet(__refs), _M_data(__cache) { _M_name_timepunct = _S_get_c_name(); _M_initialize_timepunct(); } template __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s, size_t __refs) : facet(__refs), _M_data(NULL) { if (__builtin_strcmp(__s, _S_get_c_name()) != 0) { const size_t __len = __builtin_strlen(__s) + 1; char* __tmp = new char[__len]; __builtin_memcpy(__tmp, __s, __len); _M_name_timepunct = __tmp; } else _M_name_timepunct = _S_get_c_name(); try { _M_initialize_timepunct(__cloc); } catch(...) { if (_M_name_timepunct != _S_get_c_name()) delete [] _M_name_timepunct; __throw_exception_again; } } template __timepunct<_CharT>::~__timepunct() { if (_M_name_timepunct != _S_get_c_name()) delete [] _M_name_timepunct; delete _M_data; _S_destroy_c_locale(_M_c_locale_timepunct); } _GLIBCXX_END_NAMESPACE // C++ includes used for precompiling TR1 -*- C++ -*- // Copyright (C) 2006 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 2, 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. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @file stdtr1c++.h * This is an implementation file for a precompiled header. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Threads compatibility routines for libgcc2 and libobjc. Compile this one with gcc. Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, if you link this library with other files, some of which are compiled with GCC, to produce an executable, this library does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* TPF needs its own version of gthr-*.h because TPF always links to the thread library. However, for performance reasons we still do not want to issue thread api calls unless a check is made to see that we are running as a thread. */ #ifndef _GLIBCXX_GCC_GTHR_TPF_H #define _GLIBCXX_GCC_GTHR_TPF_H /* POSIX threads specific definitions. Easy, since the interface is just one-to-one mapping. */ #define __GTHREADS 1 /* Some implementations of require this to be defined. */ #ifndef _REENTRANT #define _REENTRANT 1 #endif #include #include typedef pthread_key_t __gthread_key_t; typedef pthread_once_t __gthread_once_t; typedef pthread_mutex_t __gthread_mutex_t; typedef pthread_mutex_t __gthread_recursive_mutex_t; #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP #endif #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #define NOTATHREAD 00 #define ECBBASEPTR (unsigned long int) *(unsigned int *)0x00000514u #define ECBPG2PTR ECBBASEPTR + 0x1000 #define CE2THRCPTR *((unsigned char *)(ECBPG2PTR + 16)) #define __tpf_pthread_active() (CE2THRCPTR != NOTATHREAD) #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK # define __gthrw(name) \ static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))); # define __gthrw_(name) __gthrw_ ## name #else # define __gthrw(name) # define __gthrw_(name) name #endif __gthrw(pthread_once) __gthrw(pthread_key_create) __gthrw(pthread_key_delete) __gthrw(pthread_getspec