This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Add move symantics to other containers
- From: Christopher Jefferson <caj at cs dot york dot ac dot uk>
- To: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Sat, 09 Apr 2005 23:04:33 +0100
- Subject: [patch] Add move symantics to other containers
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This patch adds move symantics to all the other standard containers
(the previous one just added it to vector), adds a bunch of testcases,
a performance check, and also simplifies a previous testcase and
header. Hopefully an entirely non-contraversal patch.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFCWFFw3FpDzErifpIRAoYqAJ9AQ3fmxSxKjc/ne6Jo89YZMKyG3QCgnMDl
O+HaBtz0YiVN0wY7xse8svY=
=Gsty
-----END PGP SIGNATURE-----
2005-04-09 Christopher Jefferson <chris@bubblescope.net>
* include/bits/stl_vector.h (vector::operator==) : Add missing
return value.
* include/bits/stl_bvector.h (vector<bool>) : Add rvalue ref
constructor and operator=.
* include/bits/stl_deque.h (deque) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark deque as
rvalue ref aware.
* include/bits/stl_list.h (list) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark list as
rvalue ref aware.
* include/bits/stl_map.h (map) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark map as
rvalue ref aware.
* include/bits/stl_multimap.h (multimap) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark multimap as
rvalue ref aware.
* include/bits/stl_multiset.h (multiset) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark multiset as
rvalue ref aware.
* include/bits/stl_pair.h (pair) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark pair as
rvalue ref aware.
* include/bits/stl_set.h (set) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark set as
rvalue ref aware.
* include/bits/stl_set.h (set) : Add rvalue ref constructor
and operator=.
(__gnu_cxx::__is_moveable) : Add overload to mark set as
rvalue ref aware.
* testsuite/20_util/utility/pair/moveable.cc : New.
* testsuite/23_containers/deque/moveable.cc : New.
* testsuite/23_containers/list/moveable.cc : New.
* testsuite/23_containers/map/moveable.cc : New.
* testsuite/23_containers/multimap/moveable.cc : New.
* testsuite/23_containers/multiset/moveable.cc : New.
* testsuite/23_containers/set/moveable.cc : New.
* testsuite/performance/25_algorithms/unique.cc : New.
* testsuite/testsuite_rvalref.h (rvalstruct) : Simplify.
* testsuite/25_algorithms/unique/moveable.cc : Modify to use new
rvalstruct.
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_bvector.h libstdc++-v3/include/bits/stl_bvector.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_bvector.h Tue Feb 1 16:07:01 2005
+++ libstdc++-v3/include/bits/stl_bvector.h Fri Mar 25 23:18:41 2005
@@ -643,6 +643,10 @@
std::copy(__x.begin(), __x.end(), this->_M_impl._M_start);
}
+ vector(__gnu_cxx::__rvalref<vector> __x)
+ : _Bvector_base<_Alloc>(__x.get_allocator())
+ { this->swap(__x.__ref); }
+
// Check whether it's an integral type. If so, it's not an iterator.
template<class _Integer>
void
@@ -683,6 +687,13 @@
}
std::copy(__x.begin(), __x.end(), begin());
this->_M_impl._M_finish = begin() + difference_type(__x.size());
+ return *this;
+ }
+
+ vector&
+ operator=(__gnu_cxx::__rvalref<vector> __x)
+ {
+ this->swap(__x.__ref);
return *this;
}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_deque.h libstdc++-v3/include/bits/stl_deque.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_deque.h Tue Feb 1 16:07:03 2005
+++ libstdc++-v3/include/bits/stl_deque.h Fri Mar 25 23:34:16 2005
@@ -64,6 +64,7 @@
#include <bits/concept_check.h>
#include <bits/stl_iterator_base_types.h>
#include <bits/stl_iterator_base_funcs.h>
+#include <bits/moveable.h>
namespace _GLIBCXX_STD
{
@@ -672,6 +673,18 @@
this->get_allocator()); }
/**
+ * @brief %Deque move constructor
+ * @param x A %deque of identical element and allocator types
+ *
+ * The newly-constructed %deque contains the exact contents of @a x.
+ * The contents of x are a valid, but unspecified deque.
+ */
+ deque(__gnu_cxx::__rvalref<deque> __x)
+ : _Base(__x.__ref.get_allocator(), 0)
+ { this->swap(__x.__ref); }
+
+
+ /**
* @brief Builds a %deque from a range.
* @param first An input iterator.
* @param last An input iterator.
@@ -715,6 +728,20 @@
operator=(const deque& __x);
/**
+ * @brief %Deque move assignment operator.
+ * @param x A %deque of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this deque (without copying).
+ * @a x is a valid, but unspecified deque.
+ */
+ deque&
+ operator=(__gnu_cxx::__rvalref<deque> __x)
+ {
+ this->swap(__x.__ref);
+ return *this;
+ }
+
+ /**
* @brief Assigns a given value to a %deque.
* @param n Number of elements to be assigned.
* @param val Value to be assigned.
@@ -1506,5 +1533,12 @@
swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
+
+namespace __gnu_cxx
+{
+ template<typename _Tp, typename _Alloc>
+ struct __is_moveable<_GLIBCXX_STD::deque<_Tp, _Alloc> >
+ { static const bool value = true; };
+}
#endif /* _DEQUE_H */
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_list.h libstdc++-v3/include/bits/stl_list.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_list.h Tue Feb 1 16:07:07 2005
+++ libstdc++-v3/include/bits/stl_list.h Thu Mar 31 20:44:47 2005
@@ -62,6 +62,7 @@
#define _LIST_H 1
#include <bits/concept_check.h>
+#include <bits/moveable.h>
namespace _GLIBCXX_STD
{
@@ -482,6 +483,17 @@
{ this->insert(begin(), __x.begin(), __x.end()); }
/**
+ * @brief %List move constructor
+ * @param x A %list of identical element and allocator types
+ *
+ * The newly-constructed %list contains the exact contents of @a x.
+ * The contents of x are a valid, but unspecified list.
+ */
+ list(__gnu_cxx::__rvalref<list> __x)
+ : _Base(__x.__ref.get_allocator())
+ { this->swap(__x.__ref); }
+
+ /**
* @brief Builds a %list from a range.
* @param first An input iterator.
* @param last An input iterator.
@@ -520,6 +532,20 @@
operator=(const list& __x);
/**
+ * @brief %List move assignment operator.
+ * @param x A %list of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this list (without copying).
+ * @a x is a valid, but unspecified list.
+ */
+ list&
+ operator=(__gnu_cxx::__rvalref<list> __x)
+ {
+ this->swap(__x.__ref);
+ return *this;
+ }
+
+ /**
* @brief Assigns a given value to a %list.
* @param n Number of elements to be assigned.
* @param val Value to be assigned.
@@ -1214,6 +1240,13 @@
swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
+
+namespace __gnu_cxx
+{
+ template<typename _Tp, typename _Alloc>
+ struct __is_moveable<_GLIBCXX_STD::list<_Tp, _Alloc> >
+ { static const bool value = true; };
+}
#endif /* _LIST_H */
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_map.h libstdc++-v3/include/bits/stl_map.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_map.h Fri Oct 8 18:01:11 2004
+++ libstdc++-v3/include/bits/stl_map.h Thu Mar 31 20:49:21 2005
@@ -62,6 +62,7 @@
#define _MAP_H 1
#include <bits/concept_check.h>
+#include <bits/moveable.h>
namespace _GLIBCXX_STD
{
@@ -160,6 +161,17 @@
: _M_t(__x._M_t) { }
/**
+ * @brief %Map move constructor
+ * @param x A %map of identical element and allocator types
+ *
+ * The newly-constructed %map contains the exact contents of @a x.
+ * The contents of x are a valid, but unspecified map.
+ */
+ map(__gnu_cxx::__rvalref<map> __x)
+ : _M_t(__x.__ref._M_t.key_comp() , __x.__ref.get_allocator())
+ { this->swap(__x.__ref); }
+
+ /**
* @brief Builds a %map from a range.
* @param first An input iterator.
* @param last An input iterator.
@@ -200,6 +212,20 @@
return *this;
}
+ /**
+ * @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).
+ * @a x is a valid, but unspecified map.
+ */
+ map&
+ operator=(__gnu_cxx::__rvalref<map> __x)
+ {
+ this->swap(__x.__ref);
+ return *this;
+ }
+
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
@@ -671,5 +697,12 @@
swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
+
+namespace __gnu_cxx
+{
+ template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ struct __is_moveable<_GLIBCXX_STD::map<_Key, _Tp, _Compare,_Alloc> >
+ { static const bool value = true; };
+}
#endif /* _MAP_H */
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_multimap.h libstdc++-v3/include/bits/stl_multimap.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_multimap.h Fri Oct 8 18:01:11 2004
+++ libstdc++-v3/include/bits/stl_multimap.h Thu Mar 31 22:28:46 2005
@@ -62,6 +62,7 @@
#define _MULTIMAP_H 1
#include <bits/concept_check.h>
+#include <bits/moveable.h>
namespace _GLIBCXX_STD
{
@@ -175,6 +176,17 @@
: _M_t(__x._M_t) { }
/**
+ * @brief %Multimap move constructor
+ * @param x A %Multimap of identical element and allocator types
+ *
+ * The newly-constructed %multimap contains the exact contents of @a x.
+ * The contents of x are a valid, but unspecified multimap.
+ */
+ multimap(__gnu_cxx::__rvalref<multimap> __x)
+ : _M_t(__x.__ref._M_t.key_comp() , __x.__ref.get_allocator())
+ { this->swap(__x.__ref); }
+
+ /**
* @brief Builds a %multimap from a range.
* @param first An input iterator.
* @param last An input iterator.
@@ -215,6 +227,20 @@
return *this;
}
+ /**
+ * @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).
+ * @a x is a valid, but unspecified multimap.
+ */
+ multimap&
+ operator=(__gnu_cxx::__rvalref<multimap> __x)
+ {
+ this->swap(__x.__ref);
+ return *this;
+ }
+
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
@@ -652,5 +678,12 @@
multimap<_Key,_Tp,_Compare,_Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
+
+namespace __gnu_cxx
+{
+ template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ struct __is_moveable<_GLIBCXX_STD::multimap<_Key, _Tp, _Compare,_Alloc> >
+ { static const bool value = true; };
+}
#endif /* _MULTIMAP_H */
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_multiset.h libstdc++-v3/include/bits/stl_multiset.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_multiset.h Fri Oct 8 18:01:12 2004
+++ libstdc++-v3/include/bits/stl_multiset.h Thu Mar 31 22:32:03 2005
@@ -62,6 +62,7 @@
#define _MULTISET_H 1
#include <bits/concept_check.h>
+#include <bits/moveable.h>
namespace _GLIBCXX_STD
{
@@ -178,6 +179,17 @@
: _M_t(__x._M_t) { }
/**
+ * @brief %Multiset move constructor
+ * @param x A %multiset of identical element and allocator types
+ *
+ * The newly-constructed %multiset contains the exact contents of @a x.
+ * The contents of x are a valid, but unspecified multiset.
+ */
+ multiset(__gnu_cxx::__rvalref<multiset> __x)
+ : _M_t(__x.__ref._M_t.key_comp() , __x.__ref.get_allocator())
+ { this->swap(__x.__ref); }
+
+ /**
* @brief %Multiset assignment operator.
* @param x A %multiset of identical element and allocator types.
*
@@ -191,6 +203,20 @@
return *this;
}
+ /**
+ * @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).
+ * @a x is a valid, but unspecified multiset.
+ */
+ multiset&
+ operator=(__gnu_cxx::__rvalref<multiset> __x)
+ {
+ this->swap(__x.__ref);
+ return *this;
+ }
+
// accessors:
/// Returns the comparison object.
@@ -564,5 +590,12 @@
{ __x.swap(__y); }
} // namespace std
+
+namespace __gnu_cxx
+{
+ template <typename _Key, typename _Compare, typename _Alloc>
+ struct __is_moveable<_GLIBCXX_STD::multiset<_Key, _Compare, _Alloc> >
+ { static const bool value = true; };
+}
#endif /* _MULTISET_H */
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_pair.h libstdc++-v3/include/bits/stl_pair.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_pair.h Tue Aug 17 15:48:48 2004
+++ libstdc++-v3/include/bits/stl_pair.h Thu Mar 31 20:53:35 2005
@@ -61,6 +61,8 @@
#ifndef _PAIR_H
#define _PAIR_H 1
+#include <bits/moveable.h>
+
namespace std
{
/// pair holds two objects of arbitrary type.
@@ -88,6 +90,24 @@
template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p)
: first(__p.first), second(__p.second) { }
+
+ /** Construct from rvalue reference. The effects to each element
+ will depend on if, and how, they implement rvalue reference
+ symantics */
+ pair(__gnu_cxx::__rvalref<pair> __x)
+ : first(__gnu_cxx::__move(__x.__ref.first)),
+ second(__gnu_cxx::__move(__x.__ref.second)) { }
+
+ /** Copy from rvalue reference. The effects to each element will
+ depend on if, and how, they implement rvalue reference
+ symantics */
+ pair&
+ operator=(__gnu_cxx::__rvalref<pair> __x)
+ {
+ first = __gnu_cxx::__move(__x.__ref.first);
+ second = __gnu_cxx::__move(__x.__ref.second);
+ return *this;
+ }
};
/// Two pairs of the same type are equal iff their members are equal.
@@ -144,5 +164,12 @@
make_pair(_T1 __x, _T2 __y)
{ return pair<_T1, _T2>(__x, __y); }
} // namespace std
+
+namespace __gnu_cxx
+{
+ template<typename _T1, typename _T2>
+ struct __is_moveable<std::pair<_T1, _T2> >
+ { static const bool value = true; };
+}
#endif /* _PAIR_H */
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_set.h libstdc++-v3/include/bits/stl_set.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_set.h Fri Oct 8 18:01:12 2004
+++ libstdc++-v3/include/bits/stl_set.h Thu Mar 31 22:30:26 2005
@@ -62,6 +62,7 @@
#define _SET_H 1
#include <bits/concept_check.h>
+#include <bits/moveable.h>
namespace _GLIBCXX_STD
{
@@ -185,6 +186,17 @@
: _M_t(__x._M_t) { }
/**
+ * @brief %Set move constructor
+ * @param x A %set of identical element and allocator types
+ *
+ * The newly-constructed %set contains the exact contents of @a x.
+ * The contents of x are a valid, but unspecified set.
+ */
+ set(__gnu_cxx::__rvalref<set> __x)
+ : _M_t(__x.__ref._M_t.key_comp() , __x.__ref.get_allocator())
+ { this->swap(__x.__ref); }
+
+ /**
* @brief Set assignment operator.
* @param x A %set of identical element and allocator types.
*
@@ -198,6 +210,20 @@
return *this;
}
+ /**
+ * @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).
+ * @a x is a valid, but unspecified set.
+ */
+ set&
+ operator=(__gnu_cxx::__rvalref<set> __x)
+ {
+ this->swap(__x.__ref);
+ return *this;
+ }
+
// accessors:
/// Returns the comparison object with which the %set was constructed.
@@ -573,4 +599,10 @@
} // namespace std
+namespace __gnu_cxx
+{
+ template <typename _Key, typename _Compare, typename _Alloc>
+ struct __is_moveable<_GLIBCXX_STD::set<_Key, _Compare, _Alloc> >
+ { static const bool value = true; };
+}
#endif /* _SET_H */
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/include/bits/stl_vector.h libstdc++-v3/include/bits/stl_vector.h
--- libstdc++-v3.so_7.movesym.clean/include/bits/stl_vector.h Thu Mar 31 21:56:19 2005
+++ libstdc++-v3/include/bits/stl_vector.h Sat Apr 9 22:22:05 2005
@@ -291,7 +291,10 @@
*/
vector&
operator=(__gnu_cxx::__rvalref<vector> __x)
- { this->swap(__x.__ref); }
+ {
+ this->swap(__x.__ref);
+ return *this;
+ }
/**
* @brief Assigns a given value to a %vector.
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/20_util/utility/pair/moveable.cc libstdc++-v3/testsuite/20_util/utility/pair/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/20_util/utility/pair/moveable.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/20_util/utility/pair/moveable.cc Thu Mar 31 21:35:08 2005
@@ -0,0 +1,73 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This test tests the internal "moveable" extension
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on pair, and also vector. If the implementation
+// changes this test may begin to fail.
+
+#include <vector>
+#include <utility>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+void
+test1()
+{
+ std::pair<int,int> a(1,1),b(2,2);
+ a=__gnu_cxx::__move(b);
+ VERIFY(a.first == 2 && a.second == 2 && b.first == 2 &&
+ b.second == 2);
+ std::pair<int,int> c(__gnu_cxx::__move(a));
+ VERIFY(c.first == 2 && c.second == 2 && a.first == 2 &&
+ a.second == 2);
+}
+
+void
+test2()
+{
+ std::vector<int> v,w;
+ v.push_back(1);
+ w.push_back(2);
+ w.push_back(2);
+ std::pair<int, std::vector<int> > p = make_pair(1,v);
+ std::pair<int, std::vector<int> > q = make_pair(2,w);
+ p = __gnu_cxx::__move(q);
+ VERIFY(p.first == 2 && q.first == 2 &&
+ p.second.size() == 2 && q.second.size() == 1);
+ std::pair<int, std::vector<int> > r(__gnu_cxx::__move(p));
+ VERIFY(r.first == 2 && p.first == 2 &&
+ r.second.size() == 2 && p.second.size() == 0);
+}
+
+int
+main()
+{
+ test1();
+ test2();
+}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/deque/moveable.cc libstdc++-v3/testsuite/23_containers/deque/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/deque/moveable.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/23_containers/deque/moveable.cc Fri Mar 25 23:01:10 2005
@@ -0,0 +1,49 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This test tests the internal "moveable" extension
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on deque (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <deque>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::deque<int> a,b;
+ a.push_back(1);
+ b = __gnu_cxx::__move(a);
+ VERIFY( b.size() == 1 && b[0] == 1 && a.size() == 0 );
+
+ std::deque<int> c(__gnu_cxx::__move(b));
+ VERIFY( c.size() == 1 && c[0] == 1 );
+ VERIFY( b.size() == 0 );
+ return 0;
+}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/list/moveable.cc libstdc++-v3/testsuite/23_containers/list/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/list/moveable.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/23_containers/list/moveable.cc Fri Mar 25 23:35:22 2005
@@ -0,0 +1,49 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This test tests the internal "moveable" extension
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on list (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <list>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::list<int> a,b;
+ a.push_back(1);
+ b = __gnu_cxx::__move(a);
+ VERIFY( b.size() == 1 && *b.begin() == 1 && a.size() == 0 );
+
+ std::list<int> c(__gnu_cxx::__move(b));
+ VERIFY( c.size() == 1 && *c.begin() == 1 );
+ VERIFY( b.size() == 0 );
+ return 0;
+}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/map/moveable.cc libstdc++-v3/testsuite/23_containers/map/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/map/moveable.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/23_containers/map/moveable.cc Fri Mar 25 23:44:51 2005
@@ -0,0 +1,50 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This test tests the internal "moveable" extension
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on map (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <map>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::map<int, int> a,b;
+ a[2]=0;
+ b[1]=0;
+ b = __gnu_cxx::__move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::map<int, int> c(__gnu_cxx::__move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/multimap/moveable.cc libstdc++-v3/testsuite/23_containers/multimap/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/multimap/moveable.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/23_containers/multimap/moveable.cc Tue Apr 5 23:08:39 2005
@@ -0,0 +1,50 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This test tests the internal "moveable" extension
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multimap (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <map>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::multimap<int, int> a,b;
+ a.insert(std::make_pair(2,0));
+ b.insert(std::make_pair(1,0));
+ b = __gnu_cxx::__move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::multimap<int, int> c(__gnu_cxx::__move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/multiset/moveable.cc libstdc++-v3/testsuite/23_containers/multiset/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/multiset/moveable.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/23_containers/multiset/moveable.cc Tue Apr 5 23:05:19 2005
@@ -0,0 +1,50 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This test tests the internal "moveable" extension
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multiset (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <set>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::multiset<int> a,b;
+ a.insert(2);
+ b.insert(1);
+ b = __gnu_cxx::__move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::multiset<int> c(__gnu_cxx::__move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/set/moveable.cc libstdc++-v3/testsuite/23_containers/set/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/23_containers/set/moveable.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/23_containers/set/moveable.cc Tue Apr 5 23:02:13 2005
@@ -0,0 +1,50 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This test tests the internal "moveable" extension
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on set (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <set>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::set<int> a,b;
+ a.insert(2);
+ b.insert(1);
+ b = __gnu_cxx::__move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::set<int> c(__gnu_cxx::__move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/25_algorithms/unique/moveable.cc libstdc++-v3/testsuite/25_algorithms/unique/moveable.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/25_algorithms/unique/moveable.cc Tue Mar 22 17:53:44 2005
+++ libstdc++-v3/testsuite/25_algorithms/unique/moveable.cc Tue Apr 5 23:00:25 2005
@@ -30,22 +30,25 @@
using __gnu_test::rvalstruct;
typedef test_container<rvalstruct, forward_iterator_wrapper> Container;
-
+#include <stdio.h>
void test01()
{
bool test __attribute__((unused)) = true;
- rvalstruct T1[] = {1, 4, 4, 6, 1, 2, 2, 3, 1, 6, 6, 6, 5, 7, 5, 4, 4};
- rvalstruct T2[] = {1, 1, 1, 2, 2, 1, 1, 7, 6, 6, 7, 8, 8, 8, 8, 9, 9};
+ int intarray1[] = {1, 4, 4, 6, 1, 2, 2, 3, 1, 6, 6, 6, 5, 7, 5, 4, 4};
+ int intarray2[] = {1, 1, 1, 2, 2, 1, 1, 7, 6, 6, 7, 8, 8, 8, 8, 9, 9};
- const int N = sizeof(T1) / sizeof(rvalstruct);
+ const int N = sizeof(intarray1) / sizeof(int);
+ rvalstruct T1[N];
+ rvalstruct T2[N];
+
+ std::copy(intarray1,intarray1 + N, T1);
+ std::copy(intarray2,intarray2 + N, T2);
+
const int A1[] = {1, 4, 6, 1, 2, 3, 1, 6, 5, 7, 5, 4};
-
const int B1[] = {1, 2, 1, 7, 6, 7, 8, 9};
- rvalstruct::zero_counters();
-
Container con(T1, T1 + N);
VERIFY(std::unique(con.begin(), con.end()).ptr - T1 == 12);
@@ -56,10 +59,6 @@
VERIFY(std::unique(con2.begin(), con2.end()).ptr - T2 == 8);
for(int i = 0; i < 8; ++i)
VERIFY(T2[i].val == B1[i]);
-
- VERIFY(rvalstruct::empty_construct == 0 &&
- rvalstruct::copy_construct == 0 &&
- rvalstruct::copy_assign == 0);
}
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/performance/25_algorithms/unique.cc libstdc++-v3/testsuite/performance/25_algorithms/unique.cc
--- libstdc++-v3.so_7.movesym.clean/testsuite/performance/25_algorithms/unique.cc Thu Jan 1 01:00:00 1970
+++ libstdc++-v3/testsuite/performance/25_algorithms/unique.cc Fri Apr 8 21:30:44 2005
@@ -0,0 +1,138 @@
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+
+#include<vector>
+#include<algorithm>
+
+#include<sstream>
+#include<testsuite_performance.h>
+#include<testsuite_iterators.h>
+
+using namespace std;
+using namespace __gnu_test;
+
+const int length = 100000;
+const int loop_count = 500;
+
+// Used to stop move symantics
+struct vec_wrap
+{
+ vector<int> v;
+
+ explicit vec_wrap(vector<int> in_vec) : v(in_vec)
+ { }
+
+ vec_wrap() { }
+};
+
+bool inline
+operator==(const vec_wrap& lhs, const vec_wrap& rhs)
+{ return lhs.v == rhs.v; }
+
+void
+test1()
+{
+ time_counter time;
+ resource_counter resource;
+ vector<vector<int> > moveable_vecs;
+ for(int i = 0; i < length; i++)
+ {
+ vector<int> vec(1, i);
+ moveable_vecs.push_back(vec);
+ }
+ moveable_vecs[0] = vector<int>();
+ start_counters(time, resource);
+ for(int loop = 0 ; loop < loop_count; loop++)
+ {
+ moveable_vecs[1]=moveable_vecs[0];
+ unique(moveable_vecs.begin(), moveable_vecs.end() - loop);
+ }
+ stop_counters(time, resource);
+ report_performance(__FILE__, "moveable vector", time, resource);
+ clear_counters(time, resource);
+}
+
+void
+test2()
+{
+ time_counter time;
+ resource_counter resource;
+ vector<vec_wrap> unmoveable_vecs;
+ for(int i = 0; i < length; i++)
+ {
+ vector<int> vec(20, i);
+ vec_wrap wrap(vec);
+ unmoveable_vecs.push_back(wrap);
+ }
+ unmoveable_vecs[0] = vec_wrap();
+ start_counters(time, resource);
+ for(int loop = 0 ; loop < loop_count; loop++)
+ {
+ unmoveable_vecs[1] = unmoveable_vecs[0];
+ unique(unmoveable_vecs.begin(), unmoveable_vecs.end());
+ }
+ stop_counters(time, resource);
+ report_performance(__FILE__, "20 element unmoveable vector", time, resource);
+ clear_counters(time, resource);
+}
+
+
+void
+test3()
+{
+ time_counter time;
+ resource_counter resource;
+ vector<vec_wrap> unmoveable_vecs;
+ for(int i = 0; i < length; i++)
+ {
+ vector<int> vec(1, i);
+ vec_wrap wrap(vec);
+ unmoveable_vecs.push_back(wrap);
+ }
+ unmoveable_vecs[0] = vec_wrap();
+ start_counters(time, resource);
+ for(int loop = 0 ; loop < loop_count; loop++)
+ {
+ unmoveable_vecs[1] = unmoveable_vecs[0];
+ unique(unmoveable_vecs.begin(), unmoveable_vecs.end());
+ }
+ stop_counters(time, resource);
+ report_performance(__FILE__, "1 element unmoveable vector", time, resource);
+ clear_counters(time, resource);
+}
+
+
+int
+main(void)
+{
+ test1();
+ test2();
+ test3();
+}
+
+
diff -urN -x *CVS* libstdc++-v3.so_7.movesym.clean/testsuite/testsuite_rvalref.h libstdc++-v3/testsuite/testsuite_rvalref.h
--- libstdc++-v3.so_7.movesym.clean/testsuite/testsuite_rvalref.h Tue Mar 22 17:53:43 2005
+++ libstdc++-v3/testsuite/testsuite_rvalref.h Sat Apr 9 22:54:15 2005
@@ -31,75 +31,54 @@
#ifndef _GLIBCXX_TESTSUITE_RVALREF_H
#define _GLIBCXX_TESTSUITE_RVALREF_H 1
+#include <testsuite_hooks.h>
+
namespace __gnu_test
{
- struct rvalstruct
+ class rvalstruct
{
- static int empty_construct;
- static int copy_construct;
- static int move_construct;
- static int copy_assign;
- static int move_assign;
-
- static void
- zero_counters()
- {
- empty_construct = copy_construct = move_construct = 0;
- copy_assign = move_assign = 0;
- }
-
+ public:
int val;
+ bool valid;
- rvalstruct() : val(0)
- { ++empty_construct;}
-
- rvalstruct(int in) : val(in)
+ rvalstruct() : valid(false)
{ }
- rvalstruct(const rvalstruct& in)
- {
- val=in.val;
- ++copy_construct;
+ rvalstruct&
+ operator=(int newval)
+ {
+ val = newval;
+ valid = true;
}
rvalstruct(__gnu_cxx::__rvalref<rvalstruct> in)
- {
- val=in.__ref.val;
- ++move_construct;
- }
-
- rvalstruct&
- operator=(const rvalstruct& in)
{
- ++copy_assign;
- val = in.val;
- return *this;
+ VERIFY(in.__ref.valid == true);
+ val = in.__ref.val;
+ in.__ref.valid = false;
}
rvalstruct&
operator=(__gnu_cxx::__rvalref<rvalstruct> in)
{
- ++move_assign;
+ VERIFY(in.__ref.valid == true);
val = in.__ref.val;
+ in.__ref.valid = false;
return *this;
}
};
-bool
-operator==(const rvalstruct& lhs, const rvalstruct& rhs)
-{ return lhs.val == rhs.val; }
-
-bool
-operator<(const rvalstruct& lhs, const rvalstruct& rhs)
-{ return lhs.val < rhs.val; }
+ bool
+ operator==(const rvalstruct& lhs,
+ const rvalstruct& rhs)
+ { return lhs.val == rhs.val; }
+
+ bool
+ operator<(const rvalstruct& lhs,
+ const rvalstruct& rhs)
+ { return lhs.val < rhs.val; }
-int rvalstruct::empty_construct = 0;
-int rvalstruct::copy_construct = 0;
-int rvalstruct::move_construct = 0;
-int rvalstruct::copy_assign = 0;
-int rvalstruct::move_assign = 0;
-
}; // namespace __gnu_test
namespace __gnu_cxx