* 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).