#include <iostream>
#include <list>
#include <memory>
#include "RRef.hh"
#include "RRefable.hh"
#include "DynObj.hh"
#include "DynTmp.hh"
using namespace NoPtr;
struct Callee;
struct Caller;
typedef RRef<const Callee> CalleePtr;
int created = 0;
int deleted = 0;
struct Callee: public RRefable
{
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;
std::cout << "Creation and registration:" << std::endl;
typedef DynObj<Callee>::InValueContainerOpt2 CalleeOwned;
std::list<CalleeOwned> callees;
for (int i=0; i<5; ++i)
{
DynObj<Callee> callee(new Callee);
callee().registerSelf(caller);
callees.push_back(callee.giveAway());
assert( isNull(callee) );
assert( isNotNull( callees.back() ) );
assert( callees.back().isNotNull() );
}
std::cout << "Destruction of first and last:" << std::endl;
callees.pop_front();
callees.pop_back();
std::cout << "Notification of callees:" << std::endl;
caller.notifyCallees();
std::cout << "Done program:" << std::endl;
}