#include <iostream>
#include <list>
#include <memory>
#include "BLink.hh"
#include "BLinkable.hh"
#include "OwnedPtr.hh"
using namespace MangoPtr;
struct Callee;
struct Caller;
typedef BLink<const Callee> CalleePtr;
int created = 0;
int deleted = 0;
struct Callee: public BLinkable<>
{
const int id;
Callee(): id(++created) {
std::cout << "Callee " << id << " being created" << std::endl;}
~Callee() {
deleted ++;
std::cout << "Callee " << id << " being destroyed" << std::endl;
}
void registerSelf(Caller&) const;
void notifyChange() const
{
std::cout << "Callee " << id << " heard notification" << std::endl;
}
private:
Callee(const Callee& rhs);
};
struct Caller
{
std::list<CalleePtr> callees;
void registerCallee(const CalleePtr& callee)
{
assert(callee.isNotNull());
callees.push_back(callee);
}
void notifyCallees() const
{
for (std::list<CalleePtr>::const_iterator ii = callees.begin();
ii != callees.end(); ++ii)
{
if (ii->isNotNull()) (*ii)()->notifyChange();
else std::cout << "Callee no longer exists, not notifying"
<< std::endl;
}
}
};
void
Callee::registerSelf(Caller& caller)
const
{
caller.registerCallee(CalleePtr(*this));
}
int main()
{
Caller caller;
typedef Owned<Callee*, OShared> CalleeOwned;
std::list<CalleeOwned> callees;
for (int i=0; i<5; ++i)
{
std::auto_ptr<Callee> callee(new Callee);
assert(callee->getValidityOwner().isValid());
callee->registerSelf(caller);
callees.push_back(CalleeOwned());
assert( isNotNull(callee.get()) );
const int saveDeleted = deleted;
callees.back().takeOwnership( callee );
assert( isNull(callee.get()) );
assert( saveDeleted == deleted );
assert( isNotNull( callees.back()() ) );
assert( callees.back().isNotNull() );
}
callees.pop_front();
callees.pop_back();
caller.notifyCallees();
}