Commit c6195f58 by François Dumont

re PR libstdc++/29988 (More stl_tree.h enhancements: improving operator=)

2014-09-24  François Dumont  <fdumont@gcc.gnu.org>

	PR libstdc++/29988
	* include/bits/stl_tree.h (_Rb_tree_reuse_or_alloc_node<>): New.
	(_Rb_tree_alloc_node<>): New.
	(_Rb_tree<>::operator=(_Rb_tree<>&&)): New.
	(_Rb_tree<>::_M_assign_unique): New.
	(_Rb_tree<>::_M_assign_equal): New.
	(_Rb_tree<>): Adapt to reuse allocated nodes as much as possible.
	* include/bits/stl_map.h
	(std::map<>::operator=(std::map<>&&)): Default implementation.
	(std::map<>::operator=(initializer_list<>)): Adapt to use
	_Rb_tree::_M_assign_unique.
	* include/bits/stl_multimap.h
	(std::multimap<>::operator=(std::multimap<>&&)): Default implementation.
	(std::multimap<>::operator=(initializer_list<>)): Adapt to use
	_Rb_tree::_M_assign_equal.
	* include/bits/stl_set.h
	(std::set<>::operator=(std::set<>&&)): Default implementation.
	(std::set<>::operator=(initializer_list<>)): Adapt to use
	_Rb_tree::_M_assign_unique.
	* include/bits/stl_multiset.h
	(std::multiset<>::operator=(std::multiset<>&&)): Default implementation.
	(std::multiset<>::operator=(initializer_list<>)): Adapt to use
	_Rb_tree::_M_assign_equal.
	* testsuite/23_containers/map/allocator/copy_assign.cc (test03): New.
	* testsuite/23_containers/map/allocator/init-list.cc: New.
	* testsuite/23_containers/map/allocator/move_assign.cc (test03): New.
	* testsuite/23_containers/multimap/allocator/copy_assign.cc
	(test03): New.
	* testsuite/23_containers/multimap/allocator/init-list.cc: New.
	* testsuite/23_containers/multimap/allocator/move_assign.cc
	(test03): New.
	* testsuite/23_containers/multiset/allocator/copy_assign.cc
	(test03): New.
	* testsuite/23_containers/multiset/allocator/init-list.cc: New.
	* testsuite/23_containers/multiset/allocator/move_assign.cc
	(test03): New.
	* testsuite/23_containers/set/allocator/copy_assign.cc (test03): New.
	* testsuite/23_containers/set/allocator/init-list.cc: New.
	* testsuite/23_containers/set/allocator/move_assign.cc (test03): New.

From-SVN: r215568
parent 00de328a
2014-09-24 François Dumont <fdumont@gcc.gnu.org>
PR libstdc++/29988
* include/bits/stl_tree.h (_Rb_tree_reuse_or_alloc_node<>): New.
(_Rb_tree_alloc_node<>): New.
(_Rb_tree<>::operator=(_Rb_tree<>&&)): New.
(_Rb_tree<>::_M_assign_unique): New.
(_Rb_tree<>::_M_assign_equal): New.
(_Rb_tree<>): Adapt to reuse allocated nodes as much as possible.
* include/bits/stl_map.h
(std::map<>::operator=(std::map<>&&)): Default implementation.
(std::map<>::operator=(initializer_list<>)): Adapt to use
_Rb_tree::_M_assign_unique.
* include/bits/stl_multimap.h
(std::multimap<>::operator=(std::multimap<>&&)): Default implementation.
(std::multimap<>::operator=(initializer_list<>)): Adapt to use
_Rb_tree::_M_assign_equal.
* include/bits/stl_set.h
(std::set<>::operator=(std::set<>&&)): Default implementation.
(std::set<>::operator=(initializer_list<>)): Adapt to use
_Rb_tree::_M_assign_unique.
* include/bits/stl_multiset.h
(std::multiset<>::operator=(std::multiset<>&&)): Default implementation.
(std::multiset<>::operator=(initializer_list<>)): Adapt to use
_Rb_tree::_M_assign_equal.
* testsuite/23_containers/map/allocator/copy_assign.cc (test03): New.
* testsuite/23_containers/map/allocator/init-list.cc: New.
* testsuite/23_containers/map/allocator/move_assign.cc (test03): New.
* testsuite/23_containers/multimap/allocator/copy_assign.cc
(test03): New.
* testsuite/23_containers/multimap/allocator/init-list.cc: New.
* testsuite/23_containers/multimap/allocator/move_assign.cc
(test03): New.
* testsuite/23_containers/multiset/allocator/copy_assign.cc
(test03): New.
* testsuite/23_containers/multiset/allocator/init-list.cc: New.
* testsuite/23_containers/multiset/allocator/move_assign.cc
(test03): New.
* testsuite/23_containers/set/allocator/copy_assign.cc (test03): New.
* testsuite/23_containers/set/allocator/init-list.cc: New.
* testsuite/23_containers/set/allocator/move_assign.cc (test03): New.
2014-09-24 Jonathan Wakely <jwakely@redhat.com> 2014-09-24 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/63353 PR libstdc++/63353
......
...@@ -297,28 +297,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -297,28 +297,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
/** /// Move assignment operator.
* @brief %Map move assignment operator.
* @param __x A %map of identical element and allocator types.
*
* The contents of @a __x are moved into this map (without copying
* if the allocators compare equal or get moved on assignment).
* Afterwards @a __x is in a valid, but unspecified state.
*/
map& map&
operator=(map&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) operator=(map&&) = default;
{
if (!_M_t._M_move_assign(__x._M_t))
{
// The rvalue's allocator cannot be moved and is not equal,
// so we need to individually move each element.
clear();
insert(std::__make_move_if_noexcept_iterator(__x.begin()),
std::__make_move_if_noexcept_iterator(__x.end()));
__x.clear();
}
return *this;
}
/** /**
* @brief %Map list assignment operator. * @brief %Map list assignment operator.
...@@ -334,8 +315,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -334,8 +315,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
map& map&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
this->clear(); _M_t._M_assign_unique(__l.begin(), __l.end());
this->insert(__l.begin(), __l.end());
return *this; return *this;
} }
#endif #endif
......
...@@ -292,28 +292,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -292,28 +292,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
/** /// Move assignment operator.
* @brief %Multimap move assignment operator.
* @param __x A %multimap of identical element and allocator types.
*
* The contents of @a __x are moved into this multimap (without copying
* if the allocators compare equal or get moved on assignment).
* Afterwards @a __x is in a valid, but unspecified state.
*/
multimap& multimap&
operator=(multimap&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) operator=(multimap&&) = default;
{
if (!_M_t._M_move_assign(__x._M_t))
{
// The rvalue's allocator cannot be moved and is not equal,
// so we need to individually move each element.
clear();
insert(std::__make_move_if_noexcept_iterator(__x.begin()),
std::__make_move_if_noexcept_iterator(__x.end()));
__x.clear();
}
return *this;
}
/** /**
* @brief %Multimap list assignment operator. * @brief %Multimap list assignment operator.
...@@ -329,8 +310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -329,8 +310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
multimap& multimap&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
this->clear(); _M_t._M_assign_equal(__l.begin(), __l.end());
this->insert(__l.begin(), __l.end());
return *this; return *this;
} }
#endif #endif
......
...@@ -263,28 +263,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -263,28 +263,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
/** /// Move assignment operator.
* @brief %Multiset move assignment operator.
* @param __x A %multiset of identical element and allocator types.
*
* The contents of @a __x are moved into this %multiset (without
* copying if the allocators compare equal or get moved on assignment).
* Afterwards @a __x is in a valid, but unspecified state.
*/
multiset& multiset&
operator=(multiset&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) operator=(multiset&&) = default;
{
if (!_M_t._M_move_assign(__x._M_t))
{
// The rvalue's allocator cannot be moved and is not equal,
// so we need to individually move each element.
clear();
insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
std::__make_move_if_noexcept_iterator(__x._M_t.end()));
__x.clear();
}
return *this;
}
/** /**
* @brief %Multiset list assignment operator. * @brief %Multiset list assignment operator.
...@@ -300,8 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -300,8 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
multiset& multiset&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
this->clear(); _M_t._M_assign_equal(__l.begin(), __l.end());
this->insert(__l.begin(), __l.end());
return *this; return *this;
} }
#endif #endif
......
...@@ -267,28 +267,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -267,28 +267,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
/** /// Move assignment operator.
* @brief %Set move assignment operator.
* @param __x A %set of identical element and allocator types.
*
* The contents of @a __x are moved into this %set (without copying
* if the allocators compare equal or get moved on assignment).
* Afterwards @a __x is in a valid, but unspecified state.
*/
set& set&
operator=(set&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) operator=(set&&) = default;
{
if (!_M_t._M_move_assign(__x._M_t))
{
// The rvalue's allocator cannot be moved and is not equal,
// so we need to individually move each element.
clear();
insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
std::__make_move_if_noexcept_iterator(__x._M_t.end()));
__x.clear();
}
return *this;
}
/** /**
* @brief %Set list assignment operator. * @brief %Set list assignment operator.
...@@ -304,8 +285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -304,8 +285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
set& set&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
this->clear(); _M_t._M_assign_unique(__l.begin(), __l.end());
this->insert(__l.begin(), __l.end());
return *this; return *this;
} }
#endif #endif
......
...@@ -59,9 +59,33 @@ void test02() ...@@ -59,9 +59,33 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<std::pair<const int, int>> alloc_type;
typedef std::map<int, int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1 = { { 0, 0 }, { 1, 1 } };
test_type v2 = { { 2, 2 }, { 3, 3 } };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
v1 = v2;
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
// Copyright (C) 2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-options "-std=gnu++11" }
#include <map>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<std::pair<const int, int>> alloc_type;
typedef std::map<int, int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1;
v1 = { { 0, 0 }, { 1, 1 } };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
VERIFY( allocs != 0 );
VERIFY( constructs != 0 );
// Check no allocation on list initialization.
v1 = { { 4, 4 }, { 5, 5 } };
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main()
{
test01();
}
...@@ -43,8 +43,8 @@ void test01() ...@@ -43,8 +43,8 @@ void test01()
v2 = { test_type::value_type{} }; v2 = { test_type::value_type{} };
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY( 1 == v1.get_allocator().get_personality() );
VERIFY(2 == v2.get_allocator().get_personality()); VERIFY( 2 == v2.get_allocator().get_personality() );
} }
void test02() void test02()
...@@ -60,14 +60,47 @@ void test02() ...@@ -60,14 +60,47 @@ void test02()
v2 = { test_type::value_type{} }; v2 = { test_type::value_type{} };
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality()); VERIFY( 0 == v1.get_allocator().get_personality() );
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY( 1 == v2.get_allocator().get_personality() );
VERIFY( it == v2.begin() ); VERIFY( it == v2.begin() );
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef propagating_allocator<std::pair<const int, int>, false,
tracker_allocator<std::pair<const int, int>>>
alloc_type;
typedef std::map<int, int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1(alloc_type(1));
v1 = { { 0, 0 }, { 1, 1 } };
test_type v2(alloc_type(2));
v2 = { { 2, 2 }, { 3, 3 } };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
// Check no allocation on move assignment with non propagating allocators.
v1 = std::move(v2);
VERIFY( 1 == v1.get_allocator().get_personality() );
VERIFY( 2 == v2.get_allocator().get_personality() );
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
...@@ -59,9 +59,33 @@ void test02() ...@@ -59,9 +59,33 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<std::pair<const int, int>> alloc_type;
typedef std::multimap<int, int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1 = { { 1, 1 }, { 1, 1 } };
test_type v2 = { { 2, 2 }, { 2, 2 } };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
v1 = v2;
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
// Copyright (C) 2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-options "-std=gnu++11" }
#include <map>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<std::pair<const int, int>> alloc_type;
typedef std::multimap<int, int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1;
v1 = { { 0, 0 }, { 0, 0 } };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
VERIFY( allocs != 0 );
VERIFY( constructs != 0 );
// Check no allocation on list initialization.
v1 = { { 1, 1 }, { 1, 1 } };
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main()
{
test01();
}
...@@ -61,9 +61,42 @@ void test02() ...@@ -61,9 +61,42 @@ void test02()
VERIFY( it == v2.begin() ); VERIFY( it == v2.begin() );
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef propagating_allocator<std::pair<const int, int>, false,
tracker_allocator<std::pair<const int, int>>>
alloc_type;
typedef std::multimap<int, int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1(alloc_type(1));
v1 = { { 1, 1 }, { 1, 1 } };
test_type v2(alloc_type(2));
v2 = { { 2, 2 }, { 2, 2 } };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
// Check no allocation on move assignment with non propagating allocators.
v1 = std::move(v2);
VERIFY( 1 == v1.get_allocator().get_personality() );
VERIFY( 2 == v2.get_allocator().get_personality() );
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
...@@ -57,9 +57,33 @@ void test02() ...@@ -57,9 +57,33 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<int> alloc_type;
typedef std::multiset<int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1 = { 0, 0 };
test_type v2 = { 1, 1 };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
v1 = v2;
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
// Copyright (C) 2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-options "-std=gnu++11" }
#include <set>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<int> alloc_type;
typedef std::multiset<int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1;
v1 = { 0, 0 };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
VERIFY( allocs != 0 );
VERIFY( constructs != 0 );
// Check no allocation on list initialization.
v1 = { 1, 1 };
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main()
{
test01();
}
...@@ -59,9 +59,40 @@ void test02() ...@@ -59,9 +59,40 @@ void test02()
VERIFY( it == v2.begin() ); VERIFY( it == v2.begin() );
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef propagating_allocator<int, false, tracker_allocator<int>> alloc_type;
typedef std::multiset<int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1(alloc_type(1));
v1 = { 0, 0 };
test_type v2(alloc_type(2));
v2 = { 2, 2 };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
// Check no allocation on move assignment with non propagating allocators.
v1 = std::move(v2);
VERIFY( 1 == v1.get_allocator().get_personality() );
VERIFY( 2 == v2.get_allocator().get_personality() );
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
...@@ -57,9 +57,33 @@ void test02() ...@@ -57,9 +57,33 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<int> alloc_type;
typedef std::set<int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1 = { 0, 1 };
test_type v2 = { 2, 3 };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
v1 = v2;
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
// Copyright (C) 2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-options "-std=gnu++11" }
#include <set>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef tracker_allocator<int> alloc_type;
typedef std::set<int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1;
v1 = { 0, 1 };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
VERIFY( allocs != 0 );
VERIFY( constructs != 0 );
// Check no allocation on list initialization.
v1 = { 4, 5 };
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main()
{
test01();
}
...@@ -59,9 +59,40 @@ void test02() ...@@ -59,9 +59,40 @@ void test02()
VERIFY( it == v2.begin() ); VERIFY( it == v2.begin() );
} }
void test03()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_test;
typedef propagating_allocator<int, false, tracker_allocator<int>> alloc_type;
typedef std::set<int, std::less<int>, alloc_type> test_type;
tracker_allocator_counter::reset();
test_type v1(alloc_type(1));
v1 = { 0, 1 };
test_type v2(alloc_type(2));
v2 = { 2, 3 };
auto allocs = tracker_allocator_counter::get_allocation_count();
auto constructs = tracker_allocator_counter::get_construct_count();
// Check no allocation on move assignment with non propagating allocators.
v1 = std::move(v2);
VERIFY( 1 == v1.get_allocator().get_personality() );
VERIFY( 2 == v2.get_allocator().get_personality() );
VERIFY( tracker_allocator_counter::get_allocation_count() == allocs );
VERIFY( tracker_allocator_counter::get_construct_count() == constructs + 2 );
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03();
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment