Created
January 31, 2018 21:12
-
-
Save Folling/a71c25275d30babf79d42dd984cb3426 to your computer and use it in GitHub Desktop.
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 <functional> | |
#include <set> | |
template<typename T> | |
using rw = std::reference_wrapper<T>; | |
template<typename T> | |
using crw = const std::reference_wrapper<T>; | |
// used to Associate different types with another, so if one type changes | |
// so does the other, as specified by the optional function | |
template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> | |
struct Assoc { | |
explicit Assoc(T& subject): value(subject) { | |
} | |
// function to set what the appropriate ratio is | |
// if the original value increases by 10, it'll be passed to this function to make it appropriate | |
std::function<T()> function = [&]() { return 1; }; | |
T& value; | |
bool operator==(Assoc<T> comparant){ | |
if(function == comparant.function && &value == &comparant.value) { | |
return true; | |
} | |
return false; | |
} | |
friend bool operator <(crw<Assoc<T>> lhs, crw<Assoc<T>> rhs) { | |
return lhs.get().value < rhs.get().value; | |
} | |
}; | |
template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> | |
class Associative { | |
public: | |
Associative(); | |
~Associative(); | |
public: | |
bool AddAssociation(Assoc<T>& toAdd); | |
void RemoveAssociation(Assoc<T>& toRemove); | |
[[nodiscard]] | |
bool IsAssociating(T& subject); | |
public: | |
void operator+(T& summand); | |
void operator-(T& subtrahend); | |
void operator*(T& factor); | |
void operator/(T& divisor); | |
void operator%(T& divisor); | |
void operator += (T& summand); | |
void operator -= (T& subtrahend); | |
void operator *= (T& factor); | |
void operator /= (T& divisor); | |
void operator %= (T& divisor); | |
public: | |
private: | |
std::set<rw<Assoc<T>>> assocs; | |
}; | |
template <typename T, typename U> | |
Associative<T,U>::Associative() { | |
} | |
template <typename T, typename U> | |
::Associative<T,U>::~Associative() { | |
} | |
template <typename T, typename U> | |
bool Associative<T,U>::IsAssociating(T& subject) { | |
return (std::find_if(assocs.begin(), assocs.end(), | |
[&](Assoc<T>& a) { return &a.value == &subject; }) != assocs.end()); | |
} | |
template <typename T, typename U> | |
void Associative<T,U>::RemoveAssociation(Assoc<T>& toRemove) { | |
auto pos = assocs.find(toRemove); | |
if (pos != assocs.end()); | |
assocs.erase(pos); | |
} | |
template <typename T, typename U> | |
bool Associative<T, U>::AddAssociation(Assoc<T>& toAdd) { | |
// adds a reference to our set, and returns whether it was successful. | |
// since equal objects shouldn't be considered. | |
return assocs.insert(std::ref(toAdd)).second; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment