summaryrefslogtreecommitdiffstats
path: root/libstdc++-v3/include/bits/stl_algo.h
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-08 16:12:13 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-08 16:12:13 +0000
commit5b67eee55e2efd02eea37d1dd2647b908dfc8649 (patch)
tree2f38fba2ba34dabdab8dacae50f6a8e640cce001 /libstdc++-v3/include/bits/stl_algo.h
parentb82f961e82aeaeef49a8f9e6d94cb2c5800fa2a1 (diff)
downloadppe42-gcc-5b67eee55e2efd02eea37d1dd2647b908dfc8649.tar.gz
ppe42-gcc-5b67eee55e2efd02eea37d1dd2647b908dfc8649.zip
* include/bits/stl_algo.h (is_permutation): Add overloads from N3671.
* include/bits/stl_algobase.h (equal, mismatch): Likewise. * testsuite/25_algorithms/equal/1.cc: Remove duplicate test case. * testsuite/25_algorithms/equal/2.cc: New. * testsuite/25_algorithms/equal/check_type2.cc: New. * testsuite/25_algorithms/is_permutationqual/2.cc: New. * testsuite/25_algorithms/is_permutationqual/check_type2.cc: New. * testsuite/25_algorithms/mismatch/2.cc: New. * testsuite/25_algorithms/mismatch/check_type2.cc: New. * testsuite/util/testsuite_iterators.h: Fix spelling. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199854 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/bits/stl_algo.h')
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h134
1 files changed, 134 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 873005b8b1a..e61f22b66a8 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -4371,6 +4371,140 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return true;
}
+#if __cplusplus > 201103L
+ /**
+ * @brief Checks whether a permutaion of the second sequence is equal
+ * to the first sequence.
+ * @ingroup non_mutating_algorithms
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of first range.
+ * @return true if there exists a permutation of the elements in the range
+ * [__first2, __last2), beginning with ForwardIterator2 begin,
+ * such that equal(__first1, __last1, begin) returns true;
+ * otherwise, returns false.
+ */
+ template<typename _ForwardIterator1, typename _ForwardIterator2>
+ bool
+ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+ {
+ using _Cat1
+ = typename iterator_traits<_ForwardIterator1>::iterator_category;
+ using _Cat2
+ = typename iterator_traits<_ForwardIterator2>::iterator_category;
+ using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>;
+ using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>;
+ if (_It1_is_RA() && _It1_is_RA())
+ {
+ auto __d1 = std::distance(__first1, __last1);
+ auto __d2 = std::distance(__first2, __last2);
+ if (__d1 != __d2)
+ return false;
+ }
+
+ // Efficiently compare identical prefixes: O(N) if sequences
+ // have the same elements in the same order.
+ for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+ if (!(*__first1 == *__first2))
+ break;
+
+ if (__first1 == __last1 && __first2 == __last2)
+ return true;
+
+ if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
+ return false;
+
+ for (auto __scan = __first1; __scan != __last1; ++__scan)
+ {
+ if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan))
+ continue; // We've seen this one before.
+
+ auto __matches = std::count(__first2, __last2, *__scan);
+ if (0 == __matches
+ || std::count(__scan, __last1, *__scan) != __matches)
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @brief Checks whether a permutation of the second sequence is equal
+ * to the first sequence.
+ * @ingroup non_mutating_algorithms
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of first range.
+ * @param __pred A binary predicate.
+ * @return true if there exists a permutation of the elements in the range
+ * [__first2, __last2), beginning with ForwardIterator2 begin,
+ * such that equal(__first1, __last1, __begin, __pred) returns true;
+ * otherwise, returns false.
+ */
+ template<typename _ForwardIterator1, typename _ForwardIterator2,
+ typename _BinaryPredicate>
+ bool
+ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+ _BinaryPredicate __pred)
+ {
+ using _Cat1
+ = typename iterator_traits<_ForwardIterator1>::iterator_category;
+ using _Cat2
+ = typename iterator_traits<_ForwardIterator2>::iterator_category;
+ using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>;
+ using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>;
+ constexpr bool __ra_iters = _It1_is_RA() && _It1_is_RA();
+ if (__ra_iters)
+ {
+ auto __d1 = std::distance(__first1, __last1);
+ auto __d2 = std::distance(__first2, __last2);
+ if (__d1 != __d2)
+ return false;
+ }
+
+ // Efficiently compare identical prefixes: O(N) if sequences
+ // have the same elements in the same order.
+ for (; __first1 != __last1; ++__first1, ++__first2)
+ if (!bool(__pred(*__first1, *__first2)))
+ break;
+
+ if (__ra_iters)
+ {
+ if (__first1 == __last1)
+ return true;
+ }
+ else
+ {
+ auto __d1 = std::distance(__first1, __last1);
+ auto __d2 = std::distance(__first2, __last2);
+ if (__d1 == 0 && __d2 == 0)
+ return true;
+ if (__d1 != __d2)
+ return false;
+ }
+
+ for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
+ {
+ using std::placeholders::_1;
+
+ if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan,
+ std::bind(__pred, _1, *__scan)))
+ continue; // We've seen this one before.
+
+ auto __matches = std::count_if(__first2, __last2,
+ std::bind(__pred, _1, *__scan));
+ if (0 == __matches
+ || std::count_if(__scan, __last1,
+ std::bind(__pred, _1, *__scan)) != __matches)
+ return false;
+ }
+ return true;
+ }
+#endif
+
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
/**
* @brief Shuffle the elements of a sequence using a uniform random
OpenPOWER on IntegriCloud