diff --git a/include/vector b/include/vector index f0677434..e30ce783 100644 --- a/include/vector +++ b/include/vector @@ -34,47 +34,53 @@ public: typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; - explicit vector(const allocator_type& = allocator_type()); + vector() + noexcept(is_nothrow_default_constructible::value); + explicit vector(const allocator_type&); explicit vector(size_type n); vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); vector(const vector& x); - vector(vector&& x); + vector(vector&& x) + noexcept(is_nothrow_move_constructible::value); vector(initializer_list il); vector(initializer_list il, const allocator_type& a); ~vector(); vector& operator=(const vector& x); - vector& operator=(vector&& x); + vector& operator=(vector&& x) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); vector& operator=(initializer_list il); template void assign(InputIterator first, InputIterator last); void assign(size_type n, const value_type& u); void assign(initializer_list il); - allocator_type get_allocator() const; + allocator_type get_allocator() const noexcept; - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; - reverse_iterator rbegin(); - const_reverse_iterator rbegin() const; - reverse_iterator rend(); - const_reverse_iterator rend() const; + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const; - const_iterator cend() const; - const_reverse_iterator crbegin() const; - const_reverse_iterator crend() const; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; - size_type size() const; - size_type max_size() const; - size_type capacity() const; - bool empty() const; + size_type size() const noexcept; + size_type max_size() const noexcept; + size_type capacity() const noexcept; + bool empty() const noexcept; void reserve(size_type n); - void shrink_to_fit(); + void shrink_to_fit() noexcept; reference operator[](size_type n); const_reference operator[](size_type n) const; @@ -86,8 +92,8 @@ public: reference back(); const_reference back() const; - value_type* data(); - const value_type* data() const; + value_type* data() noexcept; + const value_type* data() const noexcept; void push_back(const value_type& x); void push_back(value_type&& x); @@ -106,12 +112,14 @@ public: iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); - void clear(); + void clear() noexcept; void resize(size_type sz); void resize(size_type sz, const value_type& c); - void swap(vector&); + void swap(vector&) + noexcept(!allocator_type::propagate_on_container_swap::value || + __is_nothrow_swappable::value); bool __invariants() const; }; @@ -134,62 +142,68 @@ public: class reference { public: - reference(const reference&); - operator bool() const; - reference& operator=(const bool x); - reference& operator=(const reference& x); - iterator operator&() const; - void flip(); + reference(const reference&) noexcept; + operator bool() const noexcept; + reference& operator=(const bool x) noexcept; + reference& operator=(const reference& x) noexcept; + iterator operator&() const noexcept; + void flip() noexcept; }; class const_reference { public: - const_reference(const reference&); - operator bool() const; - const_iterator operator&() const; + const_reference(const reference&) noexcept; + operator bool() const noexcept; + const_iterator operator&() const noexcept; }; + vector() + noexcept(is_nothrow_default_constructible::value); explicit vector(const allocator_type& = allocator_type()); explicit vector(size_type n, const value_type& value = value_type(), const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); vector(const vector& x); - vector(vector&& x); + vector(vector&& x) + noexcept(is_nothrow_move_constructible::value); vector(initializer_list il); vector(initializer_list il, const allocator_type& a); ~vector(); vector& operator=(const vector& x); - vector& operator=(vector&& x); + vector& operator=(vector&& x) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); vector& operator=(initializer_list il); template void assign(InputIterator first, InputIterator last); void assign(size_type n, const value_type& u); void assign(initializer_list il); - allocator_type get_allocator() const; + allocator_type get_allocator() const noexcept; - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; - reverse_iterator rbegin(); - const_reverse_iterator rbegin() const; - reverse_iterator rend(); - const_reverse_iterator rend() const; + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const; - const_iterator cend() const; - const_reverse_iterator crbegin() const; - const_reverse_iterator crend() const; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; - size_type size() const; - size_type max_size() const; - size_type capacity() const; - bool empty() const; + size_type size() const noexcept; + size_type max_size() const noexcept; + size_type capacity() const noexcept; + bool empty() const noexcept; void reserve(size_type n); - void shrink_to_fit(); + void shrink_to_fit() noexcept; reference operator[](size_type n); const_reference operator[](size_type n) const; @@ -213,13 +227,15 @@ public: iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); - void clear(); + void clear() noexcept; void resize(size_type sz); void resize(size_type sz, value_type x); - void swap(vector&); - void flip(); + void swap(vector&) + noexcept(!allocator_type::propagate_on_container_swap::value || + __is_nothrow_swappable::value); + void flip() noexcept; bool __invariants() const; }; @@ -233,7 +249,9 @@ template bool operator> (const vector& x template bool operator>=(const vector& x, const vector& y); template bool operator<=(const vector& x, const vector& y); -template void swap(vector& x, vector& y); +template +void swap(vector& x, vector& y) + noexcept(noexcept(x.swap(y))); } // std @@ -313,22 +331,38 @@ protected: pointer __end_; __compressed_pair __end_cap_; - _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __end_cap_.second();} - _LIBCPP_INLINE_VISIBILITY const allocator_type& __alloc() const {return __end_cap_.second();} - _LIBCPP_INLINE_VISIBILITY pointer& __end_cap() {return __end_cap_.first();} - _LIBCPP_INLINE_VISIBILITY const pointer& __end_cap() const {return __end_cap_.first();} + _LIBCPP_INLINE_VISIBILITY + allocator_type& __alloc() _NOEXCEPT + {return __end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY + const allocator_type& __alloc() const _NOEXCEPT + {return __end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY + pointer& __end_cap() _NOEXCEPT + {return __end_cap_.first();} + _LIBCPP_INLINE_VISIBILITY + const pointer& __end_cap() const _NOEXCEPT + {return __end_cap_.first();} - _LIBCPP_INLINE_VISIBILITY __vector_base(); + _LIBCPP_INLINE_VISIBILITY + __vector_base() + _NOEXCEPT_(is_nothrow_default_constructible::value); _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a); ~__vector_base(); - _LIBCPP_INLINE_VISIBILITY void clear() {__destruct_at_end(__begin_);} - _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast(__end_cap() - __begin_);} + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT {__destruct_at_end(__begin_);} + _LIBCPP_INLINE_VISIBILITY + size_type capacity() const _NOEXCEPT + {return static_cast(__end_cap() - __begin_);} - _LIBCPP_INLINE_VISIBILITY void __destruct_at_end(const_pointer __new_last) + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(const_pointer __new_last) _NOEXCEPT {__destruct_at_end(__new_last, is_trivially_destructible());} - _LIBCPP_INLINE_VISIBILITY void __destruct_at_end(const_pointer __new_last, false_type); - _LIBCPP_INLINE_VISIBILITY void __destruct_at_end(const_pointer __new_last, true_type); + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __vector_base& __c) @@ -337,11 +371,17 @@ protected: _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__vector_base& __c) + _NOEXCEPT_( + !__alloc_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable::value) {__move_assign_alloc(__c, integral_constant());} _LIBCPP_INLINE_VISIBILITY static void __swap_alloc(allocator_type& __x, allocator_type& __y) + _NOEXCEPT_( + !__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value) {__swap_alloc(__x, __y, integral_constant());} private: @@ -363,29 +403,33 @@ private: _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(const __vector_base& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) { __alloc() = _STD::move(__c.__alloc()); } _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(const __vector_base& __c, false_type) + _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) { using _STD::swap; swap(__x, __y); } _LIBCPP_INLINE_VISIBILITY static void __swap_alloc(allocator_type& __x, allocator_type& __y, false_type) + _NOEXCEPT {} }; template _LIBCPP_INLINE_VISIBILITY inline void -__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, false_type) +__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT { while (__new_last < __end_) __alloc_traits::destroy(__alloc(), const_cast(--__end_)); @@ -394,7 +438,7 @@ __vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, fals template _LIBCPP_INLINE_VISIBILITY inline void -__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, true_type) +__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT { __end_ = const_cast(__new_last); } @@ -402,6 +446,7 @@ __vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, true template _LIBCPP_INLINE_VISIBILITY inline __vector_base<_Tp, _Allocator>::__vector_base() + _NOEXCEPT_(is_nothrow_default_constructible::value) : __begin_(0), __end_(0), __end_cap_(0) @@ -465,7 +510,10 @@ public: typedef _STD::reverse_iterator reverse_iterator; typedef _STD::reverse_iterator const_reverse_iterator; - _LIBCPP_INLINE_VISIBILITY vector() {} + _LIBCPP_INLINE_VISIBILITY + vector() + _NOEXCEPT_(is_nothrow_default_constructible::value) + {} _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) : __base(__a) {} explicit vector(size_type __n); vector(size_type __n, const_reference __x); @@ -499,11 +547,15 @@ public: vector& operator=(const vector& __x); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY - vector(vector&& __x); + vector(vector&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value); _LIBCPP_INLINE_VISIBILITY vector(vector&& __x, const allocator_type& __a); _LIBCPP_INLINE_VISIBILITY - vector& operator=(vector&& __x); + vector& operator=(vector&& __x) + _NOEXCEPT_( + __alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY vector& operator=(initializer_list __il) @@ -530,29 +582,53 @@ public: void assign(initializer_list __il) {assign(__il.begin(), __il.end());} - _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const {return this->__alloc();} + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const _NOEXCEPT + {return this->__alloc();} - _LIBCPP_INLINE_VISIBILITY iterator begin(); - _LIBCPP_INLINE_VISIBILITY const_iterator begin() const; - _LIBCPP_INLINE_VISIBILITY iterator end(); - _LIBCPP_INLINE_VISIBILITY const_iterator end() const; + _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const {return const_reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT + {return reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT + {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT + {return reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT + {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const {return begin();} - _LIBCPP_INLINE_VISIBILITY const_iterator cend() const {return end();} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const {return rbegin();} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const {return rend();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT + {return begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT + {return end();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT + {return rbegin();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT + {return rend();} - _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast(this->__end_ - this->__begin_);} - _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return __base::capacity();} - _LIBCPP_INLINE_VISIBILITY bool empty() const {return this->__begin_ == this->__end_;} - size_type max_size() const; + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT + {return static_cast(this->__end_ - this->__begin_);} + _LIBCPP_INLINE_VISIBILITY + size_type capacity() const _NOEXCEPT + {return __base::capacity();} + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT + {return this->__begin_ == this->__end_;} + size_type max_size() const _NOEXCEPT; void reserve(size_type __n); - void shrink_to_fit(); + void shrink_to_fit() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n); _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const; @@ -564,9 +640,11 @@ public: _LIBCPP_INLINE_VISIBILITY reference back() {return *(this->__end_ - 1);} _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(this->__end_ - 1);} - _LIBCPP_INLINE_VISIBILITY value_type* data() + _LIBCPP_INLINE_VISIBILITY + value_type* data() _NOEXCEPT {return _STD::__to_raw_pointer(this->__begin_);} - _LIBCPP_INLINE_VISIBILITY const value_type* data() const + _LIBCPP_INLINE_VISIBILITY + const value_type* data() const _NOEXCEPT {return _STD::__to_raw_pointer(this->__begin_);} _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x); @@ -610,19 +688,23 @@ public: _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position); iterator erase(const_iterator __first, const_iterator __last); - _LIBCPP_INLINE_VISIBILITY void clear() {__base::clear();} + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT + {__base::clear();} void resize(size_type __sz); void resize(size_type __sz, const_reference __x); - void swap(vector&); + void swap(vector&) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value); bool __invariants() const; private: _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); void allocate(size_type __n); - void deallocate(); + void deallocate() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const; void __construct_at_end(size_type __n); void __construct_at_end(size_type __n, const_reference __x); @@ -637,13 +719,14 @@ private: void __append(size_type __n); void __append(size_type __n, const_reference __x); _LIBCPP_INLINE_VISIBILITY - iterator __make_iter(pointer __p); + iterator __make_iter(pointer __p) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY - const_iterator __make_iter(const_pointer __p) const; + const_iterator __make_iter(const_pointer __p) const _NOEXCEPT; void __swap_out_circular_buffer(__split_buffer& __v); pointer __swap_out_circular_buffer(__split_buffer& __v, pointer __p); void __move_range(pointer __from_s, pointer __from_e, pointer __to); - void __move_assign(vector& __c, true_type); + void __move_assign(vector& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value); void __move_assign(vector& __c, false_type); }; @@ -652,7 +735,7 @@ void vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v) { for (pointer __p = this->__end_; this->__begin_ < __p;) - __v.push_front(_STD::move(*--__p)); + __v.push_front(_STD::move_if_noexcept(*--__p)); _STD::swap(this->__begin_, __v.__begin_); _STD::swap(this->__end_, __v.__end_); _STD::swap(this->__end_cap(), __v.__end_cap()); @@ -666,9 +749,9 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer__begin_ < __i;) - __v.push_front(_STD::move(*--__i)); + __v.push_front(_STD::move_if_noexcept(*--__i)); for (pointer __i = __p; __i < this->__end_; ++__i) - __v.push_back(_STD::move(*__i)); + __v.push_back(_STD::move_if_noexcept(*__i)); _STD::swap(this->__begin_, __v.__begin_); _STD::swap(this->__end_, __v.__end_); _STD::swap(this->__end_cap(), __v.__end_cap()); @@ -696,7 +779,7 @@ vector<_Tp, _Allocator>::allocate(size_type __n) template void -vector<_Tp, _Allocator>::deallocate() +vector<_Tp, _Allocator>::deallocate() _NOEXCEPT { if (this->__begin_ != 0) { @@ -709,7 +792,7 @@ vector<_Tp, _Allocator>::deallocate() template typename vector<_Tp, _Allocator>::size_type -vector<_Tp, _Allocator>::max_size() const +vector<_Tp, _Allocator>::max_size() const _NOEXCEPT { return _STD::min(__alloc_traits::max_size(this->__alloc()), numeric_limits::max() / 2); // end() >= begin(), always } @@ -800,7 +883,7 @@ vector<_Tp, _Allocator>::__move_construct_at_end(pointer __first, pointer __last // Default constructs __n objects starting at __end_ // throws if construction throws // Postcondition: size() == size() + __n -// Exception safety: strong but assumes move ctor doesn't throw (copy ctor can) +// Exception safety: strong. template void vector<_Tp, _Allocator>::__append(size_type __n) @@ -819,7 +902,7 @@ vector<_Tp, _Allocator>::__append(size_type __n) // Default constructs __n objects starting at __end_ // throws if construction throws // Postcondition: size() == size() + __n -// Exception safety: strong but assumes move ctor doesn't throw (copy ctor can) +// Exception safety: strong. template void vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) @@ -943,6 +1026,7 @@ vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a) template _LIBCPP_INLINE_VISIBILITY inline vector<_Tp, _Allocator>::vector(vector&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) : __base(_STD::move(__x.__alloc())) { this->__begin_ = __x.__begin_; @@ -999,6 +1083,9 @@ template _LIBCPP_INLINE_VISIBILITY inline vector<_Tp, _Allocator>& vector<_Tp, _Allocator>::operator=(vector&& __x) + _NOEXCEPT_( + __alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) { __move_assign(__x, integral_constant()); @@ -1021,6 +1108,7 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type) template void vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) { deallocate(); this->__begin_ = __c.__begin_; @@ -1118,7 +1206,7 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) template _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::__make_iter(pointer __p) +vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT { #ifdef _LIBCPP_DEBUG return iterator(this, __p); @@ -1130,7 +1218,7 @@ vector<_Tp, _Allocator>::__make_iter(pointer __p) template _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::const_iterator -vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const +vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT { #ifdef _LIBCPP_DEBUG return const_iterator(this, __p); @@ -1142,7 +1230,7 @@ vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const template _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::begin() +vector<_Tp, _Allocator>::begin() _NOEXCEPT { return __make_iter(this->__begin_); } @@ -1150,7 +1238,7 @@ vector<_Tp, _Allocator>::begin() template _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::const_iterator -vector<_Tp, _Allocator>::begin() const +vector<_Tp, _Allocator>::begin() const _NOEXCEPT { return __make_iter(this->__begin_); } @@ -1158,7 +1246,7 @@ vector<_Tp, _Allocator>::begin() const template _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::end() +vector<_Tp, _Allocator>::end() _NOEXCEPT { return __make_iter(this->__end_); } @@ -1166,7 +1254,7 @@ vector<_Tp, _Allocator>::end() template _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::const_iterator -vector<_Tp, _Allocator>::end() const +vector<_Tp, _Allocator>::end() const _NOEXCEPT { return __make_iter(this->__end_); } @@ -1218,17 +1306,14 @@ vector<_Tp, _Allocator>::reserve(size_type __n) if (__n > capacity()) { allocator_type& __a = this->__alloc(); - __split_buffer __v(__n, 0, __a); - __v.__construct_at_end(move_iterator(this->__begin_), - move_iterator(this->__end_)); - clear(); + __split_buffer __v(__n, size(), __a); __swap_out_circular_buffer(__v); } } template void -vector<_Tp, _Allocator>::shrink_to_fit() +vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT { if (capacity() > size()) { @@ -1237,10 +1322,7 @@ vector<_Tp, _Allocator>::shrink_to_fit() { #endif // _LIBCPP_NO_EXCEPTIONS allocator_type& __a = this->__alloc(); - __split_buffer __v(size(), 0, __a); - __v.__construct_at_end(move_iterator(this->__begin_), - move_iterator(this->__end_)); - clear(); + __split_buffer __v(size(), size(), __a); __swap_out_circular_buffer(__v); #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1613,6 +1695,8 @@ vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) template void vector<_Tp, _Allocator>::swap(vector& __x) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value) { _STD::swap(this->__begin_, __x.__begin_); _STD::swap(this->__end_, __x.__end_); @@ -1714,20 +1798,32 @@ private: size_type __size_; __compressed_pair __cap_alloc_; - _LIBCPP_INLINE_VISIBILITY size_type& __cap() {return __cap_alloc_.first();} - _LIBCPP_INLINE_VISIBILITY const size_type& __cap() const {return __cap_alloc_.first();} - _LIBCPP_INLINE_VISIBILITY __storage_allocator& __alloc() {return __cap_alloc_.second();} - _LIBCPP_INLINE_VISIBILITY const __storage_allocator& __alloc() const {return __cap_alloc_.second();} + _LIBCPP_INLINE_VISIBILITY + size_type& __cap() _NOEXCEPT + {return __cap_alloc_.first();} + _LIBCPP_INLINE_VISIBILITY + const size_type& __cap() const _NOEXCEPT + {return __cap_alloc_.first();} + _LIBCPP_INLINE_VISIBILITY + __storage_allocator& __alloc() _NOEXCEPT + {return __cap_alloc_.second();} + _LIBCPP_INLINE_VISIBILITY + const __storage_allocator& __alloc() const _NOEXCEPT + {return __cap_alloc_.second();} static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); - _LIBCPP_INLINE_VISIBILITY static size_type __internal_cap_to_external(size_type __n) + _LIBCPP_INLINE_VISIBILITY + static size_type __internal_cap_to_external(size_type __n) _NOEXCEPT {return __n * __bits_per_word;} - _LIBCPP_INLINE_VISIBILITY static size_type __external_cap_to_internal(size_type __n) + _LIBCPP_INLINE_VISIBILITY + static size_type __external_cap_to_internal(size_type __n) _NOEXCEPT {return (__n - 1) / __bits_per_word + 1;} public: - _LIBCPP_INLINE_VISIBILITY vector(); + _LIBCPP_INLINE_VISIBILITY + vector() + _NOEXCEPT_(is_nothrow_default_constructible::value); _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a); ~vector(); explicit vector(size_type __n); @@ -1755,9 +1851,15 @@ public: vector(initializer_list __il, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY vector(vector&& __v); + _LIBCPP_INLINE_VISIBILITY + vector(vector&& __v) + _NOEXCEPT_(is_nothrow_move_constructible::value); vector(vector&& __v, const allocator_type& __a); - _LIBCPP_INLINE_VISIBILITY vector& operator=(vector&& __v); + _LIBCPP_INLINE_VISIBILITY + vector& operator=(vector&& __v) + _NOEXCEPT_( + __alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY vector& operator=(initializer_list __il) @@ -1784,30 +1886,60 @@ public: void assign(initializer_list __il) {assign(__il.begin(), __il.end());} - _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const + _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT {return allocator_type(this->__alloc());} - size_type max_size() const; - _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return __internal_cap_to_external(__cap());} - _LIBCPP_INLINE_VISIBILITY size_type size() const {return __size_;} - _LIBCPP_INLINE_VISIBILITY bool empty() const {return __size_ == 0;} + size_type max_size() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type capacity() const _NOEXCEPT + {return __internal_cap_to_external(__cap());} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT + {return __size_;} + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT + {return __size_ == 0;} void reserve(size_type __n); - void shrink_to_fit(); + void shrink_to_fit() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY iterator begin() {return __make_iter(0);} - _LIBCPP_INLINE_VISIBILITY const_iterator begin() const {return __make_iter(0);} - _LIBCPP_INLINE_VISIBILITY iterator end() {return __make_iter(__size_);} - _LIBCPP_INLINE_VISIBILITY const_iterator end() const {return __make_iter(__size_);} + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT + {return __make_iter(0);} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT + {return __make_iter(0);} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT + {return __make_iter(__size_);} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT + {return __make_iter(__size_);} - _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const {return const_reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT + {return reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT + {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT + {return reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT + {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const {return __make_iter(0);} - _LIBCPP_INLINE_VISIBILITY const_iterator cend() const {return __make_iter(__size_);} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const {return rbegin();} - _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const {return rend();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT + {return __make_iter(0);} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT + {return __make_iter(__size_);} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT + {return rbegin();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT + {return rend();} _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) {return __make_ref(__n);} _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __make_ref(__n);} @@ -1847,20 +1979,24 @@ public: _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position); iterator erase(const_iterator __first, const_iterator __last); - _LIBCPP_INLINE_VISIBILITY void clear() {__size_ = 0;} + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT {__size_ = 0;} - void swap(vector&); + void swap(vector&) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value); void resize(size_type __sz, value_type __x = false); - void flip(); + void flip() _NOEXCEPT; bool __invariants() const; private: _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); void allocate(size_type __n); - void deallocate(); - _LIBCPP_INLINE_VISIBILITY static size_type __align(size_type __new_size) + void deallocate() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static size_type __align(size_type __new_size) _NOEXCEPT {return __new_size + (__bits_per_word-1) & ~(__bits_per_word-1);}; _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const; _LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x); @@ -1872,9 +2008,11 @@ private: >::type __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); void __append(size_type __n, const_reference __x); - _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_type __pos) + _LIBCPP_INLINE_VISIBILITY + reference __make_ref(size_type __pos) _NOEXCEPT {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} - _LIBCPP_INLINE_VISIBILITY const_reference __make_ref(size_type __pos) const + _LIBCPP_INLINE_VISIBILITY + const_reference __make_ref(size_type __pos) const _NOEXCEPT {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} #ifdef _LIBCPP_DEBUG _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_type __pos) @@ -1884,11 +2022,14 @@ private: _LIBCPP_INLINE_VISIBILITY iterator __const_iterator_cast(const_iterator __p) {return iterator(this, pointer(const_cast<__storage_pointer>(__p.base().__seg_), __p.base().__ctz_));} #else // _LIBCPP_DEBUG - _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_type __pos) + _LIBCPP_INLINE_VISIBILITY + iterator __make_iter(size_type __pos) _NOEXCEPT {return iterator(__begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} - _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_type __pos) const + _LIBCPP_INLINE_VISIBILITY + const_iterator __make_iter(size_type __pos) const _NOEXCEPT {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} - _LIBCPP_INLINE_VISIBILITY iterator __const_iterator_cast(const_iterator __p) + _LIBCPP_INLINE_VISIBILITY + iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT {return iterator(const_cast<__storage_pointer>(__p.__seg_), __p.__ctz_);} #endif // _LIBCPP_DEBUG @@ -1909,37 +2050,48 @@ private: {} void __move_assign(vector& __c, false_type); - void __move_assign(vector& __c, true_type); + void __move_assign(vector& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value); _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(vector& __c) + _NOEXCEPT_( + !__storage_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable::value) {__move_assign_alloc(__c, integral_constant());} _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(const vector& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) { __alloc() = _STD::move(__c.__alloc()); } _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(const vector& __c, false_type) + _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y) + _NOEXCEPT_( + !__storage_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value) {__swap_alloc(__x, __y, integral_constant());} _LIBCPP_INLINE_VISIBILITY static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y, true_type) + _NOEXCEPT_(__is_nothrow_swappable::value) { using _STD::swap; swap(__x, __y); } _LIBCPP_INLINE_VISIBILITY static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y, false_type) + _NOEXCEPT {} - size_t __hash_code() const; + size_t __hash_code() const _NOEXCEPT; friend class __bit_reference; friend class __bit_const_reference; @@ -1983,7 +2135,7 @@ vector::allocate(size_type __n) template void -vector::deallocate() +vector::deallocate() _NOEXCEPT { if (this->__begin_ != 0) { @@ -1996,7 +2148,7 @@ vector::deallocate() template typename vector::size_type -vector::max_size() const +vector::max_size() const _NOEXCEPT { size_type __amax = __storage_traits::max_size(__alloc()); size_type __nmax = numeric_limits::max() / 2; // end() >= begin(), always @@ -2051,6 +2203,7 @@ vector::__construct_at_end(_ForwardIterator __first, _ForwardI template _LIBCPP_INLINE_VISIBILITY inline vector::vector() + _NOEXCEPT_(is_nothrow_default_constructible::value) : __begin_(0), __size_(0), __cap_alloc_(0) @@ -2281,6 +2434,7 @@ vector::operator=(const vector& __v) template _LIBCPP_INLINE_VISIBILITY inline vector::vector(vector&& __v) + _NOEXCEPT_(is_nothrow_move_constructible::value) : __begin_(__v.__begin_), __size_(__v.__size_), __cap_alloc_(__v.__cap_alloc_) @@ -2315,6 +2469,9 @@ template _LIBCPP_INLINE_VISIBILITY inline vector& vector::operator=(vector&& __v) + _NOEXCEPT_( + __alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) { __move_assign(__v, integral_constant()); @@ -2333,6 +2490,7 @@ vector::__move_assign(vector& __c, false_type) template void vector::__move_assign(vector& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) { deallocate(); this->__begin_ = __c.__begin_; @@ -2419,7 +2577,7 @@ vector::reserve(size_type __n) template void -vector::shrink_to_fit() +vector::shrink_to_fit() _NOEXCEPT { if (__external_cap_to_internal(size()) > __cap()) { @@ -2618,6 +2776,8 @@ vector::erase(const_iterator __first, const_iterator __last) template void vector::swap(vector& __x) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value) { _STD::swap(this->__begin_, __x.__begin_); _STD::swap(this->__size_, __x.__size_); @@ -2660,7 +2820,7 @@ vector::resize(size_type __sz, value_type __x) template void -vector::flip() +vector::flip() _NOEXCEPT { // do middle whole words size_type __n = __size_; @@ -2698,7 +2858,7 @@ vector::__invariants() const template size_t -vector::__hash_code() const +vector::__hash_code() const _NOEXCEPT { size_t __h = 0; // do middle whole words @@ -2720,7 +2880,7 @@ struct _LIBCPP_VISIBLE hash > : public unary_function, size_t> { _LIBCPP_INLINE_VISIBILITY - size_t operator()(const vector& __vec) const + size_t operator()(const vector& __vec) const _NOEXCEPT {return __vec.__hash_code();} }; @@ -2777,6 +2937,7 @@ template _LIBCPP_INLINE_VISIBILITY inline void swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } diff --git a/test/containers/sequences/vector.bool/default_noexcept.pass.cpp b/test/containers/sequences/vector.bool/default_noexcept.pass.cpp new file mode 100644 index 00000000..2f772066 --- /dev/null +++ b/test/containers/sequences/vector.bool/default_noexcept.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// vector() +// noexcept(is_nothrow_default_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector.bool/dtor_noexcept.pass.cpp b/test/containers/sequences/vector.bool/dtor_noexcept.pass.cpp new file mode 100644 index 00000000..9c0b4e49 --- /dev/null +++ b/test/containers/sequences/vector.bool/dtor_noexcept.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// ~vector() // implied noexcept; + +#include +#include + +#include "../../test_allocator.h" + +#if __has_feature(cxx_noexcept) + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); + ~some_alloc() noexcept(false); +}; + +#endif + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_destructible::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp b/test/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp new file mode 100644 index 00000000..8aaa7709 --- /dev/null +++ b/test/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// vector& operator=(vector&& c) +// noexcept( +// allocator_type::propagate_on_container_move_assignment::value && +// is_nothrow_move_assignable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector.bool/move_noexcept.pass.cpp b/test/containers/sequences/vector.bool/move_noexcept.pass.cpp new file mode 100644 index 00000000..364c3024 --- /dev/null +++ b/test/containers/sequences/vector.bool/move_noexcept.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// vector(vector&&) +// noexcept(is_nothrow_move_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_move_constructible::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector.bool/swap_noexcept.pass.cpp b/test/containers/sequences/vector.bool/swap_noexcept.pass.cpp new file mode 100644 index 00000000..99fa51fa --- /dev/null +++ b/test/containers/sequences/vector.bool/swap_noexcept.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void swap(vector& c) +// noexcept(!allocator_type::propagate_on_container_swap::value || +// __is_nothrow_swappable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + + some_alloc() {} + some_alloc(const some_alloc&); + void deallocate(void*, unsigned) {} + + typedef std::true_type propagate_on_container_swap; +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::vector> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::vector> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::vector> C; + C c1, c2; + static_assert(!noexcept(swap(c1, c2)), ""); + } +#endif +} diff --git a/test/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp b/test/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp new file mode 100644 index 00000000..5c378c5d --- /dev/null +++ b/test/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// vector() +// noexcept(is_nothrow_default_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp b/test/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp new file mode 100644 index 00000000..843c067b --- /dev/null +++ b/test/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// ~vector() // implied noexcept; + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +#if __has_feature(cxx_noexcept) + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); + ~some_alloc() noexcept(false); +}; + +#endif + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_destructible::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp b/test/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp new file mode 100644 index 00000000..30ff5be4 --- /dev/null +++ b/test/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// vector& operator=(vector&& c) +// noexcept( +// allocator_type::propagate_on_container_move_assignment::value && +// is_nothrow_move_assignable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp b/test/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp new file mode 100644 index 00000000..57e03225 --- /dev/null +++ b/test/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// vector(vector&&) +// noexcept(is_nothrow_move_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + some_alloc(const some_alloc&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::vector> C; + static_assert(!std::is_nothrow_move_constructible::value, ""); + } +#endif +} diff --git a/test/containers/sequences/vector/vector.special/swap_noexcept.pass.cpp b/test/containers/sequences/vector/vector.special/swap_noexcept.pass.cpp new file mode 100644 index 00000000..714bd459 --- /dev/null +++ b/test/containers/sequences/vector/vector.special/swap_noexcept.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void swap(vector& c) +// noexcept(!allocator_type::propagate_on_container_swap::value || +// __is_nothrow_swappable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_alloc +{ + typedef T value_type; + + some_alloc() {} + some_alloc(const some_alloc&); + void deallocate(void*, unsigned) {} + + typedef std::true_type propagate_on_container_swap; +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::vector C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::vector> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::vector> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::vector> C; + C c1, c2; + static_assert(!noexcept(swap(c1, c2)), ""); + } +#endif +}