Fix LWG issue #2106: move_iterators returning prvalues

llvm-svn: 267091
This commit is contained in:
Eric Fiselier 2016-04-22 00:49:12 +00:00
parent b7f045fc7d
commit 906c50859b
3 changed files with 47 additions and 3 deletions

View File

@ -951,7 +951,12 @@ public:
typedef typename iterator_traits<iterator_type>::difference_type difference_type;
typedef iterator_type pointer;
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
typedef value_type&& reference;
typedef typename iterator_traits<iterator_type>::reference __reference;
typedef typename conditional<
is_reference<__reference>::value,
typename remove_reference<__reference>::type&&,
__reference
>::type reference;
#else
typedef typename iterator_traits<iterator_type>::reference reference;
#endif

View File

@ -26,8 +26,18 @@
#include <iterator>
#include <type_traits>
#include "test_macros.h"
#include "test_iterators.h"
template <class ValueType, class Reference>
struct DummyIt {
typedef std::forward_iterator_tag iterator_category;
typedef ValueType value_type;
typedef std::ptrdiff_t difference_type;
typedef ValueType* pointer;
typedef Reference reference;
};
template <class It>
void
test()
@ -38,7 +48,7 @@ test()
static_assert((std::is_same<typename R::difference_type, typename T::difference_type>::value), "");
static_assert((std::is_same<typename R::pointer, It>::value), "");
static_assert((std::is_same<typename R::value_type, typename T::value_type>::value), "");
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#if TEST_STD_VER >= 11
static_assert((std::is_same<typename R::reference, typename R::value_type&&>::value), "");
#else
static_assert((std::is_same<typename R::reference, typename T::reference>::value), "");
@ -53,4 +63,33 @@ int main()
test<bidirectional_iterator<char*> >();
test<random_access_iterator<char*> >();
test<char*>();
#if TEST_STD_VER >= 11
{
typedef DummyIt<int, int> T;
typedef std::move_iterator<T> It;
static_assert(std::is_same<It::reference, int>::value, "");
}
{
typedef DummyIt<int, std::reference_wrapper<int> > T;
typedef std::move_iterator<T> It;
static_assert(std::is_same<It::reference, std::reference_wrapper<int> >::value, "");
}
{
// Check that move_iterator uses whatever reference type it's given
// when it's not a reference.
typedef DummyIt<int, long > T;
typedef std::move_iterator<T> It;
static_assert(std::is_same<It::reference, long>::value, "");
}
{
typedef DummyIt<int, int&> T;
typedef std::move_iterator<T> It;
static_assert(std::is_same<It::reference, int&&>::value, "");
}
{
typedef DummyIt<int, int&&> T;
typedef std::move_iterator<T> It;
static_assert(std::is_same<It::reference, int&&>::value, "");
}
#endif
}

View File

@ -114,7 +114,7 @@
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2404">2404</a></td><td><code>mismatch()</code>'s complexity needs to be updated</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2408">2408</a></td><td>SFINAE-friendly <code>common_type</code> / <code>iterator_traits</code> is missing in C++14</td><td>Urbana</td><td><code>common_type</code> is waiting on <a href="http://cplusplus.github.io/LWG/lwg-defects.html#2465">LWG#2465</a></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2106">2106</td><td><code>move_iterator</code> wrapping iterators returning prvalues</td><td>Urbana</td><td></td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2106">2106</td><td><code>move_iterator</code> wrapping iterators returning prvalues</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2129">2129</td><td>User specializations of <code>std::initializer_list</code></td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2212">2212</td><td><code>tuple_size</code> for <code>const pair</code> request <tuple> header</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2217">2217</td><td><code>operator==(sub_match, string)</code> slices on embedded '\0's</td><td>Urbana</td><td>Complete</td></tr>