[libcxx] r252350 - Allow deque to handle incomplete types.
Evgeniy Stepanov via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 6 14:02:30 PST 2015
Author: eugenis
Date: Fri Nov 6 16:02:29 2015
New Revision: 252350
URL: http://llvm.org/viewvc/llvm-project?rev=252350&view=rev
Log:
Allow deque to handle incomplete types.
Allow deque and deque::iterator instantiation with incomplete element
type. This is an ABI breaking change, and it is only enabled if
LIBCXX_ABI_VERSION >= 2 or LIBCXX_ABI_UNSTABLE=ON.
Added:
libcxx/trunk/test/libcxx/containers/sequences/deque/
libcxx/trunk/test/libcxx/containers/sequences/deque/incomplete.pass.cpp
Modified:
libcxx/trunk/include/__config
libcxx/trunk/include/deque
Modified: libcxx/trunk/include/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=252350&r1=252349&r2=252350&view=diff
==============================================================================
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Fri Nov 6 16:02:29 2015
@@ -34,7 +34,11 @@
#endif
#if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2
+// Change short string represention so that string data starts at offset 0,
+// improving its alignment in some cases.
#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+// Fix deque iterator type in order to support incomplete types.
+#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
#endif
#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
Modified: libcxx/trunk/include/deque
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/deque?rev=252350&r1=252349&r2=252350&view=diff
==============================================================================
--- libcxx/trunk/include/deque (original)
+++ libcxx/trunk/include/deque Fri Nov 6 16:02:29 2015
@@ -261,8 +261,21 @@ move_backward(__deque_iterator<_V1, _P1,
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+template <class _ValueType, class _DiffType>
+struct __deque_block_size {
+ static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
+};
+
template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
- class _DiffType, _DiffType _BlockSize>
+ class _DiffType, _DiffType _BS =
+#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
+// Keep template parameter to avoid changing all template declarations thoughout
+// this file.
+ 0
+#else
+ __deque_block_size<_ValueType, _DiffType>::value
+#endif
+ >
class _LIBCPP_TYPE_VIS_ONLY __deque_iterator
{
typedef _MapPointer __map_iterator;
@@ -273,7 +286,7 @@ private:
__map_iterator __m_iter_;
pointer __ptr_;
- static const difference_type __block_size = _BlockSize;
+ static const difference_type __block_size;
public:
typedef _ValueType value_type;
typedef random_access_iterator_tag iterator_category;
@@ -287,7 +300,7 @@ public:
template <class _Pp, class _Rp, class _MP>
_LIBCPP_INLINE_VISIBILITY
- __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, __block_size>& __it,
+ __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
: __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
@@ -520,6 +533,12 @@ private:
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
};
+template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
+ class _DiffType, _DiffType _BlockSize>
+const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
+ _DiffType, _BlockSize>::__block_size =
+ __deque_block_size<_ValueType, _DiffType>::value;
+
// copy
template <class _RAIter,
@@ -532,10 +551,11 @@ copy(_RAIter __f,
{
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+ const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
while (__f != __l)
{
pointer __rb = __r.__ptr_;
- pointer __re = *__r.__m_iter_ + _B2;
+ pointer __re = *__r.__m_iter_ + __block_size;
difference_type __bs = __re - __rb;
difference_type __n = __l - __f;
_RAIter __m = __l;
@@ -560,11 +580,12 @@ copy(__deque_iterator<_V1, _P1, _R1, _M1
{
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+ const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
difference_type __n = __l - __f;
while (__n > 0)
{
pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + _B1;
+ pointer __fe = *__f.__m_iter_ + __block_size;
difference_type __bs = __fe - __fb;
if (__bs > __n)
{
@@ -587,11 +608,12 @@ copy(__deque_iterator<_V1, _P1, _R1, _M1
{
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+ const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
difference_type __n = __l - __f;
while (__n > 0)
{
pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + _B1;
+ pointer __fe = *__f.__m_iter_ + __block_size;
difference_type __bs = __fe - __fb;
if (__bs > __n)
{
@@ -705,10 +727,11 @@ move(_RAIter __f,
{
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+ const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
while (__f != __l)
{
pointer __rb = __r.__ptr_;
- pointer __re = *__r.__m_iter_ + _B2;
+ pointer __re = *__r.__m_iter_ + __block_size;
difference_type __bs = __re - __rb;
difference_type __n = __l - __f;
_RAIter __m = __l;
@@ -733,11 +756,12 @@ move(__deque_iterator<_V1, _P1, _R1, _M1
{
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+ const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
difference_type __n = __l - __f;
while (__n > 0)
{
pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + _B1;
+ pointer __fe = *__f.__m_iter_ + __block_size;
difference_type __bs = __fe - __fb;
if (__bs > __n)
{
@@ -760,11 +784,12 @@ move(__deque_iterator<_V1, _P1, _R1, _M1
{
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+ const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
difference_type __n = __l - __f;
while (__n > 0)
{
pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + _B1;
+ pointer __fe = *__f.__m_iter_ + __block_size;
difference_type __bs = __fe - __fb;
if (__bs > __n)
{
@@ -909,7 +934,7 @@ protected:
typedef typename __alloc_traits::pointer pointer;
typedef typename __alloc_traits::const_pointer const_pointer;
- static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
+ static const difference_type __block_size;
typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
typedef allocator_traits<__pointer_allocator> __map_traits;
@@ -919,9 +944,9 @@ protected:
typedef __split_buffer<pointer, __pointer_allocator> __map;
typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
- difference_type, __block_size> iterator;
+ difference_type> iterator;
typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
- difference_type, __block_size> const_iterator;
+ difference_type> const_iterator;
__map __map_;
size_type __start_;
@@ -997,6 +1022,11 @@ private:
};
template <class _Tp, class _Allocator>
+const typename __deque_base<_Tp, _Allocator>::difference_type
+ __deque_base<_Tp, _Allocator>::__block_size =
+ __deque_block_size<value_type, difference_type>::value;
+
+template <class _Tp, class _Allocator>
bool
__deque_base<_Tp, _Allocator>::__invariants() const
{
Added: libcxx/trunk/test/libcxx/containers/sequences/deque/incomplete.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/containers/sequences/deque/incomplete.pass.cpp?rev=252350&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/containers/sequences/deque/incomplete.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/containers/sequences/deque/incomplete.pass.cpp Fri Nov 6 16:02:29 2015
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// deque()
+// deque::iterator()
+
+#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
+#include <deque>
+#include <cassert>
+
+struct A {
+ std::deque<A> d;
+ std::deque<A>::iterator it;
+ std::deque<A>::reverse_iterator it2;
+};
+
+int main()
+{
+ A a;
+ assert(a.d.size() == 0);
+ a.it = a.d.begin();
+ a.it2 = a.d.rend();
+}
More information about the cfe-commits
mailing list