Viewing file: pr98464.C (6.44 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// { dg-do compile } // { dg-require-effective-target c++11 } // { dg-options "-O3 -fno-tree-dce" }
template < typename, typename, template < typename > class _Op, typename... _Args > struct __detector { using type = _Op< _Args... >; }; template < typename _Default, template < typename > class _Op, typename... _Args > using __detected_or = __detector< _Default, void, _Op, _Args... >; template < typename _Default, template < typename > class _Op, typename... _Args > using __detected_or_t = typename __detected_or< _Default, _Op, _Args... >::type; template < typename, typename > struct __replace_first_arg; template < template < typename > class _Template, typename _Up, typename _Tp, typename... _Types > struct __replace_first_arg< _Template< _Tp, _Types... >, _Up > { using type = _Template< _Up >; }; template < class > class min_pointer; class MoveOnly; struct pointer_traits { template < typename _Up > using rebind = typename __replace_first_arg< min_pointer< int >, _Up >::type; }; template < typename _Iterator > class __normal_iterator { public: __normal_iterator(_Iterator); }; struct __allocator_traits_base { template < typename _Tp > using __pointer = typename _Tp::pointer; }; template < typename _Alloc > struct allocator_traits : __allocator_traits_base { typedef typename _Alloc::value_type value_type; using pointer = __detected_or_t< value_type, __pointer, _Alloc >; template < typename _Tp > struct _Ptr { using type = pointer_traits::rebind< _Tp >; }; using const_pointer = typename _Ptr< value_type >::type; using size_type = int; static pointer allocate(_Alloc __a, size_type __n) { return __a.allocate(__n); } }; template < typename _ForwardIterator, typename _Allocator > void _Destroy(_ForwardIterator __first, _ForwardIterator __last, _Allocator) { for (; __first != __last; ++__first) ; } template < typename _InputIterator, typename _ForwardIterator, typename _Allocator > _ForwardIterator __uninitialized_copy_a(_InputIterator, _ForwardIterator, _Allocator); template < typename _InputIterator, typename _ForwardIterator, typename _Allocator > _ForwardIterator __uninitialized_move_if_noexcept_a(_InputIterator __last, _ForwardIterator __result, _Allocator __alloc) { return __uninitialized_copy_a(__last, __result, __alloc); } template < typename _ForwardIterator, typename _Size, typename _Allocator > _ForwardIterator __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, _Allocator) { for (; __n; --__n, ++__first) ; return __first; } template < typename _Alloc > struct _Vector_base { typedef _Alloc _Tp_alloc_type; typedef typename _Tp_alloc_type ::pointer pointer; struct _Vector_impl_data { pointer _M_start; pointer _M_finish; pointer _M_end_of_storage; }; struct _Vector_impl : _Tp_alloc_type, _Vector_impl_data { _Vector_impl(_Tp_alloc_type) { } }; _Vector_base(long __n, _Alloc __a) : _M_impl(__a) { _M_impl._M_end_of_storage = _M_impl._M_start + __n; } _Vector_impl _M_impl; pointer _M_allocate(long __n) { return __n ? allocator_traits< _Tp_alloc_type >::allocate(_M_impl, __n) : pointer(); } }; template < typename, typename _Alloc > class vector : _Vector_base< _Alloc > { public: typedef typename _Alloc::pointer pointer; typedef __normal_iterator< typename allocator_traits< _Alloc >::const_pointer > const_iterator; typedef _Alloc allocator_type; vector(long __n, allocator_type __a = allocator_type()) : _Vector_base< _Alloc >(__n, __a) { this->_M_impl._M_finish = __uninitialized_default_n_a(this->_M_impl._M_start, __n, 0); } ~vector() { _Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 0); } const_iterator cbegin() { return this->_M_impl._M_start; } typename _Alloc::value_type operator[](long) { return *this->_M_impl._M_start; } void insert(const_iterator, MoveOnly &&) { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) ; else _M_realloc_insert(); } template < typename... > void _M_realloc_insert(); }; template < typename _Tp, typename _Alloc > template < typename... > void vector< _Tp, _Alloc >::_M_realloc_insert() { long __trans_tmp_6 = this->_M_impl._M_finish - this->_M_impl._M_start; pointer __old_start = this->_M_impl._M_start; pointer __old_finish = this->_M_impl._M_finish; pointer __new_start(this->_M_allocate(__trans_tmp_6)); pointer __new_finish = __uninitialized_move_if_noexcept_a(__old_finish, __new_finish, 0); _Destroy(__old_start, __old_finish, 0); this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; } class MoveOnly { int data_; public: bool operator==(MoveOnly) { return data_; } }; void __assert_fail(); template < class T > class min_pointer { T *ptr_; min_pointer(T *p) : ptr_(p) { } public: min_pointer() = default; T operator*() { return *ptr_; } void operator++() { ++ptr_; } void operator+=(long n) { ptr_ += n; } min_pointer operator+(long n) { min_pointer tmp(*this); tmp += n; return tmp; } friend long operator-(min_pointer x, min_pointer y) { return x.ptr_ - y.ptr_; } friend bool operator==(min_pointer x, min_pointer y) { return x.ptr_ == y.ptr_; } friend bool operator!=(min_pointer x, min_pointer y) { return !(x == y); } friend class min_allocator; }; class min_allocator { public: typedef MoveOnly value_type; typedef min_pointer< MoveOnly > pointer; pointer allocate(long) { return static_cast< MoveOnly * >(operator new(sizeof(MoveOnly))); } }; int main() { vector< int, min_allocator > v(100); v.insert(v.cbegin(), MoveOnly()); int j = 0; for (; j < 10; ++j) v[j] == MoveOnly() ? void() : __assert_fail(); }
|