re PR libstdc++/49561 ([C++0x] std::list::size complexity)
authorJonathan Wakely <jwakely@redhat.com>
Fri, 10 Oct 2014 15:33:57 +0000 (16:33 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 10 Oct 2014 15:33:57 +0000 (16:33 +0100)
PR libstdc++/49561
* acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI): Define.
* configure.ac: Use GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI.
* configure: Regenerate.
* include/Makefile.am (stamp-cxx11-abi): New target.
(c++config.h): Set _GLIBCXX_USE_CXX11_ABI macro.
* include/Makefile.in: Regenerate.
* include/bits/c++config: Add _GLIBCXX_USE_CXX11_ABI placeholder and
define _GLIBCXX_DEFAULT_ABI_TAG.
* include/bits/list.tcc (list::emplace(const_iterator, _Args&...)):
Increment size.
(list::emplace(const_iterator, const value_type&)): Likewise.
(list::merge(list&), list::merge(list&, _StrictWeakOrdering)): Adjust
list sizes.
* include/bits/stl_list.h (_List_base, list): Add ABI tag macro.
(_List_base::_M_size): New data member in cxx11 ABI mode.
(_List_base::_S_distance(_List_node_base*, _List_node_base*)): New
function.
(_List_base::_M_get_size(), _List_base::_M_set_size(size_t),
_List_base::_M_inc_size(size_t), _List_base::_M_dec_size(size_t),
_List_base::_M_distance, _List_base::_M_node_count): New functions for
accessing list size correctly for the ABI mode.
(_List_base::_List_base(_List_base&&)): Copy size and reset source.
(_List_base::_M_init()): Initialize size member.
(list::size()): Use _List_base::_M_node_count.
(list::swap(list&)): Swap sizes.
(list::splice(iterator, list&)): Update sizes.
(list::splice(iterator, list&, iterator)): Likewise.
(list::insert(iterator, const value_type&)): Update size.
(list::insert(iterator, _Args&&...)): Likewise.
(list::_M_erase(iterator)): Likewise.
* testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
Adjust.
* testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc:
Adjust.
* testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc:
Adjust.
* testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
Adjust.
* testsuite/ext/profile/mutex_extensions_neg.cc: Adjust.

From-SVN: r216094

14 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/acinclude.m4
libstdc++-v3/configure
libstdc++-v3/configure.ac
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/c++config
libstdc++-v3/include/bits/list.tcc
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc

index 69ec7fff36d99369651f56c1b28d771a8391c70b..1171d83eb37ddf2628dbd1f9b952ce4ba02bf6c4 100644 (file)
@@ -1,3 +1,46 @@
+2014-10-07  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/49561
+       * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI): Define.
+       * configure.ac: Use GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI.
+       * configure: Regenerate.
+       * include/Makefile.am (stamp-cxx11-abi): New target.
+       (c++config.h): Set _GLIBCXX_USE_CXX11_ABI macro.
+       * include/Makefile.in: Regenerate.
+       * include/bits/c++config: Add _GLIBCXX_USE_CXX11_ABI placeholder and
+       define _GLIBCXX_DEFAULT_ABI_TAG.
+       * include/bits/list.tcc (list::emplace(const_iterator, _Args&...)):
+       Increment size.
+       (list::emplace(const_iterator, const value_type&)): Likewise.
+       (list::merge(list&), list::merge(list&, _StrictWeakOrdering)): Adjust
+       list sizes.
+       * include/bits/stl_list.h (_List_base, list): Add ABI tag macro.
+       (_List_base::_M_size): New data member in cxx11 ABI mode.
+       (_List_base::_S_distance(_List_node_base*, _List_node_base*)): New
+       function.
+       (_List_base::_M_get_size(), _List_base::_M_set_size(size_t),
+       _List_base::_M_inc_size(size_t), _List_base::_M_dec_size(size_t),
+       _List_base::_M_distance, _List_base::_M_node_count): New functions for
+       accessing list size correctly for the ABI mode.
+       (_List_base::_List_base(_List_base&&)): Copy size and reset source.
+       (_List_base::_M_init()): Initialize size member.
+       (list::size()): Use _List_base::_M_node_count.
+       (list::swap(list&)): Swap sizes.
+       (list::splice(iterator, list&)): Update sizes.
+       (list::splice(iterator, list&, iterator)): Likewise.
+       (list::insert(iterator, const value_type&)): Update size.
+       (list::insert(iterator, _Args&&...)): Likewise.
+       (list::_M_erase(iterator)): Likewise.
+       * testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
+       Adjust.
+       * testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc:
+       Adjust.
+       * testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc:
+       Adjust.
+       * testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
+       Adjust.
+       * testsuite/ext/profile/mutex_extensions_neg.cc: Adjust.
+
 2014-10-09  Jonathan Wakely  <jwakely@redhat.com>
 
        * doc/xml/manual/status_cxx2011.xml: Update.
index 2650a5acfccedd3fb3ed054e0091ac393ac62f9d..0229609df2c97da2ba3759b252b87ea2786db047 100644 (file)
@@ -3831,6 +3831,25 @@ AC_DEFUN([GLIBCXX_CHECK_SDT_H], [
   AC_MSG_RESULT($glibcxx_cv_sys_sdt_h)
 ])
 
+dnl
+dnl Check if the user wants the new C++11-conforming ABI.
+dnl
+dnl --disable-libstdcxx-cxx11-abi will use old ABI for all types.
+dnl
+dnl Defines:
+dnl  _GLIBCXX_USE_ABI_TAG (always defined, either to 1 or 0)
+dnl
+AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI], [
+  AC_ARG_ENABLE([libstdcxx-cxx11-abi],
+    AC_HELP_STRING([--disable-libstdcxx-cxx11-abi],
+                  [disable the C++11-conforming ABI]),,
+                  [enable_libstdcxx_cxx11_abi=yes])
+  if test x"$enable_libstdcxx_cxx11_abi" != xyes; then
+    AC_MSG_NOTICE([C++11-conforming ABI is disabled])
+  fi
+  GLIBCXX_CONDITIONAL(ENABLE_CXX11_ABI, test $enable_libstdcxx_cxx11_abi = yes)
+])
+
 # Macros from the top-level gcc directory.
 m4_include([../config/gc++filt.m4])
 m4_include([../config/tls.m4])
index 9f51df10be25abcc34d463cd3aae54b788ba1b14..3f5fc9a24a1abcd75189c20b84967ae7b4cbc6dc 100755 (executable)
@@ -643,6 +643,8 @@ baseline_dir
 HWCAP_FLAGS
 GLIBCXX_LDBL_COMPAT_FALSE
 GLIBCXX_LDBL_COMPAT_TRUE
+ENABLE_CXX11_ABI_FALSE
+ENABLE_CXX11_ABI_TRUE
 ENABLE_VISIBILITY_FALSE
 ENABLE_VISIBILITY_TRUE
 libtool_VERSION
@@ -880,6 +882,7 @@ with_system_libunwind
 enable_linux_futex
 enable_symvers
 enable_libstdcxx_visibility
+enable_libstdcxx_cxx11_abi
 enable_libstdcxx_threads
 with_gxx_include_dir
 enable_version_specific_runtime_libs
@@ -1575,6 +1578,8 @@ Optional Features:
                           [default=yes]
   --enable-libstdcxx-visibility
                           enables visibility safe usage [default=yes]
+  --disable-libstdcxx-cxx11-abi
+                          disable the C++11-conforming ABI
   --enable-libstdcxx-threads
                           enable C++11 threads support [default=auto]
   --enable-version-specific-runtime-libs
@@ -11526,7 +11531,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11529 "configure"
+#line 11534 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11632,7 +11637,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11635 "configure"
+#line 11640 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15052,7 +15057,7 @@ fi
     #
     # Fake what AC_TRY_COMPILE does.  XXX Look at redoing this new-style.
     cat > conftest.$ac_ext << EOF
-#line 15055 "configure"
+#line 15060 "configure"
 struct S { ~S(); };
 void bar();
 void foo()
@@ -15404,7 +15409,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
   # Fake what AC_TRY_COMPILE does.
 
     cat > conftest.$ac_ext << EOF
-#line 15407 "configure"
+#line 15412 "configure"
 int main()
 {
   typedef bool atomic_type;
@@ -15439,7 +15444,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15442 "configure"
+#line 15447 "configure"
 int main()
 {
   typedef short atomic_type;
@@ -15474,7 +15479,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15477 "configure"
+#line 15482 "configure"
 int main()
 {
   // NB: _Atomic_word not necessarily int.
@@ -15510,7 +15515,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15513 "configure"
+#line 15518 "configure"
 int main()
 {
   typedef long long atomic_type;
@@ -15589,7 +15594,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15592 "configure"
+#line 15597 "configure"
 int main()
 {
   _Decimal32 d1;
@@ -15631,7 +15636,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15634 "configure"
+#line 15639 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -15665,7 +15670,7 @@ $as_echo "$enable_int128" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15668 "configure"
+#line 15673 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
 $as_echo "$as_me: visibility supported: $enable_libstdcxx_visibility" >&6;}
 
 
+
+  # Check whether --enable-libstdcxx-cxx11-abi was given.
+if test "${enable_libstdcxx_cxx11_abi+set}" = set; then :
+  enableval=$enable_libstdcxx_cxx11_abi;
+else
+  enable_libstdcxx_cxx11_abi=yes
+fi
+
+  if test x"$enable_libstdcxx_cxx11_abi" != xyes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: C++11-conforming ABI is disabled" >&5
+$as_echo "$as_me: C++11-conforming ABI is disabled" >&6;}
+  fi
+
+
+
 ac_ldbl_compat=no
 case "$target" in
   powerpc*-*-linux* | \
@@ -79309,6 +79329,15 @@ else
 fi
 
 
+    if test $enable_libstdcxx_cxx11_abi = yes; then
+  ENABLE_CXX11_ABI_TRUE=
+  ENABLE_CXX11_ABI_FALSE='#'
+else
+  ENABLE_CXX11_ABI_TRUE='#'
+  ENABLE_CXX11_ABI_FALSE=
+fi
+
+
     if test $ac_ldbl_compat = yes; then
   GLIBCXX_LDBL_COMPAT_TRUE=
   GLIBCXX_LDBL_COMPAT_FALSE='#'
@@ -79726,6 +79755,10 @@ if test -z "${ENABLE_VISIBILITY_TRUE}" && test -z "${ENABLE_VISIBILITY_FALSE}";
   as_fn_error "conditional \"ENABLE_VISIBILITY\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${ENABLE_CXX11_ABI_TRUE}" && test -z "${ENABLE_CXX11_ABI_FALSE}"; then
+  as_fn_error "conditional \"ENABLE_CXX11_ABI\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${GLIBCXX_LDBL_COMPAT_TRUE}" && test -z "${GLIBCXX_LDBL_COMPAT_FALSE}"; then
   as_fn_error "conditional \"GLIBCXX_LDBL_COMPAT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
index 1de0f6c1cbf2e21cd64a15686d32bdb0bd602b70..eb826e4133f0609431a8ff7e45eaf37d72253e6e 100644 (file)
@@ -365,6 +365,8 @@ AC_SUBST(libtool_VERSION)
 
 GLIBCXX_ENABLE_LIBSTDCXX_VISIBILITY([yes])
 
+GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI([yes])
+
 ac_ldbl_compat=no
 case "$target" in
   powerpc*-*-linux* | \
index dee4a3fc6f8b9985f00969a4bb868c5ed8ad32a2..e3aed8486151d279e07fbe21752d41ceffda6841 100644 (file)
@@ -1122,6 +1122,14 @@ stamp-visibility:
        echo 0 > stamp-visibility
 endif
 
+if ENABLE_CXX11_ABI
+stamp-cxx11-abi:
+       echo 1 > stamp-cxx11-abi
+else
+stamp-cxx11-abi:
+       echo 0 > stamp-cxx11-abi
+endif
+
 # NB: The non-empty default ldbl_compat works around an AIX sed
 # oddity, see libstdc++/31957 for details.
 ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
@@ -1130,11 +1138,13 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
                              ${toplevel_srcdir}/gcc/DATESTAMP \
                              stamp-namespace-version \
                              stamp-visibility \
-                             stamp-extern-template
+                             stamp-extern-template \
+                             stamp-cxx11-abi
        @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\
        ns_version=`cat stamp-namespace-version` ;\
        visibility=`cat stamp-visibility` ;\
        externtemplate=`cat stamp-extern-template` ;\
+       cxx11abi=`cat stamp-cxx11-abi` ;\
        ldbl_compat='s,g,g,' ;\
        grep "^[         ]*#[    ]*define[       ][      ]*_GLIBCXX_LONG_DOUBLE_COMPAT[  ][      ]*1[    ]*$$" \
        ${CONFIG_HEADER} > /dev/null 2>&1 \
@@ -1143,6 +1153,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
        -e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \
        -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \
        -e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \
+       -e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \
        -e "$$ldbl_compat" \
            < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\
        sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \
index 83dcefbd2df5539c807b1fcd817725bdb0db4fe6..b49c501a6f3b39b8f29fc4e8263c310e7c066862 100644 (file)
@@ -1532,6 +1532,11 @@ stamp-host: ${host_headers} ${bits_host_headers} ${ext_host_headers} ${host_head
 @ENABLE_VISIBILITY_FALSE@stamp-visibility:
 @ENABLE_VISIBILITY_FALSE@      echo 0 > stamp-visibility
 
+@ENABLE_CXX11_ABI_TRUE@stamp-cxx11-abi:
+@ENABLE_CXX11_ABI_TRUE@        echo 1 > stamp-cxx11-abi
+@ENABLE_CXX11_ABI_FALSE@stamp-cxx11-abi:
+@ENABLE_CXX11_ABI_FALSE@       echo 0 > stamp-cxx11-abi
+
 # NB: The non-empty default ldbl_compat works around an AIX sed
 # oddity, see libstdc++/31957 for details.
 ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
@@ -1540,11 +1545,13 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
                              ${toplevel_srcdir}/gcc/DATESTAMP \
                              stamp-namespace-version \
                              stamp-visibility \
-                             stamp-extern-template
+                             stamp-extern-template \
+                             stamp-cxx11-abi
        @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\
        ns_version=`cat stamp-namespace-version` ;\
        visibility=`cat stamp-visibility` ;\
        externtemplate=`cat stamp-extern-template` ;\
+       cxx11abi=`cat stamp-cxx11-abi` ;\
        ldbl_compat='s,g,g,' ;\
        grep "^[         ]*#[    ]*define[       ][      ]*_GLIBCXX_LONG_DOUBLE_COMPAT[  ][      ]*1[    ]*$$" \
        ${CONFIG_HEADER} > /dev/null 2>&1 \
@@ -1553,6 +1560,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
        -e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \
        -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \
        -e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \
+       -e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \
        -e "$$ldbl_compat" \
            < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\
        sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \
index ff6afc8558baa8718f0826c0e6e9a839708c975a..bb58a9b9748a6e2b35fd5dee07e809c84d906226 100644 (file)
@@ -193,6 +193,17 @@ namespace std
 #endif
 }
 
+// Use abi_tag("cxx11")
+#ifndef _GLIBCXX_USE_CXX11_ABI
+#define _GLIBCXX_USE_CXX11_ABI
+#endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 
 // Defined if inline namespaces are used for versioning.
 #define _GLIBCXX_INLINE_VERSION 
index 42855a4e31eaa30c0b1a3596c8dd2f235eb78d55..f99ec54ca4000cec6b87226fb1f92d9dbb3c6e38 100644 (file)
@@ -89,6 +89,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       {
        _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
        __tmp->_M_hook(__position._M_const_cast()._M_node);
+       this->_M_inc_size(1);
        return iterator(__tmp);
       }
 #endif
@@ -104,6 +105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     {
       _Node* __tmp = _M_create_node(__x);
       __tmp->_M_hook(__position._M_const_cast()._M_node);
+      this->_M_inc_size(1);
       return iterator(__tmp);
     }
 
@@ -353,6 +355,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
              ++__first1;
          if (__first2 != __last2)
            _M_transfer(__last1, __first2, __last2);
+
+         this->_M_inc_size(__x._M_get_size());
+         __x._M_set_size(0);
        }
     }
 
@@ -387,6 +392,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                ++__first1;
            if (__first2 != __last2)
              _M_transfer(__last1, __first2, __last2);
+
+           this->_M_inc_size(__x._M_get_size());
+           __x._M_set_size(0);
          }
       }
 
index dd9bba73bc141a3ca4f6525ce8708355d60d0358..8e6567cfe67b9052d222b2410f02671cc57afb16 100644 (file)
@@ -295,7 +295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
   /// See bits/stl_deque.h's _Deque_base for an explanation.
   template<typename _Tp, typename _Alloc>
-    class _List_base
+    class _GLIBCXX_DEFAULT_ABI_TAG _List_base
     {
     protected:
       // NOTA BENE
@@ -316,6 +316,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
 
+      static size_t
+      _S_distance(const __detail::_List_node_base* __first,
+                 const __detail::_List_node_base* __last)
+      {
+       size_t __n = 0;
+       while (__first != __last)
+         {
+           __first = __first->_M_next;
+           ++__n;
+         }
+       return __n;
+      }
+
       struct _List_impl
       : public _Node_alloc_type
       {
@@ -338,6 +351,40 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       _List_impl _M_impl;
 
+#if _GLIBCXX_USE_CXX11_ABI
+      size_t    _M_size;
+
+      size_t _M_get_size() const { return _M_size; }
+
+      void _M_set_size(size_t __n) { _M_size = __n; }
+
+      void _M_inc_size(size_t __n) { _M_size += __n; }
+
+      void _M_dec_size(size_t __n) { _M_size -= __n; }
+
+      size_t
+      _M_distance(const __detail::_List_node_base* __first,
+                 const __detail::_List_node_base* __last) const
+      { return _S_distance(__first, __last); }
+
+      // return the stored size
+      size_t _M_node_count() const { return _M_size; }
+#else
+      // dummy implementations used when the size is not stored
+      size_t _M_get_size() const { return 0; }
+      void _M_set_size(size_t) { }
+      void _M_inc_size(size_t) { }
+      void _M_dec_size(size_t) { }
+      size_t _M_distance(const void*, const void*) const { return 0; }
+
+      // count the number of nodes
+      size_t _M_node_count() const
+      {
+       return _S_distance(_M_impl._M_node._M_next,
+                          std::__addressof(_M_impl._M_node));
+      }
+#endif
+
       _List_node<_Tp>*
       _M_get_node()
       { return _M_impl._Node_alloc_type::allocate(1); }
@@ -386,7 +433,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            __node->_M_next = __xnode->_M_next;
            __node->_M_prev = __xnode->_M_prev;
            __node->_M_next->_M_prev = __node->_M_prev->_M_next = __node;
-           __xnode->_M_next = __xnode->_M_prev = __xnode;
+           _M_set_size(__x._M_get_size());
+           __x._M_init();
          }
       }
 #endif
@@ -403,6 +451,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       {
         this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
         this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
+       _M_set_size(0);
       }
     };
 
@@ -453,7 +502,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  %empty. 
   */
   template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
-    class list : protected _List_base<_Tp, _Alloc>
+    class _GLIBCXX_DEFAULT_ABI_TAG list : protected _List_base<_Tp, _Alloc>
     {
       // concept requirements
       typedef typename _Alloc::value_type                _Alloc_value_type;
@@ -893,7 +942,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**  Returns the number of elements in the %list.  */
       size_type
       size() const _GLIBCXX_NOEXCEPT
-      { return std::distance(begin(), end()); }
+      { return this->_M_node_count(); }
 
       /**  Returns the size() of the largest possible %list.  */
       size_type
@@ -1295,6 +1344,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        __detail::_List_node_base::swap(this->_M_impl._M_node, 
                                        __x._M_impl._M_node);
 
+       size_t __xsize = __x._M_get_size();
+       __x._M_set_size(this->_M_get_size());
+       this->_M_set_size(__xsize);
+
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 431. Swapping containers with unequal allocators.
        std::__alloc_swap<typename _Base::_Node_alloc_type>::
@@ -1339,6 +1392,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
            this->_M_transfer(__position._M_const_cast(),
                              __x.begin(), __x.end());
+
+           this->_M_inc_size(__x._M_get_size());
+           __x._M_set_size(0);
          }
       }
 
@@ -1385,6 +1441,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
        this->_M_transfer(__position._M_const_cast(),
                          __i._M_const_cast(), __j);
+
+       this->_M_inc_size(1);
+       __x._M_dec_size(1);
       }
 
 #if __cplusplus >= 201103L
@@ -1443,6 +1502,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            if (this != &__x)
              _M_check_equal_allocators(__x);
 
+           size_t __n = this->_M_distance(__first._M_node, __last._M_node);
+           this->_M_inc_size(__n);
+           __x._M_dec_size(__n);
+
            this->_M_transfer(__position._M_const_cast(),
                              __first._M_const_cast(),
                              __last._M_const_cast());
@@ -1688,6 +1751,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       {
         _Node* __tmp = _M_create_node(__x);
         __tmp->_M_hook(__position._M_node);
+       this->_M_inc_size(1);
       }
 #else
      template<typename... _Args>
@@ -1696,6 +1760,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        {
         _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
         __tmp->_M_hook(__position._M_node);
+        this->_M_inc_size(1);
        }
 #endif
 
@@ -1703,6 +1768,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       _M_erase(iterator __position) _GLIBCXX_NOEXCEPT
       {
+       this->_M_dec_size(1);
         __position._M_node->_M_unhook();
         _Node* __n = static_cast<_Node*>(__position._M_node);
 #if __cplusplus >= 201103L
index 885e753454616082db222d59371ce742a7291195..183753dca5fc476717006c6637570f14247e3c2c 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1665 }
+// { dg-error "no matching" "" { target *-*-* } 1728 }
 
 #include <list>
 
index ccd9d1734bf90ff106ba2e2e8714d1c44929a501..e81ff98d43e587e001c91b52809dce6a38bf4dd1 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1617 }
+// { dg-error "no matching" "" { target *-*-* } 1680 }
 
 #include <list>
 
index 04966dc443a4f838f5954b09e16e1d646bc40270..c98aa0f476bc307dd8442348d36176f91e4cffdc 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1617 }
+// { dg-error "no matching" "" { target *-*-* } 1680 }
 
 #include <list>
 #include <utility>
index 759dad6dba7802184584ccda1977c4f0194cf78c..1397796132c033bfae5fc797ad8bddfe522a77e5 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1617 }
+// { dg-error "no matching" "" { target *-*-* } 1680 }
 
 #include <list>
 
index 17df71a3fc7233cb967e550cbd8deb2d41a14d5b..5597c57d239aab516300f83e436d761a66fb379d 100644 (file)
@@ -25,4 +25,4 @@
 
 #include <vector>
 
-// { dg-error "multiple inlined namespaces" "" { target *-*-* } 279 }
+// { dg-error "multiple inlined namespaces" "" { target *-*-* } 290 }