Index: include/ext/throw_allocator.h =================================================================== --- include/ext/throw_allocator.h (revisão 88) +++ include/ext/throw_allocator.h (cópia de trabalho) @@ -221,6 +221,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) construct(pointer p, const T& val) { return std::allocator().construct(p, val); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(pointer p, U&& val) + { return std::allocator().construct(p, val); } +#endif + void destroy(pointer p) { std::allocator().destroy(p); } Index: include/ext/pool_allocator.h =================================================================== --- include/ext/pool_allocator.h (revisão 88) +++ include/ext/pool_allocator.h (cópia de trabalho) @@ -166,6 +166,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) construct(pointer __p, const _Tp& __val) { ::new(__p) _Tp(__val); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(pointer __p, _U&& __val) + { ::new(__p) _Tp(std::forward<_U>(__val)); } +#endif + void destroy(pointer __p) { __p->~_Tp(); } Index: include/ext/bitmap_allocator.h =================================================================== --- include/ext/bitmap_allocator.h (revisão 88) +++ include/ext/bitmap_allocator.h (cópia de trabalho) @@ -1091,6 +1091,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) construct(pointer __p, const_reference __data) { ::new(__p) value_type(__data); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(pointer __p, _U&& __val) + { ::new(__p) _Tp(std::forward<_U>(__val)); } +#endif + void destroy(pointer __p) { __p->~value_type(); } Index: include/ext/new_allocator.h =================================================================== --- include/ext/new_allocator.h (revisão 88) +++ include/ext/new_allocator.h (cópia de trabalho) @@ -106,6 +106,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) construct(pointer __p, const _Tp& __val) { ::new(__p) _Tp(__val); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(pointer __p, _U&& __val) + { ::new(__p) _Tp(std::forward<_U>(__val)); } +#endif + void destroy(pointer __p) { __p->~_Tp(); } }; Index: include/ext/malloc_allocator.h =================================================================== --- include/ext/malloc_allocator.h (revisão 88) +++ include/ext/malloc_allocator.h (cópia de trabalho) @@ -110,6 +110,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) construct(pointer __p, const _Tp& __val) { ::new(__p) value_type(__val); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(pointer __p, _U& __val) + { ::new(__p) _Tp(std::forward<_U>(__val)); } +#endif + void destroy(pointer __p) { __p->~_Tp(); } }; Index: include/ext/mt_allocator.h =================================================================== --- include/ext/mt_allocator.h (revisão 88) +++ include/ext/mt_allocator.h (cópia de trabalho) @@ -595,6 +595,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) construct(pointer __p, const _Tp& __val) { ::new(__p) _Tp(__val); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(pointer __p, _U&& __val) + { ::new(__p) _Tp(std::forward<_U>(__val)); } +#endif + void destroy(pointer __p) { __p->~_Tp(); } }; Index: include/bits/stl_algobase.h =================================================================== --- include/bits/stl_algobase.h (revisão 88) +++ include/bits/stl_algobase.h (cópia de trabalho) @@ -94,11 +94,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std) swap(_Tp& __a, _Tp& __b) { // concept requirements +#ifndef __GXX_EXPERIMENTAL_CXX0X__ __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) _Tp __tmp = __a; __a = __b; __b = __tmp; +#else + __glibcxx_function_requires(_MoveConstructibleConcept<_Tp>) + __glibcxx_function_requires(_MoveAssignableConcept<_Tp>) + + _Tp __tmp(move(__a)); + __a = move(__b); + __b = move(__tmp); +#endif } // See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a @@ -113,9 +122,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType1; - _ValueType1 __tmp = *__a; - *__a = *__b; - *__b = __tmp; + _ValueType1 __tmp = __move(*__a); + *__a = __move(*__b); + *__b = __move(__tmp); } }; @@ -252,6 +261,30 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __a; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline _OutputIterator + move(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + for (; __first != __last; ++__result, ++__first) + *__result = move(*__first); + return __result; + } + + template + inline _OutputIterator + move_backward(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + while (__first != __last) + *--__result = move(*--__last); + return __result; + } + +#endif + // All of these auxiliary structs serve two purposes. (1) Replace // calls to copy with memmove whenever possible. (Memmove, not memcpy, // because the input and output ranges are permitted to overlap.) @@ -642,6 +675,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std) std::__fill_normal<__fi>::__fill_n(__first, __last, __value); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline void + fill(_ForwardIterator __first, _ForwardIterator __last) + { + for (; __first != __last; ++__first) + *__first = _Tp(); + } + +#endif template struct __fill_n @@ -752,6 +796,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return std::__fill_n_normal<__oi>::__fill_n_n(__first, __n, __value); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline _OutputIterator + fill_n(_OutputIterator __first, _Size __n) + { + for (; __n > 0; --__n, ++__first) + *__first = _Tp(); + return __first; + } + +#endif + /** * @brief Finds the places in ranges which don't match. * @param first1 An input iterator. Index: include/bits/basic_string.h =================================================================== --- include/bits/basic_string.h (revisão 88) +++ include/bits/basic_string.h (cópia de trabalho) @@ -261,6 +261,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _Alloc_hider(_CharT* __dat, const _Alloc& __a) : _Alloc(__a), _M_p(__dat) { } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + _Alloc_hider(_CharT* __dat, _Alloc&& __a) + : _Alloc(move(__a)), _M_p(__dat) { } +#endif + _CharT* _M_p; // The actual data. }; @@ -436,6 +441,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @param str Source string. */ basic_string(const basic_string& __str); + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + basic_string(basic_string&& __str); +#endif + /** * @brief Construct string as copy of a substring. * @param str Source string. @@ -503,6 +513,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator=(const basic_string& __str) { return this->assign(__str); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + basic_string& + operator=(basic_string&& __str) + { + this->swap(__str); + return *this; + } +#endif + /** * @brief Copy contents of @a s into this string. * @param s Source null-terminated string. @@ -886,6 +905,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) basic_string& assign(const basic_string& __str); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + basic_string& + assign(basic_string&& __str) + { + this->swap(__str); + return *this; + } +#endif + /** * @brief Set value to a substring of a string. * @param str The string to use. @@ -1522,7 +1550,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * time. */ void +#ifndef __GXX_EXPERIMENTAL_CXX0X__ swap(basic_string& __s); +#else + swap(basic_string&& __s); +#endif // String operations: /** @@ -2089,6 +2121,32 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __str; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + basic_string<_CharT, _Traits, _Alloc>&& + operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + return __lhs.append(__rhs); + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + basic_string<_CharT, _Traits, _Alloc>&& __rhs) + { + return __rhs.append(__lhs); + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, + basic_string<_CharT, _Traits, _Alloc>&& __rhs) + { + return __lhs.append(__rhs); + } +#endif + /** * @brief Concatenate C string and string. * @param lhs First string. @@ -2100,6 +2158,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator+(const _CharT* __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(const _CharT* __lhs, + basic_string<_CharT,_Traits,_Alloc>&& __rhs) + { + return __rhs.insert(0, __lhs); + } +#endif + /** * @brief Concatenate character and string. * @param lhs First string. @@ -2110,6 +2178,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) basic_string<_CharT,_Traits,_Alloc> operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Alloc>&& __rhs) + { + return __rhs.insert(0, 1, __lhs); + } +#endif + /** * @brief Concatenate string and C string. * @param lhs First string. @@ -2126,6 +2203,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __str; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, + const _CharT* __rhs) + { + return __lhs.append(__rhs); + } +#endif + /** * @brief Concatenate string and character. * @param lhs First string. @@ -2143,6 +2230,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __str; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, _CharT __rhs) + { + return __lhs.append(1, __rhs); + } +#endif + // operator == /** * @brief Test equivalence of two strings. @@ -2378,6 +2474,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std) basic_string<_CharT, _Traits, _Alloc>& __rhs) { __lhs.swap(__rhs); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + inline void + swap(basic_string<_CharT, _Traits, _Alloc>&& __lhs, + basic_string<_CharT, _Traits, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + template + inline void + swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, + basic_string<_CharT, _Traits, _Alloc>&& __rhs) + { __lhs.swap(__rhs); } +#endif + /** * @brief Read stream into a string. * @param is Input stream. Index: include/bits/stl_pair.h =================================================================== --- include/bits/stl_pair.h (revisão 88) +++ include/bits/stl_pair.h (cópia de trabalho) @@ -61,6 +61,8 @@ #ifndef _PAIR_H #define _PAIR_H 1 +#include + _GLIBCXX_BEGIN_NAMESPACE(std) /// pair holds two objects of arbitrary type. @@ -84,10 +86,49 @@ _GLIBCXX_BEGIN_NAMESPACE(std) pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) { } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + pair(_U1&& __x, _U2&& __y) + : first(forward<_U1>(__x)), second(forward<_U2>(__y)) { } + + pair(pair&& __p) + : first(move(__p.first)), second(move(__p.second)) { } +#endif + /** There is also a templated copy ctor for the @c pair class itself. */ template pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) { } + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + pair(pair<_U1, _U2>&& __p) + : first(move(__p.first)), second(move(__p.second)) { } + + pair& + operator=(pair&& __p) + { + first = move(__p.first); + second = move(__p.second); + return *this; + } + + template + pair& + operator=(pair&& __p) + { + first = move(__p.first); + second = move(__p.second); + return *this; + } + + void + swap(pair&& __p) + { + swap(first, __p.first); + swap(second, __p.second); + } +#endif }; /// Two pairs of the same type are equal iff their members are equal. @@ -127,6 +168,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__x < __y); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) + { __x.swap(__y); } + + template + void + swap(pair<_T1, _T2>&& __x, pair<_T1, _T2>& __y) + { __x.swap(__y); } + + template + void + swap(pair<_T1, _T2>& __x, pair<_T1, _T2>&& __y) + { __x.swap(__y); } +#endif + /** * @brief A convenience wrapper for creating a pair from two objects. * @param x The first object. Index: include/bits/stl_vector.h =================================================================== --- include/bits/stl_vector.h (revisão 88) +++ include/bits/stl_vector.h (cópia de trabalho) @@ -160,7 +160,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL { // Concept requirements. typedef typename _Alloc::value_type _Alloc_value_type; +#ifndef __GXX_EXPERIMENTAL_CXX0X__ __glibcxx_class_requires(_Tp, _SGIAssignableConcept) +#else + __glibcxx_class_requires(_Tp, _MoveConstructibleConcept) + __glibcxx_class_requires(_Tp, _MoveAssignableConcept) +#endif __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) typedef _Vector_base<_Tp, _Alloc> _Base; @@ -199,6 +204,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL : _Base(__a) { } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + explicit + vector(size_type __n, const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { + std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = this->_M_impl._M_start + __n; + } + +#endif + /** * @brief Create a %vector with copies of an exemplar element. * @param n The number of elements to initially create. @@ -206,8 +224,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * * This constructor fills the %vector with @a n copies of @a value. */ +#ifndef __GXX_EXPERIMENTAL_CXX0X__ explicit vector(size_type __n, const value_type& __value = value_type(), +#else + vector(size_type __n, const value_type& __value, +#endif const allocator_type& __a = allocator_type()) : _Base(__n, __a) { @@ -233,6 +255,16 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL _M_get_Tp_allocator()); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + vector(vector&& __x) + : _Base(__x._M_get_Tp_allocator()) + { + swap(__x); + } + +#endif + /** * @brief Builds a %vector from a range. * @param first An input iterator. @@ -279,6 +311,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL vector& operator=(const vector& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + vector& + operator=(vector&& __x) + { + swap(__x); + return *this; + } + +#endif + /** * @brief Assigns a given value to a %vector. * @param n Number of elements to be assigned. @@ -401,6 +444,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL max_size() const { return _M_get_Tp_allocator().max_size(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + void + resize(size_type __new_size) + { + if (__new_size < size()) + _M_erase_at_end(this->_M_impl._M_start + __new_size); + else + _M_fill_insert(end(), __new_size - size()); + } + +#endif + /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. @@ -413,7 +469,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * given data. */ void +#ifndef __GXX_EXPERIMENTAL_CXX0X__ resize(size_type __new_size, value_type __x = value_type()) +#else + resize(size_type __new_size, value_type __x) +#endif { if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); @@ -605,6 +665,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL _M_insert_aux(end(), __x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + void + push_back(value_type&& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + this->_M_impl.construct(this->_M_impl._M_finish, move(__x)); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(end(), move(__x)); + } + +#endif + /** * @brief Removes last element. * @@ -635,6 +711,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL iterator insert(iterator __position, const value_type& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + iterator + insert(iterator __position, value_type&& __x); +#endif + /** * @brief Inserts a number of copies of given data into the %vector. * @param position An iterator into the %vector. @@ -907,10 +988,20 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + void + _M_fill_insert(iterator __pos, size_type __n); +#endif + // Called by insert(p,x) void _M_insert_aux(iterator __position, const value_type& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + void + _M_insert_aux(iterator __position, value_type&& __x); +#endif + // Internal erase functions follow. // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, @@ -987,6 +1078,20 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) { __x.swap(__y); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline void + swap(vector<_Tp, _Alloc>&& __x, vector<_Tp, _Alloc>& __y) + { __x.swap(__y); } + + template + inline void + swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>&& __y) + { __x.swap(__y); } + +#endif + _GLIBCXX_END_NESTED_NAMESPACE #endif /* _VECTOR_H */ Index: include/bits/stl_deque.h =================================================================== --- include/bits/stl_deque.h (revisão 88) +++ include/bits/stl_deque.h (cópia de trabalho) @@ -630,7 +630,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL { // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; +#ifndef __GXX_EXPERIMENTAL_CXX0X__ __glibcxx_class_requires(_Tp, _SGIAssignableConcept) +#else + __glibcxx_class_requires(_Tp, _MoveConstructibleConcept) + __glibcxx_class_requires(_Tp, _MoveAssignableConcept) +#endif __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) typedef _Deque_base<_Tp, _Alloc> _Base; @@ -683,6 +688,13 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL deque(const allocator_type& __a = allocator_type()) : _Base(__a, 0) {} +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + explicit + deque(size_type __n, const allocator_type& __a = allocator_type()) + : _Base(__a, __n) + { _M_fill_initialize(); } +#endif + /** * @brief Create a %deque with copies of an exemplar element. * @param n The number of elements to initially create. @@ -690,8 +702,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * * This constructor fills the %deque with @a n copies of @a value. */ +#ifndef __GXX_EXPERIMENTAL_CXX0X__ explicit deque(size_type __n, const value_type& __value = value_type(), +#else + deque(size_type __n, const value_type& __value, +#endif const allocator_type& __a = allocator_type()) : _Base(__a, __n) { _M_fill_initialize(__value); } @@ -709,6 +725,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL this->_M_impl._M_start, _M_get_Tp_allocator()); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + deque(deque&& __x) + : _Base(__x._M_get_Tp_allocator(), __x.size()) + { + swap(__x); + } +#endif + /** * @brief Builds a %deque from a range. * @param first An input iterator. @@ -751,6 +775,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL deque& operator=(const deque& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + deque& + operator=(deque&& __x) + { + swap(__x); + } +#endif + /** * @brief Assigns a given value to a %deque. * @param n Number of elements to be assigned. @@ -872,6 +904,20 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL max_size() const { return _M_get_Tp_allocator().max_size(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + void + resize(size_type __new_size) + { + const size_type __len = size(); + if (__new_size < __len) + _M_erase_at_end(this->_M_impl._M_start + difference_type(__new_size)); + else + _M_insert_aux(this->_M_impl._M_finish, __new_size - __len); + } + +#endif + /** * @brief Resizes the %deque to the specified number of elements. * @param new_size Number of elements the %deque should contain. @@ -884,7 +930,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * data. */ void +#ifndef __GXX_EXPERIMENTAL_CXX0X__ resize(size_type __new_size, value_type __x = value_type()) +#else + resize(size_type __new_size, value_type __x) +#endif { const size_type __len = size(); if (__new_size < __len) @@ -1040,6 +1090,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL _M_push_front_aux(__x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + void + push_front(value_type&& __x) + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) + { + this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, + move(__x)); + --this->_M_impl._M_start._M_cur; + } + else + _M_push_front_aux(move(__x)); + } + +#endif + /** * @brief Add data to the end of the %deque. * @param x Data to be added. @@ -1062,6 +1129,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL _M_push_back_aux(__x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + void + push_back(value_type&& __x) + { + if (this->_M_impl._M_finish._M_cur + != this->_M_impl._M_finish._M_last - 1) + { + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, + move(__x)); + ++this->_M_impl._M_finish._M_cur; + } + else + _M_push_back_aux(move(__x)); + } + +#endif + /** * @brief Removes first element. * @@ -1116,6 +1201,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL iterator insert(iterator __position, const value_type& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + iterator + insert(iterator __position, value_type&& __x); +#endif + /** * @brief Inserts a number of copies of given data into the %deque. * @param position An iterator into the %deque. @@ -1194,7 +1284,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * std::swap(d1,d2) will feed to this function. */ void +#ifndef __GXX_EXPERIMENTAL_CXX0X__ swap(deque& __x) +#else + swap(deque&& __x) +#endif { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); @@ -1281,6 +1375,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL void _M_fill_initialize(const value_type& __value); + void + _M_fill_initialize(); + // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. @@ -1353,8 +1450,16 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL */ void _M_push_back_aux(const value_type&); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + void _M_push_back_aux(value_type&&); +#endif + void _M_push_front_aux(const value_type&); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + void _M_push_front_aux(value_type&&); +#endif + void _M_pop_back_aux(); void _M_pop_front_aux(); @@ -1407,6 +1512,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL iterator _M_insert_aux(iterator __pos, const value_type& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + iterator + _M_insert_aux(iterator __pos, value_type&& __x); +#endif + // called by insert(p,n,x) via fill_insert void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); @@ -1418,6 +1528,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL _ForwardIterator __first, _ForwardIterator __last, size_type __n); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + void + _M_insert_aux(iterator __pos, size_type __n); +#endif // Internal erase functions follow. @@ -1603,6 +1717,18 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) { __x.swap(__y); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + inline void + swap(deque<_Tp,_Alloc>&& __x, deque<_Tp,_Alloc>& __y) + { __x.swap(__y); } + + template + inline void + swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>&& __y) + { __x.swap(__y); } +#endif + _GLIBCXX_END_NESTED_NAMESPACE #endif /* _DEQUE_H */ Index: include/bits/stl_uninitialized.h =================================================================== --- include/bits/stl_uninitialized.h (revisão 88) +++ include/bits/stl_uninitialized.h (cópia de trabalho) @@ -158,6 +158,44 @@ _GLIBCXX_BEGIN_NAMESPACE(std) std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD()); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline void + __uninitialized_fill_aux(_ForwardIterator __first, + _ForwardIterator __last, + __true_type) + { std::fill<_Tp>(__first, __last); } + + template + void + __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last, + __false_type) + { + _ForwardIterator __cur = __first; + try + { + for (; __cur != __last; ++__cur) + std::_Construct(&*__cur, _Tp()); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + template + inline void + uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; + std::__uninitialized_fill_aux<_Tp>(__first, __last, _Is_POD()); + } + +#endif + // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. template @@ -202,6 +240,43 @@ _GLIBCXX_BEGIN_NAMESPACE(std) std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline void + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + __true_type) + { std::fill_n<_Tp>(__first, __n); } + + template + void + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + __false_type) + { + _ForwardIterator __cur = __first; + try + { + for (; __n > 0; --__n, ++__cur) + std::_Construct(&*__cur, _Tp()); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + template + inline void + uninitialized_fill_n(_ForwardIterator __first, _Size __n) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; + std::__uninitialized_fill_n_aux<_Tp>(__first, __n, _Is_POD()); + } + +#endif + // Extensions: versions of uninitialized_copy, uninitialized_fill, // and uninitialized_fill_n that take an allocator parameter. // We dispatch back to the standard versions when we're given the @@ -260,6 +335,34 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const _Tp& __x, allocator<_Tp2>) { std::uninitialized_fill(__first, __last, __x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, + _Allocator __alloc) + { + _ForwardIterator __cur = __first; + try + { + for (; __cur != __last; ++__cur) + __alloc.construct(&*__cur, _Tp()); + } + catch(...) + { + std::_Destroy(__first, __cur, __alloc); + __throw_exception_again; + } + } + + template + inline void + __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, + allocator<_Tp2>) + { std::uninitialized_fill<_Tp>(__first, __last); } + +#endif + template void @@ -288,6 +391,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std) allocator<_Tp2>) { std::uninitialized_fill_n(__first, __n, __x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, + _Allocator __alloc) + { + _ForwardIterator __cur = __first; + try + { + for (; __n > 0; --__n, ++__cur) + __alloc.construct(&*__cur, _Tp()); + } + catch(...) + { + std::_Destroy(__first, __cur, __alloc); + __throw_exception_again; + } + } + + template + inline void + __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, + allocator<_Tp2>) + { std::uninitialized_fill_n<_Tp>(__first, __n); } + +#endif // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, // __uninitialized_fill_copy. All of these algorithms take a user- @@ -345,6 +477,30 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline _ForwardIterator + __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, + _InputIterator __first, + _InputIterator __last, + _Allocator __alloc) + { + std::__uninitialized_fill_a<_Tp>(__result, __mid, __alloc); + try + { + return std::__uninitialized_copy_a(__first, __last, __mid, __alloc); + } + catch(...) + { + std::_Destroy(__result, __mid, __alloc); + __throw_exception_again; + } + } + +#endif + // __uninitialized_copy_fill // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. @@ -370,6 +526,32 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline void + __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, + _ForwardIterator __last2, + _Allocator __alloc) + { + _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1, + __first2, + __alloc); + try + { + std::__uninitialized_fill_a<_Tp>(__mid2, __last2, __alloc); + } + catch(...) + { + std::_Destroy(__first2, __mid2, __alloc); + __throw_exception_again; + } + } + +#endif + _GLIBCXX_END_NAMESPACE #endif /* _STL_UNINITIALIZED_H */ Index: include/bits/boost_concept_check.h =================================================================== --- include/bits/boost_concept_check.h (revisão 88) +++ include/bits/boost_concept_check.h (cópia de trabalho) @@ -186,6 +186,17 @@ struct _Aux_require_same<_Tp,_Tp> { type // functions? present way would require a default ctor, i think... }; +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + struct _MoveConstructibleConcept + { + void __constraints() { + _Tp __a = static_cast<_Tp&&>(__b); // require move constructor + } + _Tp __b; + }; +#endif + template struct _CopyConstructibleConcept { @@ -201,6 +212,18 @@ struct _Aux_require_same<_Tp,_Tp> { type _Tp __b; }; +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + struct _MoveAssignableConcept + { + void __constraints() { + __a = static_cast<_Tp&&>(__b); + } + _Tp __a; + _Tp __b; + }; +#endif + // The SGI STL version of Assignable requires copy constructor and operator= template struct _SGIAssignableConcept @@ -217,6 +240,17 @@ struct _Aux_require_same<_Tp,_Tp> { type _Tp __a; }; +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + struct _DestructibleConcept + { + void __constraints() { + __a.~_Tp(); + } + _Tp __a; + }; +#endif + template struct _ConvertibleConcept { @@ -420,6 +454,7 @@ struct _Aux_require_same<_Tp,_Tp> { type { void __constraints() { // __function_requires< _DefaultConstructibleConcept<_Tp> >(); + __function_requires< _AssignableConcept<_Tp> >(); __function_requires< _EqualityComparableConcept<_Tp> >(); // typedef typename std::iterator_traits<_Tp>::value_type _V; Index: include/bits/stl_algo.h =================================================================== --- include/bits/stl_algo.h (revisão 88) +++ include/bits/stl_algo.h (cópia de trabalho) @@ -1858,7 +1858,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) for (_Distance __i = 0; __i < __d; __i++) { - _ValueType __tmp = *__first; + _ValueType __tmp = __move(*__first); _RandomAccessIterator __p = __first; if (__k < __l) @@ -1867,11 +1867,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { if (__p > __first + __l) { - *__p = *(__p - __l); + *__p = __move(*(__p - __l)); __p -= __l; } - *__p = *(__p + __k); + *__p = __move(*(__p + __k)); __p += __k; } } @@ -1881,15 +1881,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { if (__p < __last - __k) { - *__p = *(__p + __k); + *__p = __move(*(__p + __k)); __p += __k; } - *__p = * (__p - __l); + *__p = __move(*(__p - __l)); __p -= __l; } } - *__p = __tmp; + *__p = __move(__tmp); ++__first; } } @@ -2158,15 +2158,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std) for ( ; __first != __last ; ++__first) if (__pred(*__first)) { - *__result1 = *__first; + *__result1 = __move(*__first); ++__result1; } else { - *__result2 = *__first; + *__result2 = __move(*__first); ++__result2; } +#ifndef __GXX_EXPERIMENTAL_CXX0X__ std::copy(__buffer, __result2, __result1); +#else + std::move(__buffer, __result2, __result1); +#endif return __result1; } else @@ -2224,8 +2228,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std) typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; +#ifndef __GXX_EXPERIMENTAL_CXX0X__ _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, __last); +#else + _Temporary_buffer<_ForwardIterator, _ValueType> __buf(distance(__first, + __last)); +#endif + if (__buf.size() > 0) return std::__stable_partition_adaptive(__first, __last, __pred, Index: include/bits/stl_iterator.h =================================================================== --- include/bits/stl_iterator.h (revisão 88) +++ include/bits/stl_iterator.h (cópia de trabalho) @@ -414,6 +414,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return *this; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + back_insert_iterator& + operator=(typename _Container::value_type&& __value) + { + container->push_back(move(__value)); + return *this; + } +#endif + /// Simply returns *this. back_insert_iterator& operator*() @@ -488,6 +497,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return *this; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + front_insert_iterator& + operator=(typename _Container::value_type&& __value) + { + container->push_front(move(__value)); + return *this; + } +#endif + /// Simply returns *this. front_insert_iterator& operator*() @@ -584,6 +602,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return *this; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + insert_iterator& + operator=(typename _Container::value_type&& __value) + { + iter = container->insert(iter, move(__value)); + ++iter; + return *this; + } +#endif + /// Simply returns *this. insert_iterator& operator*() Index: include/bits/vector.tcc =================================================================== --- include/bits/vector.tcc (revisão 88) +++ include/bits/vector.tcc (cópia de trabalho) @@ -61,6 +61,8 @@ #ifndef _VECTOR_TCC #define _VECTOR_TCC 1 +#include + _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) template @@ -73,8 +75,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL if (this->capacity() < __n) { const size_type __old_size = size(); +#ifndef __GXX_EXPERIMENTAL_CXX0X__ pointer __tmp = _M_allocate_and_copy(__n, this->_M_impl._M_start, this->_M_impl._M_finish); +#else + pointer __tmp = _M_allocate_and_copy(__n, + make_move_iterator(this->_M_impl._M_start), + make_move_iterator(this->_M_impl._M_finish)); +#endif std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -103,6 +111,27 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL return iterator(this->_M_impl._M_start + __n); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + insert(iterator __position, value_type&& __x) + { + const size_type __n = __position - begin(); + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage + && __position == end()) + { + this->_M_impl.construct(this->_M_impl._M_finish, move(__x)); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(__position, move(__x)); + return iterator(this->_M_impl._M_start + __n); + } + +#endif + template typename vector<_Tp, _Alloc>::iterator vector<_Tp, _Alloc>:: @@ -301,6 +330,74 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + vector<_Tp, _Alloc>:: + _M_insert_aux(iterator __position, value_type&& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + this->_M_impl.construct(this->_M_impl._M_finish, + static_cast(*(this->_M_impl._M_finish - 1))); + ++this->_M_impl._M_finish; + std::copy_backward(make_move_iterator(__position.base()), + make_move_iterator(this->_M_impl._M_finish - 2), + make_move_iterator(this->_M_impl._M_finish - 1)); + *__position = move(__x); + } + else + { + const size_type __old_size = size(); + if (__old_size == this->max_size()) + __throw_length_error(__N("vector::_M_insert_aux")); + + // When sizeof(value_type) == 1 and __old_size > size_type(-1)/2 + // __len overflows: if we don't notice and _M_allocate doesn't + // throw we crash badly later. + size_type __len = __old_size != 0 ? 2 * __old_size : 1; + if (__len < __old_size) + __len = this->max_size(); + + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + __new_finish = + std::__uninitialized_copy_a( + make_move_iterator(this->_M_impl._M_start), + make_move_iterator(__position.base()), + __new_start, + _M_get_Tp_allocator()); + this->_M_impl.construct(__new_finish, move(__x)); + ++__new_finish; + __new_finish = + std::__uninitialized_copy_a( + make_move_iterator(__position.base()), + make_move_iterator(this->_M_impl._M_finish), + __new_finish, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } + +#endif + template void vector<_Tp, _Alloc>:: @@ -388,6 +485,103 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + vector<_Tp, _Alloc>:: + _M_fill_insert(iterator __position, size_type __n) + { + if (__n != 0) + { + if (size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_finish) >= __n) + { + const size_type __elems_after = end() - __position; + pointer __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::__uninitialized_copy_a( + make_move_iterator(this->_M_impl._M_finish - __n), + make_move_iterator(this->_M_impl._M_finish), + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n; + std::copy_backward(make_move_iterator(__position.base()), + make_move_iterator(__old_finish - __n), + __old_finish); + pointer __i = __position.base(); + pointer __end = __position.base() + __n; + while (__i != __end) + *__i++ = value_type(); + } + else + { + std::__uninitialized_fill_n_a( + this->_M_impl._M_finish, + __n - __elems_after, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n - __elems_after; + std::__uninitialized_copy_a(make_move_iterator(__position.base()), + make_move_iterator(__old_finish), + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __elems_after; + pointer __i = __position.base(); + while (__i != __old_finish) + *__i++ = value_type(); + } + } + else + { + const size_type __old_size = size(); + if (this->max_size() - __old_size < __n) + __throw_length_error(__N("vector::_M_fill_insert")); + + // See _M_insert_aux above. + size_type __len = __old_size + std::max(__old_size, __n); + if (__len < __old_size) + __len = this->max_size(); + + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + __new_finish = + std::__uninitialized_copy_a(make_move_iterator(this->_M_impl._M_start), + make_move_iterator(__position.base()), + __new_start, + _M_get_Tp_allocator()); + std::__uninitialized_fill_n_a(__new_finish, __n, + _M_get_Tp_allocator()); + __new_finish += __n; + __new_finish = + std::__uninitialized_copy_a(make_move_iterator(__position.base()), + make_move_iterator(this->_M_impl._M_finish), + __new_finish, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(__new_start, __new_finish, + _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } + } + +#endif + template template void vector<_Tp, _Alloc>:: Index: include/bits/stl_tempbuf.h =================================================================== --- include/bits/stl_tempbuf.h (revisão 88) +++ include/bits/stl_tempbuf.h (cópia de trabalho) @@ -97,6 +97,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _M_initialize_buffer(const _Tp& __val, __false_type) { std::uninitialized_fill_n(_M_buffer, _M_len, __val); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + void + _M_initialize_buffer() + { std::uninitialized_fill_n(_M_buffer, _M_len); } + +#endif + public: /// As per Table mumble. size_type @@ -124,6 +132,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + _Temporary_buffer(size_type __n); +#endif + ~_Temporary_buffer() { std::_Destroy(_M_buffer, _M_buffer + _M_len); @@ -166,6 +178,37 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + _Temporary_buffer<_ForwardIterator, _Tp>:: + _Temporary_buffer(size_type __n) + : _M_original_len(__n), + _M_len(0), _M_buffer(0) + { + // Workaround for a __type_traits bug in the pre-7.3 compiler. + typedef typename std::__is_scalar<_Tp>::__type _Trivial; + + try + { + pair __p(get_temporary_buffer< + value_type>(_M_original_len)); + _M_buffer = __p.first; + _M_len = __p.second; + if (_M_len > 0) + _M_initialize_buffer(); + } + catch(...) + { + std::return_temporary_buffer(_M_buffer); + _M_buffer = 0; + _M_len = 0; + __throw_exception_again; + } + } + +#endif + _GLIBCXX_END_NAMESPACE #endif /* _TEMPBUF_H */ Index: include/bits/deque.tcc =================================================================== --- include/bits/deque.tcc (revisão 88) +++ include/bits/deque.tcc (cópia de trabalho) @@ -62,6 +62,8 @@ #ifndef _DEQUE_TCC #define _DEQUE_TCC 1 +#include + _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) template @@ -106,6 +108,31 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL return _M_insert_aux(__position, __x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + insert(iterator __position, value_type&& __x) + { + if (__position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(move(__x)); + return this->_M_impl._M_start; + } + else if (__position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(move(__x)); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } + else + return _M_insert_aux(__position, move(__x)); + } + +#endif + template typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: @@ -217,6 +244,37 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL _M_insert_aux(__pos, __n, __x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + deque<_Tp, _Alloc>:: + _M_fill_initialize() + { + _Map_pointer __cur; + try + { + for (__cur = this->_M_impl._M_start._M_node; + __cur < this->_M_impl._M_finish._M_node; + ++__cur) + std::__uninitialized_fill_a(*__cur, + *__cur + _S_buffer_size(), + _M_get_Tp_allocator()); + std::__uninitialized_fill_a( + this->_M_impl._M_finish._M_first, + this->_M_impl._M_finish._M_cur, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), + _M_get_Tp_allocator()); + __throw_exception_again; + } + } + +#endif + template void deque<_Tp, _Alloc>:: @@ -321,6 +379,31 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + deque<_Tp, _Alloc>:: + _M_push_back_aux(value_type&& __t) + { + _M_reserve_map_at_back(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); + try + { + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, move(__t)); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; + } + catch(...) + { + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); + __throw_exception_again; + } + } + +#endif + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. template void @@ -345,6 +428,32 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + deque<_Tp, _Alloc>:: + _M_push_front_aux(value_type&& __t) + { + _M_reserve_map_at_front(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); + try + { + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + this->_M_impl.construct(this->_M_impl._M_start._M_cur, move(__t)); + } + catch(...) + { + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); + __throw_exception_again; + } + } + +#endif + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. template void deque<_Tp, _Alloc>:: @@ -459,6 +568,42 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL return __pos; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, value_type&& __x) + { + difference_type __index = __pos - this->_M_impl._M_start; + if (static_cast(__index) < size() / 2) + { + push_front(move(front())); + iterator __front1 = this->_M_impl._M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_impl._M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + std::move(__front2, __pos1, __front1); + } + else + { + push_back(move(back())); + iterator __back1 = this->_M_impl._M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_impl._M_start + __index; + std::move_backward(__pos, __back2, __back1); + } + *__pos = move(__x); + return __pos; + } + +#endif + template void deque<_Tp, _Alloc>:: @@ -633,6 +778,99 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + void + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, size_type __n) + { + const difference_type __elems_before = __pos - this->_M_impl._M_start; + const size_type __length = this->size(); + if (__elems_before < difference_type(__length / 2)) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elems_before; + try + { + if (__elems_before >= difference_type(__n)) + { + iterator __start_n = (this->_M_impl._M_start + + difference_type(__n)); + std::__uninitialized_copy_a( + make_move_iterator(this->_M_impl._M_start), + make_move_iterator(__start_n), + __new_start, _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::move(__start_n, __pos, __old_start); + std::fill(__pos - difference_type(__n), __pos); + } + else + { + std::__uninitialized_copy_fill( + make_move_iterator(this->_M_impl._M_start), + make_move_iterator(__pos), __new_start, + this->_M_impl._M_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::fill(__old_start, __pos); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = this->_M_impl._M_finish - __elems_after; + try + { + if (__elems_after > difference_type(__n)) + { + iterator __finish_n = (this->_M_impl._M_finish + - difference_type(__n)); + std::__uninitialized_copy_a( + make_move_iterator(__finish_n), + make_move_iterator(this->_M_impl._M_finish), + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(make_move_iterator(__pos), + make_move_iterator(__finish_n), + __old_finish); + std::fill(__pos, __pos + difference_type(__n)); + } + else + { + std::__uninitialized_fill_copy( + this->_M_impl._M_finish, + __pos + difference_type(__n), + make_move_iterator(__pos), + make_move_iterator(this->_M_impl._M_finish), + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::fill(__pos, __old_finish); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + } + +#endif + template void deque<_Tp, _Alloc>:: Index: include/bits/basic_string.tcc =================================================================== --- include/bits/basic_string.tcc (revisão 88) +++ include/bits/basic_string.tcc (cópia de trabalho) @@ -186,6 +186,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __str.get_allocator()) { } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(basic_string&& __str) + : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), + __str.get_allocator()), + move(__str.get_allocator())) + { } +#endif + template basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _Alloc& __a) @@ -498,7 +508,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template void basic_string<_CharT, _Traits, _Alloc>:: +#ifndef __GXX_EXPERIMENTAL_CXX0X__ swap(basic_string& __s) +#else + swap(basic_string&& __s) +#endif { if (_M_rep()->_M_is_leaked()) _M_rep()->_M_set_sharable(); @@ -975,7 +989,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCXX_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE && !defined(__GXX_EXPERIMENTAL_CXX0X__) extern template class basic_string; extern template basic_istream& Index: include/bits/stl_move_iterator.h =================================================================== --- include/bits/stl_move_iterator.h (revisão 0) +++ include/bits/stl_move_iterator.h (revisão 0) @@ -0,0 +1,183 @@ +// move_iterator 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. + +#if !defined(_MOVE_ITERATOR_H) && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define _MOVE_ITERATOR_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template + class move_iterator + { + protected: + _Iterator _M_current; + + public: + typedef _Iterator iterator_type; + typedef typename iterator_traits<_Iterator>::iterator_category + iterator_category; + typedef typename iterator_traits<_Iterator>::value_type value_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::value_type&& reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; + + move_iterator() : _M_current() { } + + explicit + move_iterator(iterator_type __i) : _M_current(__i) { } + + template + move_iterator(const move_iterator& __i) + : _M_current(__i.base()) { } + + template + move_iterator& + operator=(const move_iterator& __i) + { + _M_current = __i.base(); + return *this; + } + + // Forward iterator requirements + reference + operator*() const + { return move(*_M_current); } + + pointer + operator->() const + { return _M_current; } + + move_iterator& + operator++() + { + ++_M_current; + return *this; + } + + move_iterator + operator++(int) + { return move_iterator(_M_current++); } + + // Bidirectional iterator requirements + move_iterator& + operator--() + { + --_M_current; + return *this; + } + + move_iterator + operator--(int) + { return move_iterator(_M_current--); } + + // Random access iterator requirements + reference + operator[](const difference_type& __n) const + { return move(_M_current[__n]); } + + move_iterator& + operator+=(const difference_type& __n) + { _M_current += __n; return *this; } + + move_iterator + operator+(const difference_type& __n) const + { return move_iterator(_M_current + __n); } + + move_iterator& + operator-=(const difference_type& __n) + { _M_current -= __n; return *this; } + + move_iterator + operator-(const difference_type& __n) const + { return move_iterator(_M_current - __n); } + + _Iterator + base() const + { return _M_current; } + }; + + template + inline bool + operator==(const move_iterator<_Iterator1>& __lhs, + const move_iterator<_Iterator2>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template + inline bool + operator!=(const move_iterator<_Iterator1>& __lhs, + const move_iterator<_Iterator2>& __rhs) + { return __lhs.base() != __rhs.base(); } + + template + inline bool + operator<(const move_iterator<_Iterator1>& __lhs, + const move_iterator<_Iterator2>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template + inline bool + operator<=(const move_iterator<_Iterator1>& __lhs, + const move_iterator<_Iterator2>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template + inline bool + operator>(const move_iterator<_Iterator1>& __lhs, + const move_iterator<_Iterator2>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template + inline bool + operator>=(const move_iterator<_Iterator1>& __lhs, + const move_iterator<_Iterator2>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + template + inline typename move_iterator<_Iterator1>::difference_type + operator-(const move_iterator<_Iterator1>& __lhs, + const move_iterator<_Iterator2>& __rhs) + { return __lhs.base() - __rhs.base(); } + + template + inline move_iterator<_Iterator> + operator+(typename move_iterator<_Iterator>::difference_type __n, + const move_iterator<_Iterator>& __i) + { return move_iterator<_Iterator>(__i.base() + __n); } + + template + move_iterator<_Iterator> + make_move_iterator(const _Iterator& i) + { + return move_iterator<_Iterator>(i); + } + +_GLIBCXX_END_NAMESPACE + +#endif // _MOVE_ITERATOR_H Index: include/bits/stl_construct.h =================================================================== --- include/bits/stl_construct.h (revisão 88) +++ include/bits/stl_construct.h (cópia de trabalho) @@ -81,6 +81,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ::new(static_cast(__p)) _T1(__value); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + inline void + _Construct(_T1* __p, _T2&& __value) + { + ::new(static_cast(__p)) _T1(forward<_T2>(__value)); + } + +#endif + /** * @if maint * Constructs an object in existing memory by invoking an allocated Index: include/bits/stl_unique_ptr.h =================================================================== --- include/bits/stl_unique_ptr.h (revisão 0) +++ include/bits/stl_unique_ptr.h (revisão 0) @@ -0,0 +1,604 @@ +// unique_ptr implementation -*- 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. + +#if !defined(_UNIQUE_PTR_H) && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define _UNIQUE_PTR_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + namespace detail { + + template + struct select + { + typedef Then type; + }; + + template + struct select + { + typedef Else type; + }; + + template struct restrict_to {}; + template struct restrict_to {typedef T type;}; + + // Pending empty-base optimization. + template + class compressed_pair + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef first_type first_param_type; + typedef second_type second_param_type; + typedef first_type& first_reference; + typedef second_type& second_reference; + typedef first_type const& first_const_reference; + typedef second_type const& second_const_reference; + + compressed_pair(first_param_type x, second_param_type y) + : _M_first(x), _M_second(y) { } + + explicit + compressed_pair(first_param_type x) + : _M_first(x), _M_second() { } + + explicit + compressed_pair(second_param_type y) + : _M_first(), _M_second(y) { } + + compressed_pair& + operator=(const compressed_pair& cp) + { + _M_first = cp._M_first; + _M_second = cp._M_second; + return *this; + } + + first_reference + first() { return _M_first; } + + first_const_reference + first() const { return _M_first; } + + second_reference + second() { return _M_second; } + + second_const_reference + second() const { return _M_second; } + + void + swap(compressed_pair& y) + { + swap(_M_first, y._M_first); + swap(_M_second, y._M_second); + } + + private: + first_type _M_first; + second_type _M_second; + }; + + struct two {char _[2];}; + + namespace pointer_type_imp + { + + template static two test(...); + template static char test(typename U::pointer* = 0); + + } + + template + struct has_pointer_type + { + static const bool value = sizeof(pointer_type_imp::test(0)) == 1; + }; + + namespace pointer_type_imp + { + + template ::value> + struct pointer_type + { + typedef typename D::pointer type; + }; + + template + struct pointer_type + { + typedef T* type; + }; + + } + + template + struct pointer_type + { + typedef typename pointer_type_imp::pointer_type::type>::type type; + }; + + } + + template + struct default_delete + { + default_delete() {} + template default_delete(const default_delete&) {} + void operator() (T* ptr) const + { + static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type"); + delete ptr; + } + }; + + template + struct default_delete + { + void operator() (T* ptr) const + { + static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type"); + delete [] ptr; + } + }; + + template + struct default_delete + { + void operator() (T* ptr, size_t) const + { + static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type"); + delete [] ptr; + } + }; + + template > + class unique_ptr + { + struct nat {int for_bool_;}; + public: + typedef T element_type; + typedef D deleter_type; + typedef typename detail::pointer_type::type pointer; + + // constructors + unique_ptr() : ptr_(pointer()) + { + static_assert(!tr1::is_pointer::value, "Constructed with null function pointer deleter"); + } + + explicit unique_ptr(pointer p) : ptr_(p) + { + static_assert(!tr1::is_pointer::value, "Constructed with null function pointer deleter"); + } + + unique_ptr(pointer p, typename detail::select< + tr1::is_reference::value, + D, + const D&>::type d) + : ptr_(p, d) {} + + unique_ptr(pointer p, typename tr1::remove_reference::type&& d) + : ptr_(p, std::move(d)) + { + static_assert(!tr1::is_reference::value, "rvalue deleter bound to reference"); + } + + unique_ptr(unique_ptr&& u) + : ptr_(u.release(), std::forward(u.get_deleter())) {} + + template + unique_ptr(unique_ptr&& u, + typename detail::restrict_to< + tr1::is_convertible::pointer, pointer>::value && + tr1::is_convertible::value && + ( + !tr1::is_reference::value || + tr1::is_same::value + ) + , + nat + >::type = nat()) + : ptr_(u.release(), std::forward(u.get_deleter())) {} + + // destructor + ~unique_ptr() {reset();} + + // assignment + unique_ptr& + operator=(unique_ptr&& u) + { + reset(u.release()); + ptr_.second() = std::move(u.get_deleter()); + return *this; + } + + template + unique_ptr& + operator=(unique_ptr&& u) + { + reset(u.release()); + ptr_.second() = std::move(u.get_deleter()); + return *this; + } + + unique_ptr& + operator=(int nat::*) + { + reset(); + return *this; + } + + // observers + typename tr1::add_reference::type + operator*() const + { return *ptr_.first(); } + + pointer + operator->() const + { return ptr_.first(); } + + pointer + get() const + { return ptr_.first(); } + + D& + get_deleter() + { return ptr_.second(); } + + const D& + get_deleter() const + { return ptr_.second(); } + + operator int + nat::*() const + { return ptr_.first() ? &nat::for_bool_ : 0; } + + // modifiers + pointer + release() + { + pointer tmp = ptr_.first(); + ptr_.first() = pointer(); + return tmp; + } + + void + reset(pointer p = pointer()) + { + if (ptr_.first() != p) + { + if (ptr_.first()) + ptr_.second()(ptr_.first()); + ptr_.first() = p; + } + } + + void + swap(unique_ptr&& u) + { ptr_.swap(u.ptr_); } + + private: + detail::compressed_pair ptr_; + + unique_ptr(const unique_ptr&); + template unique_ptr(const unique_ptr&); + unique_ptr& operator=(const unique_ptr&); + template unique_ptr& operator=(const unique_ptr&); + }; + + template + class unique_ptr + { + struct nat {int for_bool_;}; + public: + typedef T element_type; + typedef D deleter_type; + typedef typename detail::pointer_type::type pointer; + + // constructors + unique_ptr() : ptr_(pointer()) + { + static_assert(!tr1::is_pointer::value, "Constructed with null function pointer deleter"); + } + + explicit unique_ptr(pointer p) : ptr_(p) + { + static_assert(!tr1::is_pointer::value, "Constructed with null function pointer deleter"); + } + + unique_ptr(pointer p, typename detail::select< + tr1::is_reference::value, + D, + const D&>::type d) + : ptr_(p, d) { } + + unique_ptr(pointer p, typename tr1::remove_reference::type&& d) + : ptr_(p, std::move(d)) + { + static_assert(!tr1::is_reference::value, "rvalue deleter bound to reference"); + } + + unique_ptr(unique_ptr&& u) + : ptr_(u.release(), std::forward(u.get_deleter())) { } + + // destructor + ~unique_ptr() + { reset(); } + + // assignment + unique_ptr& + operator=(unique_ptr&& u) + { + reset(u.release()); + ptr_.second() = std::move(u.get_deleter()); + return *this; + } + + unique_ptr& + operator=(int nat::*) + { + reset(); + return *this; + } + + // observers + typename tr1::add_reference::type + operator[](size_t i) const + { return ptr_.first()[i]; } + + pointer + get() const + { return ptr_.first(); } + + D& + get_deleter() + { return ptr_.second(); } + + const D& + get_deleter() const + { return ptr_.second(); } + + operator int nat::*() const + { return ptr_.first() ? &nat::for_bool_ : 0; } + + // modifiers + pointer + release() + { + pointer tmp = ptr_.first(); + ptr_.first() = pointer(); + return tmp; + } + + void + reset(pointer p = pointer()) + { + if (ptr_.first() != p) + { + if (ptr_.first()) + ptr_.second()(ptr_.first()); + ptr_.first() = p; + } + } + + void + swap(unique_ptr&& u) + { ptr_.swap(u.ptr_); } + + private: + detail::compressed_pair ptr_; + + template unique_ptr(U p, + typename detail::select< + tr1::is_reference::value, + D, + const D&>::type d, + typename detail::restrict_to::value>::type* = 0); + template unique_ptr(U p, typename tr1::remove_reference::type&& d, + typename detail::restrict_to::value>::type* = 0); + template explicit unique_ptr(U, + typename detail::restrict_to::value>::type* = 0); + unique_ptr(const unique_ptr&); + unique_ptr& operator=(const unique_ptr&); + }; + + template + class unique_ptr + { + struct nat {int for_bool_;}; + public: + typedef T element_type; + typedef D deleter_type; + typedef typename detail::pointer_type::type pointer; + static const size_t size = N; + + // constructors + unique_ptr() : ptr_(pointer()) + { + static_assert(!tr1::is_pointer::value, "Constructed with null function pointer deleter"); + } + + explicit unique_ptr(pointer p) : ptr_(p) + { + static_assert(!tr1::is_pointer::value, "Constructed with null function pointer deleter"); + } + + unique_ptr(pointer p, typename detail::select< + tr1::is_reference::value, + D, + const D&>::type d) + : ptr_(p, d) { } + + unique_ptr(pointer p, typename tr1::remove_reference::type&& d) + : ptr_(p, std::move(d)) + { + static_assert(!tr1::is_reference::value, "rvalue deleter bound to reference"); + } + + unique_ptr(unique_ptr&& u) + : ptr_(u.release(), std::forward(u.get_deleter())) { } + + // destructor + ~unique_ptr() + { reset(); } + + // assignment + unique_ptr& + operator=(unique_ptr&& u) + { + reset(u.release()); + ptr_.second() = std::move(u.get_deleter()); + return *this; + } + + unique_ptr& + operator=(int nat::*) + { + reset(); + return *this; + } + + // observers + typename tr1::add_reference::type + operator[](size_t i) const + { return ptr_.first()[i]; } + + pointer + get() const + { return ptr_.first(); } + + D& + get_deleter() + { return ptr_.second(); } + + const D& + get_deleter() const + { return ptr_.second(); } + + operator int nat::*() const + { return ptr_.first() ? &nat::for_bool_ : 0; } + + // modifiers + pointer + release() + { + pointer tmp = ptr_.first(); + ptr_.first() = pointer(); + return tmp; + } + + void + reset(pointer p = pointer()) + { + if (ptr_.first() != p) + { + if (ptr_.first()) + ptr_.second()(ptr_.first(), N); + ptr_.first() = p; + } + } + + void + swap(unique_ptr&& u) + { ptr_.swap(u.ptr_); } + + private: + detail::compressed_pair ptr_; + + template unique_ptr(U p, + typename detail::select< + tr1::is_reference::value, + D, + const D&>::type d, + typename detail::restrict_to::value>::type* = 0); + template unique_ptr(U p, typename tr1::remove_reference::type&& d, + typename detail::restrict_to::value>::type* = 0); + template explicit unique_ptr(U, + typename detail::restrict_to::value>::type* = 0); + unique_ptr(const unique_ptr&); + unique_ptr& operator=(const unique_ptr&); + }; + + template + inline + void swap(unique_ptr& x, unique_ptr& y) + { x.swap(y); } + + template + inline + void swap(unique_ptr&& x, unique_ptr& y) + { x.swap(y); } + + template + inline + void swap(unique_ptr& x, unique_ptr&& y) + { x.swap(y); } + + template + inline + bool + operator==(const unique_ptr& x, const unique_ptr& y) + { return x.get() == y.get(); } + + template + inline + bool + operator!=(const unique_ptr& x, const unique_ptr& y) + { return x.get() != y.get(); } + + template + inline + bool + operator <(const unique_ptr& x, const unique_ptr& y) + { return x.get() < y.get(); } + + template + inline + bool + operator<=(const unique_ptr& x, const unique_ptr& y) + { return x.get() <= y.get(); } + + template + inline + bool + operator >(const unique_ptr& x, const unique_ptr& y) + { return x.get() > y.get(); } + + template + inline + bool + operator>=(const unique_ptr& x, const unique_ptr& y) + { return x.get() >= y.get(); } + +_GLIBCXX_END_NAMESPACE + +#endif /* _UNIQUE_PTR_H */ Index: include/bits/stl_move.h =================================================================== --- include/bits/stl_move.h (revisão 0) +++ include/bits/stl_move.h (revisão 0) @@ -0,0 +1,68 @@ +// move/forward implementation -*- 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. + +#if !defined(_MOVE_H) +#define _MOVE_H 1 + +#include + +_GLIBCXX_BEGIN_NAMESPACE(std) + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + + template + struct identity { typedef _Tp type; }; + + template + _Tp&& + forward (typename identity<_Tp>::type&& __t) + { return __t; } + + template + typename tr1::remove_reference<_Tp>::type&& + move (_Tp&& __t) + { return static_cast<_Tp&&>(__t); } + + template + typename tr1::remove_reference<_Tp>::type&& + __move (_Tp&& __t) + { return static_cast<_Tp&&>(__t); } + +#else + + template + _Tp + __move (_Tp const& __t) + { return __t; } + +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _MOVE_H */ Index: include/Makefile.in =================================================================== --- include/Makefile.in (revisão 88) +++ include/Makefile.in (cópia de trabalho) @@ -333,6 +333,8 @@ bits_headers = \ ${bits_srcdir}/stl_iterator_base_types.h \ ${bits_srcdir}/stl_list.h \ ${bits_srcdir}/stl_map.h \ + ${bits_srcdir}/stl_move.h \ + ${bits_srcdir}/stl_move_iterator.h \ ${bits_srcdir}/stl_multimap.h \ ${bits_srcdir}/stl_multiset.h \ ${bits_srcdir}/stl_numeric.h \ @@ -344,6 +346,7 @@ bits_headers = \ ${bits_srcdir}/stl_stack.h \ ${bits_srcdir}/stl_tempbuf.h \ ${bits_srcdir}/stl_tree.h \ + ${bits_srcdir}/stl_unique_ptr.h \ ${bits_srcdir}/stl_uninitialized.h \ ${bits_srcdir}/stl_vector.h \ ${bits_srcdir}/streambuf.tcc \ Index: include/Makefile.am =================================================================== --- include/Makefile.am (revisão 88) +++ include/Makefile.am (cópia de trabalho) @@ -103,6 +103,8 @@ bits_headers = \ ${bits_srcdir}/stl_iterator_base_types.h \ ${bits_srcdir}/stl_list.h \ ${bits_srcdir}/stl_map.h \ + ${bits_srcdir}/stl_move.h \ + ${bits_srcdir}/stl_move_iterator.h \ ${bits_srcdir}/stl_multimap.h \ ${bits_srcdir}/stl_multiset.h \ ${bits_srcdir}/stl_numeric.h \ @@ -114,6 +116,7 @@ bits_headers = \ ${bits_srcdir}/stl_stack.h \ ${bits_srcdir}/stl_tempbuf.h \ ${bits_srcdir}/stl_tree.h \ + ${bits_srcdir}/stl_unique_ptr.h \ ${bits_srcdir}/stl_uninitialized.h \ ${bits_srcdir}/stl_vector.h \ ${bits_srcdir}/streambuf.tcc \ Index: include/std/iterator =================================================================== --- include/std/iterator (revisão 88) +++ include/std/iterator (cópia de trabalho) @@ -71,5 +71,6 @@ #include #include #include +#include #endif /* _GLIBCXX_ITERATOR */ Index: include/std/utility =================================================================== --- include/std/utility (revisão 88) +++ include/std/utility (cópia de trabalho) @@ -64,6 +64,7 @@ #include #include +#include #include #endif /* _GLIBCXX_UTILITY */ Index: include/std/memory =================================================================== --- include/std/memory (revisão 88) +++ include/std/memory (cópia de trabalho) @@ -59,6 +59,7 @@ #include #include #include +#include _GLIBCXX_BEGIN_NAMESPACE(std)