diff --git a/alib2std/src/extensions/foreach.hpp b/alib2std/src/extensions/foreach.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e036cc8467201ee6942c92547a6a24b19a893608 --- /dev/null +++ b/alib2std/src/extensions/foreach.hpp @@ -0,0 +1,125 @@ +/* + * foreach.hpp + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#ifndef __FOREACH_HPP_ +#define __FOREACH_HPP_ + +namespace std { + +template <class Iterator1, class Iterator2> +class const_pair_foreach_iterator { + Iterator1 current1; + Iterator2 current2; + +public: + typedef Iterator1 iterator_type1; + typedef typename iterator_traits<Iterator1>::iterator_category iterator_category1; + typedef typename iterator_traits<Iterator1>::value_type value_type1; + typedef Iterator1 pointer1; + typedef const value_type1& reference1; + + typedef Iterator2 iterator_type2; + typedef typename iterator_traits<Iterator2>::iterator_category iterator_category2; + typedef typename iterator_traits<Iterator2>::value_type value_type2; + typedef Iterator2 pointer2; + typedef const value_type2& reference2; + + explicit const_pair_foreach_iterator() { + } + + explicit const_pair_foreach_iterator (Iterator1 it1, Iterator2 it2) : current1(it1), current2(it2) { + } + + const_pair_foreach_iterator (const const_pair_foreach_iterator<Iterator1, Iterator2>& it) : current1(it.current1), current2(it.current2) { + } + + const_pair_foreach_iterator& operator= (const const_pair_foreach_iterator<Iterator1, Iterator2>& it) { + current1 = it.current1; + current2 = it.current2; + } + + iterator_type1 base1() const { + return current1; + } + + iterator_type2 base2() const { + return current2; + } + + std::tuple<reference1, reference2> operator*() const { + return std::tie(*current1, *current2); + } + + const_pair_foreach_iterator& operator++() { + ++current1; + ++current2; + return *this; + } + + const_pair_foreach_iterator& operator--() { + --current1; + --current2; + return *this; + } + + const_pair_foreach_iterator& operator++(int) { + const_pair_foreach_iterator temp = *this; + ++current1; + ++current2; + return temp; + } + + const_pair_foreach_iterator& operator--(int) { + const_pair_foreach_iterator temp = *this; + --current1; + --current2; + return temp; + } + + bool operator== (const const_pair_foreach_iterator<Iterator1, Iterator2>& other) { + return this->current1 == other.current1 && this->current2 == other.current2; + } + + bool operator!= (const const_pair_foreach_iterator<Iterator1, Iterator2>& other) { + return ! ( *this == other ); + } + +}; + +template<class Iterator1, class Iterator2> +const_pair_foreach_iterator<Iterator1, Iterator2> make_pair_foreach_iterator (Iterator1 it1, Iterator2 it2) { + return const_pair_foreach_iterator<Iterator1, Iterator2>(it1, it2); +} + +template<class T, class R> +class const_pair_foreach { + + const T& first; + const R& second; + +public: + const_pair_foreach(const T& first, const R& second) : first(first), second(second) {} + + const_pair_foreach_iterator<typename T::const_iterator, typename R::const_iterator> begin() const { + return make_pair_foreach_iterator(first.begin(), second.begin()); + } + + const_pair_foreach_iterator<typename T::const_iterator, typename R::const_iterator> end() const { + return make_pair_foreach_iterator(first.end(), second.end()); + } + +}; + +template<class T, class R> +const_pair_foreach<T, R> make_pair_foreach(const T& first, const R& second) { + return const_pair_foreach<T, R>(first, second); +} + +} /* namespace std */ + +#endif /* __FOREACH_HPP_ */ + diff --git a/alib2std/src/foreach b/alib2std/src/foreach new file mode 100644 index 0000000000000000000000000000000000000000..ebe1467f89cce2273385a6a4924bbddec819c9b4 --- /dev/null +++ b/alib2std/src/foreach @@ -0,0 +1,8 @@ +#ifndef __FOREACH_HEADER_WRAPPER_ +#define __FOREACH_HEADER_WRAPPER_ + +#include "tuple" +#include "extensions/foreach.hpp" + +#endif /* __FOREACH_HEADER_WRAPPER_ */ + diff --git a/alib2std/test-src/extensions/ForeachTest.cpp b/alib2std/test-src/extensions/ForeachTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0f4051edad94c09efa944e22949b76385c06b8f --- /dev/null +++ b/alib2std/test-src/extensions/ForeachTest.cpp @@ -0,0 +1,27 @@ +#include "ForeachTest.h" +#include <list> +#include <vector> +#include <foreach> + + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ForeachTest, "bits" ); +CPPUNIT_TEST_SUITE_REGISTRATION( ForeachTest ); + +void ForeachTest::setUp() { +} + +void ForeachTest::tearDown() { +} + +void ForeachTest::testForeach() { + std::vector<int> vector1 {1, 2, 3}; + std::list<int> vector2 {2, 3, 4}; + + int i = 1; + for(const std::tuple<const int&, const int&>& elements : std::make_pair_foreach(vector1, vector2)) { + CPPUNIT_ASSERT(std::get<0>(elements) == i); + CPPUNIT_ASSERT(std::get<1>(elements) == i + 1); + i++; + } +} + diff --git a/alib2std/test-src/extensions/ForeachTest.h b/alib2std/test-src/extensions/ForeachTest.h new file mode 100644 index 0000000000000000000000000000000000000000..e64820a28bb0ce2b3f8486bf5e4bcba58d03ad02 --- /dev/null +++ b/alib2std/test-src/extensions/ForeachTest.h @@ -0,0 +1,19 @@ +#ifndef COMPARE_TEST_H_ +#define COMPARE_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class ForeachTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( ForeachTest ); + CPPUNIT_TEST( testForeach ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testForeach(); +}; + +#endif // COMPARE_TEST_H_