summaryrefslogtreecommitdiffstats
path: root/libcxx/include/array
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2018-02-04 02:17:02 +0000
committerEric Fiselier <eric@efcs.ca>2018-02-04 02:17:02 +0000
commit192622dc49d3f7fe31d6512d0e85fd03fbb39a62 (patch)
tree20724db2976a3a2ce0d328306e41b8bfb3a5c496 /libcxx/include/array
parent8d511a65aff2085eba0ad5c6699fefb1f601a0b5 (diff)
downloadbcm5719-llvm-192622dc49d3f7fe31d6512d0e85fd03fbb39a62.tar.gz
bcm5719-llvm-192622dc49d3f7fe31d6512d0e85fd03fbb39a62.zip
Make array<const T, 0> non-CopyAssignable and make swap and fill ill-formed.
The standard isn't exactly clear how std::array should handle zero-sized arrays with const element types. In particular W.R.T. copy assignment, swap, and fill. This patch takes the position that those operations should be ill-formed, and makes changes to libc++ to make it so. This follows up on commit r324182. llvm-svn: 324185
Diffstat (limited to 'libcxx/include/array')
-rw-r--r--libcxx/include/array31
1 files changed, 21 insertions, 10 deletions
diff --git a/libcxx/include/array b/libcxx/include/array
index 8cd3ecdf9e7..4a89ea90d44 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -122,7 +122,8 @@ struct __array_traits {
typedef _Tp _StorageT[_Size];
_LIBCPP_INLINE_VISIBILITY
- static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) {
+ static _LIBCPP_CONSTEXPR_AFTER_CXX14 typename remove_const<_Tp>::type*
+ __data(typename remove_const<_StorageT>::type& __store) {
return __store;
}
@@ -144,12 +145,16 @@ struct __array_traits {
template <class _Tp>
struct __array_traits<_Tp, 0> {
- typedef typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type _StorageT;
+ typedef typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
+ _NonConstStorageT;
+ typedef typename conditional<is_const<_Tp>::value, const _NonConstStorageT,
+ _NonConstStorageT>::type _StorageT;
+ typedef typename remove_const<_Tp>::type _NonConstTp;
_LIBCPP_INLINE_VISIBILITY
- static _Tp* __data(_StorageT& __store) {
+ static _NonConstTp* __data(_NonConstStorageT& __store) {
_StorageT *__ptr = std::addressof(__store);
- return reinterpret_cast<_Tp*>(__ptr);
+ return reinterpret_cast<_NonConstTp*>(__ptr);
}
_LIBCPP_INLINE_VISIBILITY
@@ -162,8 +167,7 @@ struct __array_traits<_Tp, 0> {
static void __swap(_StorageT&, _StorageT&) {}
_LIBCPP_INLINE_VISIBILITY
- static void __fill(_StorageT&, _Tp const&) {
- }
+ static void __fill(_StorageT&, _Tp const&) {}
};
template <class _Tp, size_t _Size>
@@ -187,12 +191,19 @@ struct _LIBCPP_TEMPLATE_VIS array
typename _Traits::_StorageT __elems_;
// No explicit construct/copy/destroy for aggregate type
- _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
- {_Traits::__fill(__elems_, __u);}
+ _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) {
+ static_assert(_Size != 0 || !is_const<_Tp>::value,
+ "cannot fill zero-sized array of type 'const T'");
+ _Traits::__fill(__elems_, __u);
+ }
_LIBCPP_INLINE_VISIBILITY
- void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value)
- { _Traits::__swap(__elems_, __a.__elems_); }
+ void swap(array& __a)
+ _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) {
+ static_assert(_Size != 0 || !is_const<_Tp>::value,
+ "cannot swap zero-sized array of type 'const T'");
+ _Traits::__swap(__elems_, __a.__elems_);
+ }
// iterators:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
OpenPOWER on IntegriCloud