Add a libstdc++-4.4 patch for C++0x to the website.

llvm-svn: 128498
This commit is contained in:
Jeffrey Yasskin 2011-03-29 22:27:50 +00:00
parent bceec7f9a8
commit cb40757195
2 changed files with 374 additions and 0 deletions

View File

@ -85,6 +85,11 @@
ISO C++ standard (1998/2003). This section tracks the status of various C++0x
features.</p>
<p>You can use clang in C++0x mode either
with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++.
libstdc++-4.4 requires <a href="libstdc++4.4-clang0x.patch">a patch</a> to work
with clang; other versions have not been tested.</p>
<h2 id="specification">Implementation Status by Feature</h2>

View File

@ -0,0 +1,369 @@
This patch was generated from the headers installed by MacPorts
gcc-4.4 on OS X 10.6. You can apply it there with
`cd /opt/local/include/gcc44/c++ ; sudo patch -p1 <this_patch`, or similar
on other operating systems. Mail cfe-dev if you find other problems in the
standard headers.
This patch is offered under the same modified GPLv3 as libstdc++-4.4.
diff -ur a/bits/move.h b/bits/move.h
--- a/bits/move.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/move.h 2011-03-29 10:33:39.000000000 -0700
@@ -48,13 +48,35 @@
template<typename _Tp>
inline _Tp&&
- forward(typename std::identity<_Tp>::type&& __t)
+ forward(typename std::remove_reference<_Tp>::type& __t)
+#ifdef __clang__
+ { return static_cast<_Tp&&>(__t); }
+#else
{ return __t; }
+#endif
+
+ template<typename _Tp>
+ inline _Tp&&
+ forward(typename std::remove_reference<_Tp>::type&& __t)
+ {
+#ifdef __clang__
+ static_assert(!std::is_lvalue_reference<_Tp>::value,
+ "Can't instantiate this forward() with an"
+ " lvalue reference type.");
+ return static_cast<_Tp&&>(__t);
+#else
+ return __t;
+#endif
+ }
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t)
+#ifdef __clang__
+ { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
+#else
{ return __t; }
+#endif
_GLIBCXX_END_NAMESPACE
diff -ur a/bits/stl_deque.h b/bits/stl_deque.h
--- a/bits/stl_deque.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_deque.h 2011-03-29 10:33:39.000000000 -0700
@@ -1395,11 +1395,7 @@
* std::swap(d1,d2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(deque&& __x)
-#else
swap(deque& __x)
-#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
diff -ur a/bits/stl_iterator.h b/bits/stl_iterator.h
--- a/bits/stl_iterator.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_iterator.h 2011-03-29 10:33:39.000000000 -0700
@@ -913,7 +913,7 @@
reference
operator*() const
- { return *_M_current; }
+ { return std::move(*_M_current); }
pointer
operator->() const
diff -ur a/bits/stl_list.h b/bits/stl_list.h
--- a/bits/stl_list.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_list.h 2011-03-29 10:33:39.000000000 -0700
@@ -1106,11 +1106,7 @@
* function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(list&& __x)
-#else
swap(list& __x)
-#endif
{
_List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node);
@@ -1160,6 +1156,12 @@
}
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ splice(iterator __position, list& __x)
+ { splice(__position, std::move(__x)); }
+#endif
+
/**
* @brief Insert element from another %list.
* @param position Iterator referencing the element to insert before.
@@ -1187,6 +1189,12 @@
this->_M_transfer(__position, __i, __j);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ splice(iterator __position, list& __x, iterator __i)
+ { splice(__position, std::move(__x), __i); }
+#endif
+
/**
* @brief Insert range from another %list.
* @param position Iterator referencing the element to insert before.
@@ -1217,6 +1225,13 @@
}
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ splice(iterator __position, list& __x, iterator __first,
+ iterator __last)
+ { splice(__position, std::move(__x), __first, __last); }
+#endif
+
/**
* @brief Remove all elements equal to value.
* @param value The value to remove.
@@ -1287,6 +1302,10 @@
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
merge(list&& __x);
+
+ void
+ merge(list& __x)
+ { merge(std::move(__x)); }
#else
merge(list& __x);
#endif
@@ -1307,6 +1326,11 @@
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
merge(list&&, _StrictWeakOrdering);
+
+ template<typename _StrictWeakOrdering>
+ void
+ merge(list& __l, _StrictWeakOrdering __comp)
+ { merge(std::move(__l), __comp); }
#else
merge(list&, _StrictWeakOrdering);
#endif
diff -ur a/bits/stl_map.h b/bits/stl_map.h
--- a/bits/stl_map.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_map.h 2011-03-29 10:33:39.000000000 -0700
@@ -608,11 +608,7 @@
* that std::swap(m1,m2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(map&& __x)
-#else
swap(map& __x)
-#endif
{ _M_t.swap(__x._M_t); }
/**
diff -ur a/bits/stl_multimap.h b/bits/stl_multimap.h
--- a/bits/stl_multimap.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_multimap.h 2011-03-29 10:33:39.000000000 -0700
@@ -544,11 +544,7 @@
* std::swap(m1,m2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(multimap&& __x)
-#else
swap(multimap& __x)
-#endif
{ _M_t.swap(__x._M_t); }
/**
diff -ur a/bits/stl_multiset.h b/bits/stl_multiset.h
--- a/bits/stl_multiset.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_multiset.h 2011-03-29 10:33:39.000000000 -0700
@@ -376,11 +376,7 @@
* std::swap(s1,s2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(multiset&& __x)
-#else
swap(multiset& __x)
-#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
diff -ur a/bits/stl_pair.h b/bits/stl_pair.h
--- a/bits/stl_pair.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_pair.h 2011-03-29 10:33:39.000000000 -0700
@@ -84,10 +84,21 @@
: first(__a), second(__b) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<class _U1, class _U2>
+ template<class _U1, class = typename
+ std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
+ pair(_U1&& __x, const _T2& __y)
+ : first(std::forward<_U1>(__x)), second(__y) { }
+
+ template<class _U2, class = typename
+ std::enable_if<std::is_convertible<_U2, _T2>::value>::type>
+ pair(const _T1& __x, _U2&& __y)
+ : first(__x), second(std::forward<_U2>(__y)) { }
+
+ template<class _U1, class _U2, class = typename
+ std::enable_if<std::is_convertible<_U1, _T1>::value
+ && std::is_convertible<_U2, _T2>::value>::type>
pair(_U1&& __x, _U2&& __y)
- : first(std::forward<_U1>(__x)),
- second(std::forward<_U2>(__y)) { }
+ : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
pair(pair&& __p)
: first(std::move(__p.first)),
@@ -107,11 +118,19 @@
second(std::move(__p.second)) { }
// http://gcc.gnu.org/ml/libstdc++/2007-08/msg00052.html
+
+#if 0
+ // This constructor is incompatible with libstdc++-4.6, and it
+ // interferes with passing NULL pointers to the 2-argument
+ // constructors, so we disable it. map::emplace isn't
+ // implemented in libstdc++-4.4 anyway, and that's what this
+ // constructor was here for.
template<class _U1, class _Arg0, class... _Args>
pair(_U1&& __x, _Arg0&& __arg0, _Args&&... __args)
: first(std::forward<_U1>(__x)),
second(std::forward<_Arg0>(__arg0),
std::forward<_Args>(__args)...) { }
+#endif
pair&
operator=(pair&& __p)
@@ -131,7 +150,7 @@
}
void
- swap(pair&& __p)
+ swap(pair& __p)
{
using std::swap;
swap(first, __p.first);
diff -ur a/bits/stl_set.h b/bits/stl_set.h
--- a/bits/stl_set.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_set.h 2011-03-29 10:33:39.000000000 -0700
@@ -383,11 +383,7 @@
* std::swap(s1,s2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(set&& __x)
-#else
swap(set& __x)
-#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
diff -ur a/bits/stl_tree.h b/bits/stl_tree.h
--- a/bits/stl_tree.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_tree.h 2011-03-29 10:33:39.000000000 -0700
@@ -675,11 +675,7 @@
{ return _M_get_Node_allocator().max_size(); }
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(_Rb_tree&& __t);
-#else
swap(_Rb_tree& __t);
-#endif
// Insert/erase.
pair<iterator, bool>
@@ -1104,11 +1100,7 @@
typename _Compare, typename _Alloc>
void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __t)
-#else
swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
-#endif
{
if (_M_root() == 0)
{
diff -ur a/bits/stl_vector.h b/bits/stl_vector.h
--- a/bits/stl_vector.h 2011-03-15 14:49:05.000000000 -0700
+++ b/bits/stl_vector.h 2011-03-29 10:33:39.000000000 -0700
@@ -923,11 +923,7 @@
* std::swap(v1,v2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(vector&& __x)
-#else
swap(vector& __x)
-#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
diff -ur a/exception_ptr.h b/exception_ptr.h
--- a/exception_ptr.h 2011-03-15 14:49:08.000000000 -0700
+++ b/exception_ptr.h 2011-03-29 10:33:39.000000000 -0700
@@ -140,7 +140,7 @@
friend bool
operator==(const exception_ptr&, const exception_ptr&) throw();
- const type_info*
+ const class type_info*
__cxa_exception_type() const throw();
};
diff -ur a/ext/algorithm b/ext/algorithm
--- a/ext/algorithm 2011-03-15 14:49:05.000000000 -0700
+++ b/ext/algorithm 2011-03-29 10:33:39.000000000 -0700
@@ -423,6 +423,9 @@
__out_last - __out_first);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ using std::is_heap;
+#else
/**
* This is an SGI extension.
* @ingroup SGIextensions
@@ -462,6 +465,7 @@
return std::__is_heap(__first, __comp, __last - __first);
}
+#endif
// is_sorted, a predicated testing whether a range is sorted in
// nondescending order. This is an extension, not part of the C++
diff -ur a/ext/vstring.h b/ext/vstring.h
--- a/ext/vstring.h 2011-03-15 14:49:05.000000000 -0700
+++ b/ext/vstring.h 2011-03-29 10:33:39.000000000 -0700
@@ -152,7 +152,7 @@
* string.
*/
__versa_string(__versa_string&& __str)
- : __vstring_base(std::forward<__vstring_base>(__str)) { }
+ : __vstring_base(std::move(__str)) { }
/**
* @brief Construct string from an initializer list.
@@ -1439,11 +1439,7 @@
* constant time.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(__versa_string&& __s)
-#else
swap(__versa_string& __s)
-#endif
{ this->_M_swap(__s); }
// String operations: