[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