Skip to content

Instantly share code, notes, and snippets.

@Folling
Created January 31, 2018 21:12
Show Gist options
  • Save Folling/a71c25275d30babf79d42dd984cb3426 to your computer and use it in GitHub Desktop.
Save Folling/a71c25275d30babf79d42dd984cb3426 to your computer and use it in GitHub Desktop.
#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