Created
July 14, 2017 08:41
-
-
Save Psirus/b85a51a50d47ae32f24710e2abf5969e to your computer and use it in GitHub Desktop.
GroupRefactor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <algorithm> | |
#include <vector> | |
#include <boost/iterator/indirect_iterator.hpp> | |
namespace NuTo | |
{ | |
namespace Groups | |
{ | |
template <typename T> | |
class Group : private std::vector<T*> | |
{ | |
public: | |
typedef std::vector<T*> parent; | |
typedef boost::indirect_iterator<typename parent::iterator> GroupIterator; | |
void AddMember(T& element) | |
{ | |
parent::push_back(&element); | |
} | |
GroupIterator begin() | |
{ | |
return parent::begin(); | |
} | |
GroupIterator end() | |
{ | |
return parent::end(); | |
} | |
typename parent::iterator pbegin() | |
{ | |
return parent::begin(); | |
} | |
typename parent::iterator pend() | |
{ | |
return parent::end(); | |
} | |
typename parent::const_iterator pcbegin() const | |
{ | |
return parent::cbegin(); | |
} | |
typename parent::const_iterator pcend() const | |
{ | |
return parent::cend(); | |
} | |
bool Contains(const T& element) | |
{ | |
auto result = std::find(parent::begin(), parent::end(), &element); | |
if (result != parent::end()) | |
return true; | |
else | |
return false; | |
} | |
using parent::size; | |
using typename parent::iterator; | |
using typename parent::value_type; | |
using parent::insert; | |
}; | |
template <typename T> | |
Group<T> Unite(const Group<T>& one, const Group<T>& two) | |
{ | |
Group<T> newGroup; | |
std::insert_iterator<Group<T>> newGroupInsertIterator(newGroup, newGroup.pbegin()); | |
std::set_union(one.pcbegin(), one.pcend(), two.pcbegin(), two.pcend(), newGroupInsertIterator); | |
return newGroup; | |
} | |
template <typename T> | |
Group<T> Difference(const Group<T>& one, const Group<T>& two) | |
{ | |
Group<T> newGroup; | |
std::insert_iterator<Group<T>> newGroupInsertIterator(newGroup, newGroup.pbegin()); | |
std::set_difference(one.pcbegin(), one.pcend(), two.pcbegin(), two.pcend(), newGroupInsertIterator); | |
return newGroup; | |
} | |
template <typename T> | |
Group<T> Intersection(const Group<T>& one, const Group<T>& two) | |
{ | |
Group<T> newGroup; | |
std::insert_iterator<Group<T>> newGroupInsertIterator(newGroup, newGroup.pbegin()); | |
std::set_intersection(one.pcbegin(), one.pcend(), two.pcbegin(), two.pcend(), newGroupInsertIterator); | |
return newGroup; | |
} | |
template <typename T> | |
Group<T> SymmetricDifference(const Group<T>& one, const Group<T>& two) | |
{ | |
Group<T> newGroup; | |
std::insert_iterator<Group<T>> newGroupInsertIterator(newGroup, newGroup.pbegin()); | |
std::set_symmetric_difference(one.pcbegin(), one.pcend(), two.pcbegin(), two.pcend(), newGroupInsertIterator); | |
return newGroup; | |
} | |
} // namespace Group | |
} // namespace NuTo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "BoostUnitTest.h" | |
#include "base/Group.h" | |
#include <iostream> | |
using namespace NuTo; | |
BOOST_AUTO_TEST_CASE(ContainsTest) | |
{ | |
Groups::Group<int> group; | |
int a = 0; | |
BOOST_CHECK(not group.Contains(a)); | |
group.AddMember(a); | |
BOOST_CHECK(group.Contains(a)); | |
group.AddMember(a); | |
BOOST_CHECK(group.Contains(a)); | |
} | |
class Foo | |
{ | |
}; | |
struct GroupTestFixture | |
{ | |
GroupTestFixture() | |
{ | |
groupOne.AddMember(a); | |
groupOne.AddMember(b); | |
groupOne.AddMember(c); | |
groupTwo.AddMember(c); | |
groupTwo.AddMember(d); | |
} | |
Foo a, b, c, d; | |
Groups::Group<Foo> groupOne; | |
Groups::Group<Foo> groupTwo; | |
}; | |
BOOST_FIXTURE_TEST_CASE(unionTest, GroupTestFixture) | |
{ | |
auto unionGroup = Groups::Unite(groupOne, groupTwo); | |
BOOST_CHECK_EQUAL(unionGroup.size(), 4); | |
BOOST_CHECK(unionGroup.Contains(a)); | |
BOOST_CHECK(unionGroup.Contains(b)); | |
BOOST_CHECK(unionGroup.Contains(c)); | |
BOOST_CHECK(unionGroup.Contains(d)); | |
} | |
BOOST_FIXTURE_TEST_CASE(differenceTest, GroupTestFixture) | |
{ | |
auto diffGroup = Groups::Difference(groupOne, groupTwo); | |
BOOST_CHECK_EQUAL(diffGroup.size(), 2); | |
BOOST_CHECK(diffGroup.Contains(a)); | |
BOOST_CHECK(diffGroup.Contains(b)); | |
} | |
BOOST_FIXTURE_TEST_CASE(intersectionTest, GroupTestFixture) | |
{ | |
auto intersectGroup = Groups::Intersection(groupOne, groupTwo); | |
BOOST_CHECK_EQUAL(intersectGroup.size(), 1); | |
BOOST_CHECK(intersectGroup.Contains(c)); | |
} | |
BOOST_FIXTURE_TEST_CASE(symmetricDiffTest, GroupTestFixture) | |
{ | |
auto symmetricDiffGroup = Groups::SymmetricDifference(groupOne, groupTwo); | |
BOOST_CHECK_EQUAL(symmetricDiffGroup.size(), 3); | |
BOOST_CHECK(symmetricDiffGroup.Contains(a)); | |
BOOST_CHECK(symmetricDiffGroup.Contains(b)); | |
BOOST_CHECK(symmetricDiffGroup.Contains(d)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment