From dd4a867781ab1b8d7c36c65b9446d22a1b480081 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 24 Apr 2018 15:37:44 +0200 Subject: [PATCH] tune unique to handle pointers properly --- alib2std/src/extensions/algorithm.hpp | 68 +++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/alib2std/src/extensions/algorithm.hpp b/alib2std/src/extensions/algorithm.hpp index b86b4eac9e..9c42f5b544 100644 --- a/alib2std/src/extensions/algorithm.hpp +++ b/alib2std/src/extensions/algorithm.hpp @@ -140,6 +140,74 @@ const T & min ( const T & a, const T & b, const Args & ... args) { return min ( b > a ? a : b, args ... ); } +template < typename _ForwardIterator, typename _BinaryPredicate > +_ForwardIterator __adjacent_find ( _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred ) { + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while (++__next != __last) { + if ( __binary_pred( * __first, * __next ) ) + return __first; + __first = __next; + } + return __last; +} + +template < typename _ForwardIterator, typename _BinaryPredicate > +_ForwardIterator __unique ( _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred ) { + // Skip the beginning, if already unique. + __first = ext::__adjacent_find ( __first, __last, __binary_pred ); + if ( __first == __last ) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; + ++ __first; + while ( ++__first != __last ) + if ( ! __binary_pred ( * __dest, * __first ) ) + std::swap ( * ++__dest, * __first ); + return ++ __dest; +} + +/** + * @brief Shuffles values in a sequece so that consecutive duplicate values are pushed to the front and others to the back. + * @ingroup mutating_algorithms + * @param __first A forward iterator. + * @param __last A forward iterator. + * @return An iterator designating the end of the resulting sequence. + * + * All but the first element from each group of consecutive + * values that compare equal are pushed to the end of the sequence. + * unique() is stable, so the relative order of elements that are + * not pushed to the end is unchanged. + * Elements between the end of the resulting sequence and @p __last + * are still present, but their order is unspecified. +*/ +template < typename _ForwardIterator > +inline _ForwardIterator unique ( _ForwardIterator __first, _ForwardIterator __last ) { + return ext::__unique(__first, __last, [] ( const auto & a, const auto & b ) { return a == b; } ); +} + +/** + * @brief Shuffles values in a sequece so that consecutive duplicate values are pushed to the front and others to the back. + * @ingroup mutating_algorithms + * @param __first A forward iterator. + * @param __last A forward iterator. + * @param __binary_pred A binary predicate. + * @return An iterator designating the end of the resulting sequence. + * + * All but the first element from each group of consecutive + * values for which @p __binary_pred returns true are pushed to the end of the sequence. + * unique() is stable, so the relative order of elements that are + * not pushed to the end is unchanged. + * Elements between the end of the resulting sequence and @p __last + * are still present, but their order is unspecified. +*/ +template < typename _ForwardIterator, typename _BinaryPredicate > +inline _ForwardIterator unique ( _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred ) { + return ext::__unique(__first, __last, __binary_pred ); +} + } /* namespace ext */ #endif /* __ALGORITHM_HPP_ */ -- GitLab