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
|
#ifndef Vaz5kkzRinGGCeloVow8grqZI1c
#define Vaz5kkzRinGGCeloVow8grqZI1c
// HINT: simple schema, based on the fact the this PLA changes only
// props it does not depend on (read from)
#include <assert.h>
#include <boost/type_traits/is_same.hpp>
#include <boost/tuple/tuple.hpp>
#include "context.hpp"
#include "template_helpers.hpp"
#include "time.hpp"
namespace PLA_Generate_Impl {
using namespace boost;
using namespace boost::mpl;
// local state
// general case: no action (and zero storage)
template<typename Prop, typename CQ, typename DQ, bool quantMatch /* == false */>
struct LocalState {
template<typename PropComp, typename Context, typename MI, typename MQ>
inline void process(PropComp &, Context, Time, MI &, MQ &) {}
template <typename PropComp, typename Context>
inline void commit(PropComp &, Context, Time) {}
};
// matching case: get/set the value to local storage
template<typename Prop, typename CQ, typename DQ>
struct LocalState<Prop, CQ, DQ, true /* == quantMatch */> {
typename Prop::type val;
template<typename PropComp, typename Context, typename MI, typename MQ>
inline void process(PropComp &pc, Context context, Time time,
MI &indices, MQ &queues) {
// calc new val and store locally
// TODO: check generation of discrete properties
ContinuousProperty_Generate<Prop, CQ, DQ>::
eval(pc, context, time, val, indices, queues);
}
template <typename PropComp, typename Context>
inline void commit(PropComp &pc, Context context, Time time) {
// HINT: caller has to check if we should commit
typedef typename Prop::quant Quant;
Ptr<Quant> dst(context.template getptr<Quant>());
PLA_Set<Prop> pla_set(time, dst, val); // TODO: omit time if Prop is discrete
pc.call(pla_set);
}
};
// generate action
template<typename CQ, typename DQ, typename MI, typename MQ>
struct PLA_Generate {
// action types & consts
typedef Void result_t;
template<typename ContextProp, bool doWriteResults>
struct local_state_t : LocalState<ContextProp, CQ, DQ,
or_<is_same<CQ, typename ContextProp::quant>,
is_same<DQ, typename ContextProp::quant>
>::value>
{
typedef ContextProp prop;
static const bool write = doWriteResults;
};
typedef EmitContext<CQ, DQ> context_t;
// action state & constructor
context_t context;
Time time;
result_t result;
MI &indices;
MQ &queues;
PLA_Generate(Time time, context_t context, MI &indices, MQ &queues)
: context(context), time(time), indices(indices), queues(queues) {}
// action methods
template<typename PropComp, typename LocalData, typename LocalState>
inline void pre(PropComp &pc, LocalData &, LocalState &state) {
// if we have the correct quantity (and ought to write to it)
typedef typename LocalState::prop Prop;
typedef typename Prop::quant Quant;
if ( (is_same<CQ, Quant>::value and ContinuousProperty_Generate
<Prop, CQ, DQ>::changesValue)
or (is_same<DQ, typename LocalState::prop::quant>::value and state.write))
state.process(pc, context, time, indices, queues);
}
template<typename PropComp, typename _LocalData, typename LocalState>
inline void post(PropComp &pc, _LocalData &data, LocalState &state) {
typedef typename LocalState::prop Prop;
typedef typename Prop::quant Quant;
if ( (is_same<CQ, Quant>::value and ContinuousProperty_Generate
<Prop, CQ, DQ>::changesValue)
or (is_same<DQ, typename LocalState::prop::quant>::value and state.write))
state.commit(pc, context, time); // ... store new value and time
}
private:
PLA_Generate();
};
}
using PLA_Generate_Impl::PLA_Generate;
#endif // Vaz5kkzRinGGCeloVow8grqZI1c
|