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