Skip to content

Instantly share code, notes, and snippets.

@vittorioromeo
Last active August 29, 2015 14:01
Show Gist options
  • Save vittorioromeo/68ec51f64ca5add01b4f to your computer and use it in GitHub Desktop.
Save vittorioromeo/68ec51f64ca5add01b4f to your computer and use it in GitHub Desktop.
#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