mclow.lists created this revision. `__wrap_iter` is an internal libc++ class that is used as an iterator type when (for some reason) we don't want to use raw pointers as an iterator. It is the iterator type for `vector` and `string` (but not `array` - not sure why). If we used pointers, all the operations on the iterators would be constexpr. With this patch, the corresponding operations on `__wrap_iter` are constexpr as well.
We'll have to do this when http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2938 is adopted. No tests, because all the interesting constructors of `__wrap_iter` are private, and only accessed through friend functions. I have written tests (after making the appropriate ctors public) and they seem to work. https://reviews.llvm.org/D33550 Files: include/algorithm include/iterator
Index: include/iterator =================================================================== --- include/iterator +++ include/iterator @@ -1199,32 +1199,32 @@ template <class _Iter> class __wrap_iter; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; @@ -1236,13 +1236,13 @@ -> decltype(__x.base() - __y.base()); #else template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #endif template <class _Iter> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT_DEBUG; @@ -1254,7 +1254,7 @@ #if _LIBCPP_DEBUG_LEVEL < 2 template <class _Tp> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1265,7 +1265,7 @@ #else template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1288,7 +1288,8 @@ private: iterator_type __i; public: - _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter() _NOEXCEPT_DEBUG #if _LIBCPP_STD_VER > 11 : __i{} #endif @@ -1297,7 +1298,8 @@ __get_db()->__insert_i(this); #endif } - template <class _Up> _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u, + template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter(const __wrap_iter<_Up>& __u, typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT_DEBUG : __i(__u.base()) { @@ -1306,13 +1308,13 @@ #endif } #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 __wrap_iter(const __wrap_iter& __x) : __i(__x.base()) { __get_db()->__iterator_copy(this, &__x); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 __wrap_iter& operator=(const __wrap_iter& __x) { if (this != &__x) @@ -1328,7 +1330,8 @@ __get_db()->__erase_i(this); } #endif - _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator*() const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1336,7 +1339,8 @@ #endif return *__i; } - _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + pointer operator->() const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1344,7 +1348,8 @@ #endif return (pointer)_VSTD::addressof(*__i); } - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter& operator++() _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1353,9 +1358,11 @@ ++__i; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter operator++(int) _NOEXCEPT_DEBUG {__wrap_iter __tmp(*this); ++(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter& operator--() _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), @@ -1364,11 +1371,14 @@ --__i; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter operator--(int) _NOEXCEPT_DEBUG {__wrap_iter __tmp(*this); --(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter operator+ (difference_type __n) const _NOEXCEPT_DEBUG {__wrap_iter __w(*this); __w += __n; return __w;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), @@ -1377,11 +1387,14 @@ __i += __n; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter operator- (difference_type __n) const _NOEXCEPT_DEBUG {return *this + (-__n);} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG {*this += -__n; return *this;} - _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator[](difference_type __n) const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), @@ -1390,17 +1403,21 @@ return __i[__n]; } - _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT_DEBUG {return __i;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + iterator_type base() const _NOEXCEPT_DEBUG {return __i;} -private: +// private: #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter(const void* __p, iterator_type __x) : __i(__x) { __get_db()->__insert_ic(this, __p); } #else - _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {} #endif +private: template <class _Up> friend class __wrap_iter; template <class _CharT, class _Traits, class _Alloc> friend class basic_string; @@ -1408,32 +1425,32 @@ template <class _Iter1, class _Iter2> friend - bool + _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend - bool + _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend - bool + _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend - bool + _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend - bool + _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend - bool + _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #ifndef _LIBCPP_CXX03_LANG @@ -1445,13 +1462,13 @@ #else template <class _Iter1, class _Iter2> friend - typename __wrap_iter<_Iter1>::difference_type + _LIBCPP_CONSTEXPR_AFTER_CXX14 typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #endif template <class _Iter1> friend - __wrap_iter<_Iter1> + _LIBCPP_CONSTEXPR_AFTER_CXX14 __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT_DEBUG; template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op); @@ -1461,7 +1478,7 @@ #if _LIBCPP_DEBUG_LEVEL < 2 template <class _Tp> - friend + friend _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1470,7 +1487,7 @@ __unwrap_iter(__wrap_iter<_Tp*>); #else template <class _Tp> - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1481,7 +1498,7 @@ }; template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1489,7 +1506,7 @@ } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1501,7 +1518,7 @@ } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1509,7 +1526,7 @@ } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1517,7 +1534,7 @@ } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1525,7 +1542,7 @@ } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1533,7 +1550,7 @@ } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1541,7 +1558,7 @@ } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1549,7 +1566,7 @@ } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1557,7 +1574,7 @@ } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1579,7 +1596,7 @@ } #else template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1592,7 +1609,7 @@ #endif template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type __n, __wrap_iter<_Iter> __x) _NOEXCEPT_DEBUG Index: include/algorithm =================================================================== --- include/algorithm +++ include/algorithm @@ -1760,7 +1760,7 @@ } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1774,7 +1774,7 @@ #if _LIBCPP_DEBUG_LEVEL < 2 template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1788,7 +1788,7 @@ #else template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < is_trivially_copy_assignable<_Tp>::value,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits