summaryrefslogtreecommitdiff
path: root/core/pla_get.hpp
blob: ba7d2a068cb9a7d598e7477c80561fee9a4a2c4c (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
#ifndef j9bZiR9W7dKz17gTUOtW1xODHdA
#define j9bZiR9W7dKz17gTUOtW1xODHdA

#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>

#include "context.hpp"
#include "continuous_property.hpp"
#include "property_instance.hpp"
#include "property_list.hpp"
#include "quant_types.hpp"
#include "template_helpers.hpp"

// worker template forward decl 
template<typename Prop, typename CurrentProp, typename Data, typename QuantClass>
struct PLA_Get_Impl;

// PLA template
template<typename Prop, typename Context = SingleContext<typename Prop::quant>>
struct PLA_Get {
  // action consts
  typedef typename Prop::type result_t;
  template<typename ContextProp, bool _doWriteResult> struct local_state_t {
    typedef ContextProp prop;
  };

  // action parameters
  typedef typename Prop::instance_ptr_t instance_t;
  typedef typename boost::mpl::if_<boost::is_same<ContinuousPropertyClass, typename Prop::quant::class_t>,
				   Time,
				   Void>::type time_t;
  Context ctx;
  time_t time;
  result_t result;

  PLA_Get(time_t time, Context ctx) : ctx(ctx), time(time) {}
  PLA_Get(Context ctx) : ctx(ctx) {
    BOOST_STATIC_ASSERT((boost::is_same<time_t, Void>::value)); 
  }

  // action methods
  template<typename _PropComp, typename _ContextData, typename _LocalState>
  inline void pre(_PropComp &pc, _ContextData &data, _LocalState &state) { }


  template<typename PC, typename ContextData, typename LocalState>
  inline void post(PC &pc, ContextData &data, LocalState &state) {
    BOOST_MPL_ASSERT(( PL_Contains<PL<typename PC::properties_t>, Prop> ));
    PLA_Get_Impl<Prop, typename LocalState::prop, ContextData, typename LocalState::prop::quant::class_t>
      ::eval(pc, data, ctx, time, result);
  }
};

// worker template implementation
//  * do nothing at the wrong type
template<typename Prop, typename WrongProp, typename Data, typename QuantClass>
struct PLA_Get_Impl {
  template<typename PC, typename Context = SingleContext<typename Prop::quant>>
  static inline void eval(PC &, Data &, Context,
			  typename PLA_Get<Prop>::time_t, typename Prop::type &) { }
};

//  * store pointer to the data structure at the correct type
template<typename Prop, typename Data>
struct PLA_Get_Impl<Prop, Prop, Data, ContinuousPropertyClass> {
  template<typename PC, typename Context = SingleContext<typename Prop::quant>>
  static inline void eval(PC &pc, Data &data, Context ctx,
			  typename PLA_Get<Prop>::time_t time, 
			  typename Prop::type &fold_state) {
    Time oldTime = data.data.getTime(time, ctx.template getptr<typename Prop::quant>()());
    assert(oldTime <= time); // we can not jump backward
    if (oldTime < time) {
      Time dt = time - oldTime;
      fold_state = ContinuousProperty_Evolve<PC, Prop, typename Prop::quant, Context>
	::eval(pc, ctx, oldTime, dt);
    }else{
      fold_state = data.data.getValue(time, ctx.template getptr<typename Prop::quant>()());
    }
  }
};

template<typename Prop, typename Data>
struct PLA_Get_Impl<Prop, Prop, Data, DiscretePropertyClass> {
  template<typename PC, typename Context = SingleContext<typename Prop::quant>>
  static inline void eval(PC &, Data &data, Context ctx,
			  typename PLA_Get<Prop>::time_t,
			  typename Prop::type &fold_state) {
    fold_state = data.data(ctx.template getptr<typename Prop::quant>()());
  }
};

#endif // j9bZiR9W7dKz17gTUOtW1xODHdA
contact: Jan Huwald // Impressum