/// This is a helper function for the rotate algorithm.
template<typename _ForwardIterator>
- void
+ _ForwardIterator
__rotate(_ForwardIterator __first,
_ForwardIterator __middle,
_ForwardIterator __last,
forward_iterator_tag)
{
- if (__first == __middle || __last == __middle)
- return;
+ if (__first == __middle)
+ return __last;
+ else if (__last == __middle)
+ return __first;
_ForwardIterator __first2 = __middle;
do
}
while (__first2 != __last);
+ _ForwardIterator __ret = __first;
+
__first2 = __middle;
while (__first2 != __last)
else if (__first2 == __last)
__first2 = __middle;
}
+ return __ret;
}
/// This is a helper function for the rotate algorithm.
template<typename _BidirectionalIterator>
- void
+ _BidirectionalIterator
__rotate(_BidirectionalIterator __first,
_BidirectionalIterator __middle,
_BidirectionalIterator __last,
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
_BidirectionalIterator>)
- if (__first == __middle || __last == __middle)
- return;
+ if (__first == __middle)
+ return __last;
+ else if (__last == __middle)
+ return __first;
std::__reverse(__first, __middle, bidirectional_iterator_tag());
std::__reverse(__middle, __last, bidirectional_iterator_tag());
}
if (__first == __middle)
- std::__reverse(__middle, __last, bidirectional_iterator_tag());
+ {
+ std::__reverse(__middle, __last, bidirectional_iterator_tag());
+ return __last;
+ }
else
- std::__reverse(__first, __middle, bidirectional_iterator_tag());
+ {
+ std::__reverse(__first, __middle, bidirectional_iterator_tag());
+ return __first;
+ }
}
/// This is a helper function for the rotate algorithm.
template<typename _RandomAccessIterator>
- void
+ _RandomAccessIterator
__rotate(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
_RandomAccessIterator __last,
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
- if (__first == __middle || __last == __middle)
- return;
+ if (__first == __middle)
+ return __last;
+ else if (__last == __middle)
+ return __first;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_Distance;
if (__k == __n - __k)
{
std::swap_ranges(__first, __middle, __middle);
- return;
+ return __middle;
}
_RandomAccessIterator __p = __first;
+ _RandomAccessIterator __ret = __first + (__last - __middle);
for (;;)
{
_ValueType __t = _GLIBCXX_MOVE(*__p);
_GLIBCXX_MOVE3(__p + 1, __p + __n, __p);
*(__p + __n - 1) = _GLIBCXX_MOVE(__t);
- return;
+ return __ret;
}
_RandomAccessIterator __q = __p + __k;
for (_Distance __i = 0; __i < __n - __k; ++ __i)
}
__n %= __k;
if (__n == 0)
- return;
+ return __ret;
std::swap(__n, __k);
__k = __n - __k;
}
_ValueType __t = _GLIBCXX_MOVE(*(__p + __n - 1));
_GLIBCXX_MOVE_BACKWARD3(__p, __p + __n - 1, __p + __n);
*__p = _GLIBCXX_MOVE(__t);
- return;
+ return __ret;
}
_RandomAccessIterator __q = __p + __n;
__p = __q - __k;
}
__n %= __k;
if (__n == 0)
- return;
+ return __ret;
std::swap(__n, __k);
}
}
}
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 488. rotate throws away useful information
/**
* @brief Rotate the elements of a sequence.
* @ingroup mutating_algorithms
* @param __first A forward iterator.
* @param __middle A forward iterator.
* @param __last A forward iterator.
- * @return Nothing.
+ * @return first + (last - middle).
*
* Rotates the elements of the range @p [__first,__last) by
* @p (__middle - __first) positions so that the element at @p __middle
* for each @p n in the range @p [0,__last-__first).
*/
template<typename _ForwardIterator>
- inline void
+ inline _ForwardIterator
rotate(_ForwardIterator __first, _ForwardIterator __middle,
_ForwardIterator __last)
{
__glibcxx_requires_valid_range(__first, __middle);
__glibcxx_requires_valid_range(__middle, __last);
- std::__rotate(__first, __middle, __last,
- std::__iterator_category(__first));
+ return std::__rotate(__first, __middle, __last,
+ std::__iterator_category(__first));
}
/**
bool operator<(X,X) { return true;}
-void
+__gnu_test::forward_iterator_wrapper<X>
test1(__gnu_test::forward_iterator_wrapper<X>& begin,
__gnu_test::forward_iterator_wrapper<X>& middle,
__gnu_test::forward_iterator_wrapper<X>& end)
{ return std::rotate(begin,middle,end); }
-void
+__gnu_test::bidirectional_iterator_wrapper<X>
test1(__gnu_test::bidirectional_iterator_wrapper<X>& begin,
__gnu_test::bidirectional_iterator_wrapper<X>& middle,
__gnu_test::bidirectional_iterator_wrapper<X>& end)
{ return std::rotate(begin,middle,end); }
-void
+__gnu_test::random_access_iterator_wrapper<X>
test1(__gnu_test::random_access_iterator_wrapper<X>& begin,
__gnu_test::random_access_iterator_wrapper<X>& middle,
__gnu_test::random_access_iterator_wrapper<X>& end)
--- /dev/null
+// Copyright (C) 2015 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 <algorithm>
+#include <iterator>
+#include <forward_list>
+#include <list>
+#include <vector>
+#include <testsuite_hooks.h>
+
+template<typename Container>
+void
+test(Container& c)
+{
+ int size = std::distance(c.begin(), c.end());
+ for (int i=0; i < size; ++i)
+ {
+ auto first = c.begin(), middle = std::next(first, i), last = c.end();
+ auto r = std::rotate(first, middle, last);
+ auto expected = std::next(first, std::distance(middle, last));
+ VERIFY( r == expected );
+ }
+}
+
+void
+test01()
+{
+ // test random access iterators
+ std::vector<int> v{ 0, 1, 2, 3, 4 };
+ test(v);
+ v.push_back(5);
+ test(v);
+}
+
+void
+test02()
+{
+ // test bidirectional iterators
+ std::list<int> l{ 0, 1, 2, 3, 4 };
+ test(l);
+ l.push_back(5);
+ test(l);
+}
+
+void
+test03()
+{
+ // test forward iterators
+ std::forward_list<int> l{ 0, 1, 2, 3, 4 };
+ test(l);
+ l.push_front(5);
+ test(l);
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}