public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Tree containers profile mode fix
@ 2014-01-15 16:59 François Dumont
  2014-01-15 17:13 ` Jonathan Wakely
  0 siblings, 1 reply; 2+ messages in thread
From: François Dumont @ 2014-01-15 16:59 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2480 bytes --]

Hi

     Here is a patch to fix profile mode compilation errors. It makes 
tree based containers C++11 allocator aware in profile mode as they are 
in normal mode. I also try to use default implementation as much as 
possible to benefit from the normal mode noexcept qualifications on the 
defaulted functions.

     Note that for some containers having no profiling instrumentation I 
try to replace the empty wrapper with template alias like:

template <typename _Key, typename _Compare = std::less<_Key>,
                  typename _Alloc = std::allocator<_Key>>
using set = _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>;

     But some explicit instantiations failed then in the tests. Is it a 
gcc limitation or a Standard requirement to refuse explicit 
instantiation of a template alias ? If It could be interpreted as an 
explicit instantiation of the underlying type it would be really useful.

2014-01-15  François Dumont <fdumont@gcc.gnu.org>

     * include/profile/set.h (set): Implement C++11 allocator-aware
     container requirements.
     * include/profile/map.h (map): Likewise.
     * include/profile/multiset.h (multiset): Likewise.
     * include/profile/multimap.h (multimap): Likewise.
     * include/profile/set.h
     (set::operator=(const set&)): Define as default in C++11 mode.
     (set::operator=(set&&)): Likewise.
     * include/profile/map.h
     (map::operator=(const map&)): Likewise.
     (map::operator=(map&&)): Likewise.
     * include/profile/multiset.h
     (multiset::operator=(const multiset&)): Likewise.
     (multiset::operator=(multiset&&)): Likewise.
     * include/profile/multimap.h
     (multimap::operator=(const multimap&)): Likewise.
     (multimap::operator=(multimap&&)): Likewise.
     * include/profile/set.h (set::operator=(std::initializer_list<>)):
     Rely on the same operator from normal mode.
     * include/profile/map.h (map::operator=(std::initializer_list<>)):
     Likewise.
     * include/profile/multiset.h
     (multiset::operator=(std::initializer_list<>)): Likewise.
     * include/debug/multimap.h
     (multimap::operator=(std::initializer_list<>)): Likewise.
     * include/debug/set.h (set::swap(set&)): Add noexcept
     specification.
     * include/debug/map.h (map::swap(map&)): Likewise.
     * include/debug/multiset.h (multiset::swap(multiset&)): Likewise.
     * include/debug/multimap.h (multimap::swap(multimap&)): Likewise.

Tested under Linux x86_64 normal and profile modes.

François


[-- Attachment #2: profile.patch --]
[-- Type: text/x-patch, Size: 10944 bytes --]

Index: include/profile/multiset.h
===================================================================
--- include/profile/multiset.h	(revision 206587)
+++ include/profile/multiset.h	(working copy)
@@ -43,6 +43,10 @@
     {
       typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base;
 
+#if __cplusplus >= 201103L
+      typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
+#endif
+
     public:
       // types:
       typedef _Key				     key_type;
@@ -79,49 +83,62 @@
 		 const _Allocator& __a = _Allocator())
 	: _Base(__first, __last, __comp, __a) { }
 
+#if __cplusplus < 201103L
       multiset(const multiset& __x)
       : _Base(__x) { }
+#else
+      multiset(const multiset&) = default;
+      multiset(multiset&&) = default;
 
-      multiset(const _Base& __x)
-      : _Base(__x) { }
-
-#if __cplusplus >= 201103L
-      multiset(multiset&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x))
-      { }
-
       multiset(initializer_list<value_type> __l,
 	       const _Compare& __comp = _Compare(),
 	       const allocator_type& __a = allocator_type())
       : _Base(__l, __comp, __a) { }
+
+      explicit
+      multiset(const allocator_type& __a)
+	: _Base(__a) { }
+
+      multiset(const multiset& __x, const allocator_type& __a)
+      : _Base(__x, __a) { }
+
+      multiset(multiset&& __x, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _Base(std::move(__x), __a) { }
+
+      multiset(initializer_list<value_type> __l, const allocator_type& __a)
+      : _Base(__l, __a) { }
+
+      template<typename _InputIterator>
+        multiset(_InputIterator __first, _InputIterator __last,
+	    const allocator_type& __a)
+	  : _Base(__first, __last, __a) { }
 #endif
 
+      multiset(const _Base& __x)
+      : _Base(__x) { }
+
       ~multiset() _GLIBCXX_NOEXCEPT { }
 
+#if __cplusplus < 201103L
       multiset&
       operator=(const multiset& __x)
       {
-	*static_cast<_Base*>(this) = __x;
+	_M_base() = __x;
 	return *this;
       }
+#else
+      multiset&
+      operator=(const multiset&) = default;
 
-#if __cplusplus >= 201103L
       multiset&
-      operator=(multiset&& __x)
-      {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
-	return *this;
-      }
+      operator=(multiset&&) = default;
 
       multiset&
       operator=(initializer_list<value_type> __l)
       {
-	this->clear();
-	this->insert(__l);
+	_M_base() = __l;
 	return *this;
       }
 #endif
@@ -272,6 +289,9 @@
 
       void
       swap(multiset& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _Base::swap(__x); }
 
       void
Index: include/profile/map.h
===================================================================
--- include/profile/map.h	(revision 206587)
+++ include/profile/map.h	(working copy)
@@ -43,6 +43,10 @@
     {
       typedef _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> _Base;
 
+#if __cplusplus >= 201103L
+      typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
+#endif
+
     public:
       // types:
       typedef _Key                                  key_type;
@@ -93,40 +97,61 @@
       map(map&& __x)
       noexcept(is_nothrow_copy_constructible<_Compare>::value)
       : _Base(std::move(__x))
-      { }
+      { __profcxx_map_to_unordered_map_construct(this); }
 
       map(initializer_list<value_type> __l,
 	  const _Compare& __c = _Compare(),
 	  const allocator_type& __a = allocator_type())
-      : _Base(__l, __c, __a) { }
+      : _Base(__l, __c, __a)
+      { __profcxx_map_to_unordered_map_construct(this); }
+
+      explicit
+      map(const allocator_type& __a)
+	: _Base(__a)
+      { __profcxx_map_to_unordered_map_construct(this); }
+
+      map(const map& __x, const allocator_type& __a)
+      : _Base(__x, __a)
+      { __profcxx_map_to_unordered_map_construct(this); }
+
+      map(map&& __x, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _Base(std::move(__x), __a)
+      { __profcxx_map_to_unordered_map_construct(this); }
+
+      map(initializer_list<value_type> __l, const allocator_type& __a)
+      : _Base(__l, __a)
+      { __profcxx_map_to_unordered_map_construct(this); }
+
+      template<typename _InputIterator>
+        map(_InputIterator __first, _InputIterator __last,
+	    const allocator_type& __a)
+	  : _Base(__first, __last, __a)
+      { __profcxx_map_to_unordered_map_construct(this); }
 #endif
 
       ~map() _GLIBCXX_NOEXCEPT
       { __profcxx_map_to_unordered_map_destruct(this); }
 
+#if __cplusplus < 201103L
       map&
       operator=(const map& __x)
       {
-	*static_cast<_Base*>(this) = __x;
+	_M_base() = __x;
 	return *this;
       }
+#else
+      map&
+      operator=(const map&) = default;
 
-#if __cplusplus >= 201103L
       map&
-      operator=(map&& __x)
-      {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
-	return *this;
-      }
+      operator=(map&&) = default;
 
       map&
       operator=(initializer_list<value_type> __l)
       {
-	this->clear();
-	this->insert(__l);
+	_M_base() = __l;
 	return *this;
       }
 #endif
@@ -393,6 +418,9 @@
 
       void
       swap(map& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _Base::swap(__x); }
 
       void
Index: include/profile/multimap.h
===================================================================
--- include/profile/multimap.h	(revision 206587)
+++ include/profile/multimap.h	(working copy)
@@ -43,6 +43,10 @@
     {
       typedef _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
 
+#if __cplusplus >= 201103L
+      typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
+#endif
+
     public:
       // types:
       typedef _Key				     key_type;
@@ -79,49 +83,62 @@
 	       const _Allocator& __a = _Allocator())
       : _Base(__first, __last, __comp, __a) { }
 
+#if __cplusplus < 201103L
       multimap(const multimap& __x)
       : _Base(__x) { }
+#else
+      multimap(const multimap&) = default;
+      multimap(multimap&&) = default;
 
-      multimap(const _Base& __x)
-      : _Base(__x) { }
-
-#if __cplusplus >= 201103L
-      multimap(multimap&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x))
-      { }
-
       multimap(initializer_list<value_type> __l,
 	       const _Compare& __c = _Compare(),
 	       const allocator_type& __a = allocator_type())
       : _Base(__l, __c, __a) { }
+
+      explicit
+      multimap(const allocator_type& __a)
+	: _Base(__a) { }
+
+      multimap(const multimap& __x, const allocator_type& __a)
+      : _Base(__x, __a) { }
+
+      multimap(multimap&& __x, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _Base(std::move(__x), __a) { }
+
+      multimap(initializer_list<value_type> __l, const allocator_type& __a)
+      : _Base(__l, __a) { }
+
+      template<typename _InputIterator>
+        multimap(_InputIterator __first, _InputIterator __last,
+	    const allocator_type& __a)
+	  : _Base(__first, __last, __a) { }
 #endif
 
+      multimap(const _Base& __x)
+      : _Base(__x) { }
+
       ~multimap() _GLIBCXX_NOEXCEPT { }
 
+#if __cplusplus < 201103L
       multimap&
       operator=(const multimap& __x)
       {
-	*static_cast<_Base*>(this) = __x;
+	_M_base() = __x;
 	return *this;
       }
+#else
+      multimap&
+      operator=(const multimap&) = default;
 
-#if __cplusplus >= 201103L
       multimap&
-      operator=(multimap&& __x)
-      {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
-	return *this;
-      }
+      operator=(multimap&&) = default;
 
       multimap&
       operator=(initializer_list<value_type> __l)
       {
-	this->clear();
-	this->insert(__l);
+	_M_base() = __l;
 	return *this;
       }
 #endif
@@ -289,6 +306,9 @@
 
       void
       swap(multimap& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _Base::swap(__x); }
 
       void
Index: include/profile/set.h
===================================================================
--- include/profile/set.h	(revision 206587)
+++ include/profile/set.h	(working copy)
@@ -43,6 +43,10 @@
     {
       typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base;
 
+#if __cplusplus >= 201103L
+      typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
+#endif
+
     public:
       // types:
       typedef _Key				    key_type;
@@ -79,49 +83,62 @@
 	    const _Allocator& __a = _Allocator())
 	: _Base(__first, __last, __comp, __a) { }
 
+#if __cplusplus < 201103L
       set(const set& __x)
       : _Base(__x) { }
+#else
+      set(const set&) = default;
+      set(set&&) = default;
 
-      set(const _Base& __x)
-      : _Base(__x) { }
-
-#if __cplusplus >= 201103L
-      set(set&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x))
-      { }
-
       set(initializer_list<value_type> __l,
 	  const _Compare& __comp = _Compare(),
 	  const allocator_type& __a = allocator_type())
       : _Base(__l, __comp, __a) { }
+
+      explicit
+      set(const allocator_type& __a)
+	: _Base(__a) { }
+
+      set(const set& __x, const allocator_type& __a)
+      : _Base(__x, __a) { }
+
+      set(set&& __x, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _Base(std::move(__x), __a) { }
+
+      set(initializer_list<value_type> __l, const allocator_type& __a)
+      : _Base(__l, __a) { }
+
+      template<typename _InputIterator>
+        set(_InputIterator __first, _InputIterator __last,
+	    const allocator_type& __a)
+	  : _Base(__first, __last, __a) { }
 #endif
 
+      set(const _Base& __x)
+      : _Base(__x) { }
+
       ~set() _GLIBCXX_NOEXCEPT { }
 
+#if __cplusplus < 201103L
       set&
       operator=(const set& __x)
       {
-	*static_cast<_Base*>(this) = __x;
+	_M_base() = __x;
 	return *this;
       }
+#else
+      set&
+      operator=(const set&) = default;
 
-#if __cplusplus >= 201103L
       set&
-      operator=(set&& __x)
-      {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
-	return *this;
-      }
+      operator=(set&&) = default;
 
       set&
       operator=(initializer_list<value_type> __l)
       {
-	this->clear();
-	this->insert(__l);
+	_M_base() = __l;
 	return *this;
       }
 #endif
@@ -286,6 +303,9 @@
 
       void
       swap(set& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _Base::swap(__x); }
 
       void


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Tree containers profile mode fix
  2014-01-15 16:59 Tree containers profile mode fix François Dumont
@ 2014-01-15 17:13 ` Jonathan Wakely
  0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2014-01-15 17:13 UTC (permalink / raw)
  To: François Dumont; +Cc: libstdc++, gcc-patches

On 15 January 2014 16:59, François Dumont wrote:
> Hi
>
>     Here is a patch to fix profile mode compilation errors. It makes tree
> based containers C++11 allocator aware in profile mode as they are in normal
> mode. I also try to use default implementation as much as possible to
> benefit from the normal mode noexcept qualifications on the defaulted
> functions.
>
>     Note that for some containers having no profiling instrumentation I try
> to replace the empty wrapper with template alias like:
>
> template <typename _Key, typename _Compare = std::less<_Key>,
>                  typename _Alloc = std::allocator<_Key>>
> using set = _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>;
>
>     But some explicit instantiations failed then in the tests. Is it a gcc
> limitation or a Standard requirement to refuse explicit instantiation of a
> template alias ? If It could be interpreted as an explicit instantiation of
> the underlying type it would be really useful.

I'm pretty sure you cannot instantiate an alias template. An alias
template's underlying type might not be a template at all.


> 2014-01-15  François Dumont <fdumont@gcc.gnu.org>
>
>     * include/profile/set.h (set): Implement C++11 allocator-aware
>     container requirements.
>     * include/profile/map.h (map): Likewise.
>     * include/profile/multiset.h (multiset): Likewise.
>     * include/profile/multimap.h (multimap): Likewise.
>     * include/profile/set.h
>     (set::operator=(const set&)): Define as default in C++11 mode.
>     (set::operator=(set&&)): Likewise.
>     * include/profile/map.h
>     (map::operator=(const map&)): Likewise.
>     (map::operator=(map&&)): Likewise.
>     * include/profile/multiset.h
>     (multiset::operator=(const multiset&)): Likewise.
>     (multiset::operator=(multiset&&)): Likewise.
>     * include/profile/multimap.h
>     (multimap::operator=(const multimap&)): Likewise.
>     (multimap::operator=(multimap&&)): Likewise.
>     * include/profile/set.h (set::operator=(std::initializer_list<>)):
>     Rely on the same operator from normal mode.
>     * include/profile/map.h (map::operator=(std::initializer_list<>)):
>     Likewise.
>     * include/profile/multiset.h
>     (multiset::operator=(std::initializer_list<>)): Likewise.
>     * include/debug/multimap.h
>     (multimap::operator=(std::initializer_list<>)): Likewise.
>     * include/debug/set.h (set::swap(set&)): Add noexcept
>     specification.
>     * include/debug/map.h (map::swap(map&)): Likewise.
>     * include/debug/multiset.h (multiset::swap(multiset&)): Likewise.
>     * include/debug/multimap.h (multimap::swap(multimap&)): Likewise.

The profile mode parts are OK, but the ChangeLog entry seems to have
extra files listed that are not in the patch. I assume the ChangeLog
is wrong?

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-01-15 17:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-15 16:59 Tree containers profile mode fix François Dumont
2014-01-15 17:13 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).