Last active
August 29, 2015 14:01
-
-
Save vittorioromeo/68ec51f64ca5add01b4f to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <SSVUtils/SSVUtils.hpp> | |
using Idx = std::size_t; | |
using Ctr = int; | |
struct Manager; | |
class Handle; | |
struct Impl | |
{ | |
std::string test; | |
}; | |
struct Atom | |
{ | |
Impl impl; | |
Idx ctrlIdx; | |
bool alive{false}; | |
}; | |
class Controller | |
{ | |
friend struct Manager; | |
friend class Handle; | |
private: | |
Idx idx; | |
Ctr ctr; | |
public: | |
inline Controller(Idx mIdx) noexcept : idx{mIdx} { } | |
}; | |
class Handle | |
{ | |
friend struct Manager; | |
private: | |
Manager& manager; | |
Idx ctrlIdx; | |
Ctr ctr; | |
inline Handle(Manager& mManager, Idx mCtrlIdx, Ctr mCtr) noexcept : manager(mManager), ctrlIdx{mCtrlIdx}, ctr{mCtr} { } | |
public: | |
Atom& getAtom(); | |
bool isAlive(); | |
}; | |
struct Manager | |
{ | |
std::vector<Atom> atoms; | |
std::vector<Controller> controllers; | |
Idx lastFree{0u}; | |
inline Manager() | |
{ | |
} | |
inline Handle createAtom() | |
{ | |
if(atoms.size() <= lastFree) | |
{ | |
auto oldSize(atoms.size()); | |
auto newSize(oldSize + 10); | |
atoms.resize(newSize); | |
controllers.reserve(newSize); | |
for(auto i(oldSize); i < newSize; ++i) | |
{ | |
atoms[i].ctrlIdx = i; | |
controllers.emplace_back(i); | |
} | |
} | |
//atoms[lastFree] = Atom{}; | |
atoms[lastFree].alive = true; | |
auto cIdx(atoms[lastFree].ctrlIdx); | |
controllers[cIdx].idx = lastFree; | |
++(controllers[cIdx].ctr); | |
++lastFree; | |
return {*this, cIdx, controllers[cIdx].ctr}; | |
} | |
inline void refresh() | |
{ | |
ssvu::sortStable(atoms, [](const Atom& mA, const Atom& mB){ return mA.alive > mB.alive; }); | |
auto rIdx(atoms.size() - 1); | |
for(; !atoms[rIdx].alive && rIdx > 0; --rIdx) | |
{ | |
auto& controller(controllers[atoms[rIdx].ctrlIdx]); | |
++(controller.ctr); | |
controller.idx = -1; | |
} | |
for(auto fIdx(0u); fIdx <= rIdx; ++fIdx) controllers[atoms[fIdx].ctrlIdx].idx = fIdx; | |
} | |
void printState() | |
{ | |
ssvu::lo("ATOMS") << ""; | |
for(const auto& a : atoms) std::cout << std::setw(4) << std::left << (int)a.alive << " "; | |
std::cout << std::endl; | |
ssvu::lo("CTIDX") << ""; | |
for(const auto& a : controllers) std::cout << std::setw(4) << std::left << (int)a.idx << " "; | |
std::cout << std::endl; | |
ssvu::lo("CTCTR") << ""; | |
for(const auto& a : controllers) std::cout << std::setw(4) << std::left << (int)a.ctr << " "; | |
std::cout << std::endl << std::endl; | |
ssvu::lo("ASTRS") << "\n"; | |
std::size_t idx{0u}; | |
for(const auto& a : atoms) std::cout << idx++ << ": " << a.impl.test << "\n"; | |
std::cout << std::endl; | |
} | |
}; | |
inline Atom& Handle::getAtom() | |
{ | |
return manager.atoms[manager.controllers[ctrlIdx].idx]; | |
} | |
inline bool Handle::isAlive() | |
{ | |
return manager.controllers[ctrlIdx].ctr == ctr; | |
} | |
int main() | |
{ | |
Manager test; | |
test.printState(); | |
auto a0 = test.createAtom(); | |
auto a1 = test.createAtom(); | |
auto a2 = test.createAtom(); | |
auto a3 = test.createAtom(); | |
auto a4 = test.createAtom(); | |
auto a5 = test.createAtom(); | |
auto a6 = test.createAtom(); | |
a0.getAtom().impl.test = "hi"; | |
a4.getAtom().impl.test = "ciao"; | |
a6.getAtom().impl.test = "bye"; | |
test.printState(); | |
test.atoms[2].alive = false; | |
test.atoms[3].alive = false; | |
test.atoms[5].alive = false; | |
test.printState(); | |
test.refresh(); | |
test.printState(); | |
ssvu::lo("RESULT") << a0.getAtom().impl.test << std::endl; | |
ssvu::lo("RESULT") << a4.getAtom().impl.test << std::endl; | |
ssvu::lo("RESULT") << a6.getAtom().impl.test << std::endl; | |
ssvu::lo("alive") << a0.isAlive() << std::endl; | |
ssvu::lo("alive") << a1.isAlive() << std::endl; | |
ssvu::lo("alive") << a2.isAlive() << std::endl; | |
ssvu::lo("alive") << a3.isAlive() << std::endl; | |
ssvu::lo("alive") << a4.isAlive() << std::endl; | |
ssvu::lo("alive") << a5.isAlive() << std::endl; | |
ssvu::lo("alive") << a6.isAlive() << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment