1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
|