summaryrefslogtreecommitdiff
path: root/core/context.hpp
blob: dd4ed7e5ea49ad0ce57dc5b7ec2ab70e00a79404 (plain)
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
contact: Jan Huwald // Impressum