From c79eae8e9b57baf6c07c81f627efc3bc71426f9b Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 30 Jan 2019 15:02:10 +0100
Subject: [PATCH] add function to test whether iterator is in range

---
 alib2std/src/extensions/algorithm.hpp          | 16 ++++++++++++++++
 alib2std/test-src/extensions/AlgorithmTest.cpp | 15 +++++++++++++++
 alib2std/test-src/extensions/AlgorithmTest.h   |  2 ++
 3 files changed, 33 insertions(+)

diff --git a/alib2std/src/extensions/algorithm.hpp b/alib2std/src/extensions/algorithm.hpp
index 5efa54d9e4..d67c4799cd 100644
--- a/alib2std/src/extensions/algorithm.hpp
+++ b/alib2std/src/extensions/algorithm.hpp
@@ -406,6 +406,22 @@ inline _ForwardIterator unique ( _ForwardIterator __first, _ForwardIterator __la
 	return ext::__unique(__first, __last, __binary_pred );
 }
 
+/**
+ * @brief determines if iterator @p candidate is in range [@p from, @p to).
+ * @param from the beginning of the tested range
+ * @param end the ending of the tested range
+ * @param candidate the tested iterator
+ *
+ * @return true if the candidate iterator is in provided range
+ */
+template < class ForwardIteratorBegin, class ForwardIteratorEnd, class ForwardCandidateIterator >
+inline bool range_contains_iterator ( ForwardIteratorBegin from, const ForwardIteratorEnd & end, const ForwardCandidateIterator & candidate ) {
+	for ( ; from != end; ++ from )
+		if ( ( void * ) std::addressof ( * from ) == ( const void * ) std::addressof ( * candidate ) )
+			return true;
+	return false;
+}
+
 } /* namespace ext */
 
 #endif /* __ALGORITHM_HPP_ */
diff --git a/alib2std/test-src/extensions/AlgorithmTest.cpp b/alib2std/test-src/extensions/AlgorithmTest.cpp
index 3a35c1471c..0979b622dd 100644
--- a/alib2std/test-src/extensions/AlgorithmTest.cpp
+++ b/alib2std/test-src/extensions/AlgorithmTest.cpp
@@ -2,6 +2,7 @@
 #include <alib/algorithm>
 #include <alib/set>
 #include <alib/vector>
+#include <alib/list>
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AlgorithmTest, "bits" );
 CPPUNIT_TEST_SUITE_REGISTRATION( AlgorithmTest );
@@ -156,3 +157,17 @@ void AlgorithmTest::testSymmetricDifference ( ) {
 	CPPUNIT_ASSERT ( a_b == a_b2 );
 	CPPUNIT_ASSERT ( b_a == b_a2 );
 }
+
+void AlgorithmTest::testRangeContainsIterator ( ) {
+	std::list < int > test = { 1, 2, 3, 4, 5, 6 };
+	std::list < int > other = { 1, 2, 3, 4, 5, 6, 7 };
+	std::list < char > other2 = { 'a', 'b', 'c' };
+
+	std::list < int >::iterator iter = test.begin ( );
+	iter++;
+	iter++;
+
+	CPPUNIT_ASSERT ( ext::range_contains_iterator ( test.begin ( ), test.end ( ), iter ) );
+	CPPUNIT_ASSERT ( ! ext::range_contains_iterator ( other.begin ( ), other.end ( ), iter ) );
+	CPPUNIT_ASSERT ( ! ext::range_contains_iterator ( other2.begin ( ), other2.end ( ), iter ) );
+}
diff --git a/alib2std/test-src/extensions/AlgorithmTest.h b/alib2std/test-src/extensions/AlgorithmTest.h
index f10b9b302b..b9e589f788 100644
--- a/alib2std/test-src/extensions/AlgorithmTest.h
+++ b/alib2std/test-src/extensions/AlgorithmTest.h
@@ -10,6 +10,7 @@ class AlgorithmTest : public CppUnit::TestFixture
   CPPUNIT_TEST( testTransform );
   CPPUNIT_TEST( testFindRange );
   CPPUNIT_TEST( testSymmetricDifference );
+  CPPUNIT_TEST( testRangeContainsIterator );
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -20,6 +21,7 @@ public:
   void testTransform();
   void testFindRange();
   void testSymmetricDifference ( );
+  void testRangeContainsIterator ( );
 };
 
 #endif  // ALGORITHM_TEST_H_
-- 
GitLab