1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
#ifndef LINKABLE_H
#define LINKABLE_H
#include <algorithm>
#include <memory>
#include <vector>
struct LinkableDefaultData {};
template <typename Implementation, typename SharedData = LinkableDefaultData>
class Linkable {
public:
using iterator = typename std::vector<Implementation*>::iterator;
using const_iterator = typename std::vector<Implementation*>::const_iterator;
Linkable() : _group(new Group()) {
_group->members.emplace_back(static_cast<Implementation*>(this));
}
~Linkable() { Unlink(); }
void Link(Implementation& other) {
// Are they not linked yet?
if (other._group != _group) {
std::shared_ptr<Group> otherGroup = other._group;
// Combine the two groups
for (auto& scalePtr : otherGroup->members) {
scalePtr->_group = _group;
_group->members.emplace_back(scalePtr);
}
}
}
void Unlink() {
auto& members = _group->members;
members.erase(std::find(members.begin(), members.end(), this));
_group = std::make_shared<Group>();
_group->members.emplace_back(static_cast<Implementation*>(this));
}
bool IsLinked() const { return _group->members.size() > 1; }
SharedData& Data() { return _group->shared; }
const SharedData& Data() const { return _group->shared; }
iterator begin() { return _group->members.begin(); }
const_iterator begin() const { return _group->members.begin(); }
iterator end() { return _group->members.end(); }
const_iterator end() const { return _group->members.end(); }
size_t MemberCount() const { return _group->members.size(); }
private:
struct Group {
SharedData shared;
std::vector<Implementation*> members;
};
std::shared_ptr<Group> _group;
};
#endif
|