diff options
author | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
---|---|---|
committer | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
commit | 420d2ef464d4a741028e132e662d5626806a41f5 (patch) | |
tree | 1aca6eb512e4ed0fb5f3c10c528cb998b6ffd695 /core/context.hpp |
Diffstat (limited to 'core/context.hpp')
-rw-r--r-- | core/context.hpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/core/context.hpp b/core/context.hpp new file mode 100644 index 0000000..dd4ed7e --- /dev/null +++ b/core/context.hpp @@ -0,0 +1,123 @@ +#ifndef sOuC39DJVwHiStoyuZdritpuC5M +#define sOuC39DJVwHiStoyuZdritpuC5M + +#include <assert.h> + +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/set.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/insert.hpp> +#include <boost/tuple/tuple.hpp> + +#include "pointers.hpp" +#include "time.hpp" +#include "type_set.hpp" + +/* methods common to all context's + + getptr<Quant>() -> return an instance id + + */ + +namespace ContextImpl { + + using namespace boost; + using namespace boost::mpl; + + // common context (internal) + template<typename... Quants> + struct CCtx : public TypeSet<Ptr<Quants>...> { + CCtx(Ptr<Quants>... ids) : TypeSet<Ptr<Quants>...>(std::move(ids)...) {} + + template<typename Quant> + typename Quant::instance_ptr_t getptr() { + return this->template get<Ptr<Quant>>(); + } + }; + + /// SingleContext: stores a single quant w/o any relation + template<typename Quant> + struct SingleContext : public CCtx<Quant> { + SingleContext(Ptr<Quant> id) : CCtx<Quant>(id) {} + }; + + /// ContinuousContext: resembles the global <- neuron <- synapse hierarchy + template<typename Quant> + struct ContinuousContext; + + template<> + struct ContinuousContext<Global> : CCtx<Global> { + ContinuousContext() + : CCtx<Global>(Ptr<Global>()) {} + explicit ContinuousContext(Ptr<Global> p) + : CCtx<Global>(p) {} + }; + + template<> + struct ContinuousContext<Neuron> : CCtx<Neuron, Global> { + explicit ContinuousContext(Ptr<Neuron> p) + : CCtx<Neuron, Global>(p, Ptr<Global>()) {} + }; + + template<> + struct ContinuousContext<Synapse> + : CCtx<Synapse, Neuron, Global> { + explicit ContinuousContext(Ptr<Synapse> p) + : CCtx<Synapse, Neuron, Global>(p, p.extractNeuron(), Ptr<Global>()) {} + }; + + // common context with one discrete ptr (internal) + template<typename DQ, typename CQ> + struct DCtx { + DCtx(Ptr<DQ> did, Ptr<CQ> cid) + : id(did), sub(cid) {} + + template<typename Quant> + typename Quant::instance_ptr_t getptr() { + if (boost::is_same<Quant, DQ>::value) { + return FORCE_CONV(typename Quant::instance_ptr_t, id); + }else{ + return sub.getptr<Quant>(); + } + } + + friend std::ostream& operator<< (std::ostream &os, DCtx val) { + return os << val.id << ":" << val.sub; + } + + Ptr<DQ> id; + ContinuousContext<CQ> sub; + }; + + + /// DelieverContext: when a (discrete) event is delievered to a + /// continuous quantity + template<typename DQ, typename CQ> + struct DelieverContext : DCtx<DQ, CQ> { + DelieverContext(Ptr<DQ> did, Ptr<CQ> cid) + : DCtx<DQ, CQ>(did, cid) {} + }; + + // HACK: allow Neuron to access Synapse on SpikeArrival; this only + // works because SA is send with a zero delay, so synapse is already + // evolved to current time + template<> + struct DelieverContext<SpikeArrival, Neuron> : DCtx<SpikeArrival, Synapse> { + DelieverContext(boost::tuple<Ptr<SpikeArrival>, Ptr<Synapse>> t, Ptr<Neuron>) + : DCtx<SpikeArrival, Synapse>(t.get<0>(), t.get<1>()) {} + }; + + /// EmitContent: CQ emits event of class DQ + template<typename CQ, typename DQ> + struct EmitContext : DCtx<DQ, CQ> { + EmitContext(Ptr<CQ> cid, Ptr<DQ> did) + : DCtx<DQ, CQ>(did, cid) {} + }; +} + +using ContextImpl::SingleContext; +using ContextImpl::ContinuousContext; +using ContextImpl::DelieverContext; +using ContextImpl::EmitContext; + +#endif // sOuC39DJVwHiStoyuZdritpuC5M |