Empirical
TypeTracker.h
Go to the documentation of this file.
1 
14 #ifndef EMP_TYPE_TRACKER_H
15 #define EMP_TYPE_TRACKER_H
16 
17 #include <unordered_map>
18 
19 #include "../base/array.h"
20 #include "../base/assert.h"
21 #include "../meta/meta.h"
22 
23 #include "functions.h"
24 #include "GenericFunction.h"
25 #include "map_utils.h"
26 
27 namespace emp {
28 
30  struct TrackedType {
31  virtual size_t GetTypeTrackerID() const noexcept = 0;
32  virtual ~TrackedType() {;}
33  };
34 
38  template <typename REAL_T, size_t ID>
39  struct TypeTracker_Class : public TrackedType {
40  using real_t = REAL_T;
41  REAL_T value;
42 
43  TypeTracker_Class(const REAL_T & in) : value(in) { ; }
44  TypeTracker_Class(REAL_T && in) : value(std::forward<REAL_T>(in)) { ; }
45  TypeTracker_Class(const TypeTracker_Class &) = default;
47  TypeTracker_Class & operator=(const TypeTracker_Class &) = default;
48  TypeTracker_Class & operator=(TypeTracker_Class &&) = default;
49  virtual size_t GetTypeTrackerID() const noexcept { return ID; }
50  };
51 
54  template <typename... TYPES>
55  struct TypeTracker {
56  using this_t = TypeTracker<TYPES...>;
57  template <typename REAL_T>
58  using wrap_t = TypeTracker_Class< REAL_T, get_type_index<REAL_T,TYPES...>() >;
59 
61  constexpr static size_t GetNumTypes() { return sizeof...(TYPES); }
62 
64  constexpr static size_t GetNumCombos(size_t vals=2) {
65  size_t result = 1;
66  for (size_t v = 0; v < vals; v++) result *= GetNumTypes();
67  return result;
68  }
69 
71  constexpr static size_t GetCumCombos(size_t vals=2) {
72  size_t cur_result = 1;
73  size_t cum_result = 1;
74  for (size_t v = 0; v < vals; v++) {
75  cur_result *= GetNumTypes();
76  cum_result += cur_result;
77  }
78  return cum_result;
79  }
80 
82  template <typename T>
83  constexpr static size_t GetID() { return get_type_index<T,TYPES...>(); }
84 
86  template <typename T1, typename T2, typename... Ts>
87  constexpr static size_t GetID() { return GetID<T1>() + GetID<T2,Ts...>() * GetNumTypes(); }
88 
90  template <typename... Ts>
91  constexpr static size_t GetComboID() {
92  return GetCumCombos(sizeof...(Ts)-1) + GetID<Ts...>();
93  }
94 
96  static size_t GetTrackedID(const TrackedType & tt) { return tt.GetTypeTrackerID(); }
97  template <typename... Ts>
98 
100  static size_t GetTrackedID(const TrackedType & tt1, const TrackedType & tt2, const Ts &... ARGS) {
101  return tt1.GetTypeTrackerID() + GetTrackedID(tt2, ARGS...) * GetNumTypes();
102  }
103 
105  static size_t GetTrackedID(TrackedType * tt) { return tt->GetTypeTrackerID(); }
106 
108  template <typename... Ts>
109  static size_t GetTrackedID(TrackedType * tt1, TrackedType * tt2, Ts *... ARGS) {
110  return tt1->GetTypeTrackerID() + GetTrackedID(tt2, ARGS...) * GetNumTypes();
111  }
112 
115  template <typename... Ts>
116  constexpr static size_t GetTrackedComboID(Ts... ARGS) {
117  return GetCumCombos(sizeof...(Ts)-1) + GetTrackedID(ARGS...);
118  }
119 
121  std::unordered_map<size_t, emp::GenericFunction *> fun_map;
122 
123  // Constructors!
124  TypeTracker() : fun_map() { ; }
125  TypeTracker(const TypeTracker &) = default;
126  TypeTracker(TypeTracker &&) = default;
127  TypeTracker & operator=(const TypeTracker &) = default;
128  TypeTracker & operator=(TypeTracker &&) = default;
129 
130  // Destructor!
132  for (auto x : fun_map) delete x.second; // Clear out Functions.
133  }
134 
136  template <typename REAL_T> wrap_t<REAL_T> Wrap(REAL_T && val) {
137  emp_assert((has_type<REAL_T,TYPES...>())); // Make sure we're wrapping a legal type.
138  return wrap_t<REAL_T>(std::forward<REAL_T>(val));
139  }
140 
142  template <typename REAL_T> wrap_t<REAL_T> * New(REAL_T & val) {
143  emp_assert((has_type<REAL_T, TYPES...>())); // Make sure we're wrapping a legal type.
144  return new wrap_t<REAL_T>(val);
145  }
146 
148  template <typename REAL_T> wrap_t<REAL_T> * New(REAL_T && val) {
149  emp_assert((has_type<REAL_T, TYPES...>())); // Make sure we're wrapping a legal type.
150  return new wrap_t<REAL_T>(std::forward<REAL_T>(val));
151  }
152 
154  template <typename TEST_T>
155  bool IsType( TrackedType & tt ) {
156  return tt.GetTypeTrackerID() == get_type_index<TEST_T,TYPES...>();
157  }
158 
160  template <typename TEST_T>
161  bool IsType( TrackedType * tt ) { return IsType(*tt); }
162 
164  template <typename REAL_T>
165  REAL_T ToType( TrackedType & tt ) {
166  emp_assert(IsType<REAL_T>(tt));
167  return ((wrap_t<REAL_T> *) &tt)->value;
168  }
169 
171  template <typename REAL_T>
172  REAL_T ToType( TrackedType * tt ) { return ToType(*tt); }
173 
175  template <typename OUT_T>
176  OUT_T Cast( TrackedType & tt ) { return ((wrap_t<OUT_T> *) &tt)->value; }
177 
179  template <typename OUT_T>
180  OUT_T Cast( TrackedType * tt ) { return Cast(*tt); }
181 
184  template <typename... Ts>
185  this_t & AddFunction( std::function<void(Ts...)> fun ) {
186  constexpr size_t ID = GetComboID<Ts...>();
187 
188  // We need to ensure there are the same number of TrackedType parameters in the wrapped
189  // function as there were typed parameters in the original. To accomplish this task, we
190  // will expand the original type pack, but use decoys to convert to TrackedType.
191 
192  auto fun_wrap = [fun](emp::type_decoy<TrackedType *,Ts>... args) {
193  // Ensure all types can be cast appropriately
194  emp_assert( AllTrue( dynamic_cast<wrap_t<Ts> *>(args)... ) );
195 
196  // Now run the function with the correct type conversions
197  fun( ((wrap_t<Ts> *) args)->value... );
198  };
199 
200  fun_map[ID] = new Function<void(emp::type_decoy<TrackedType *,Ts>...)>(fun_wrap);
201 
202  return *this;
203  }
204 
207  template <typename... Ts>
208  this_t & AddFunction( void (*fun)(Ts...) ) {
209  return AddFunction( std::function<void(Ts...)>(fun) );
210  }
211 
213  template <typename... Ts>
214  void RunFunction( Ts... args ) { // args must all be TrackedType pointers!
215  const size_t pos = GetTrackedComboID(args...);
216  if (Has(fun_map, pos)) { // If a redirect exists, use it!
217  GenericFunction * gfun = fun_map[pos];
219  }
220  }
221 
223  template <typename... Ts>
224  void operator()(Ts... args) { RunFunction(args...); }
225  };
226 
227 }
228 
229 #endif
~TypeTracker()
Definition: TypeTracker.h:131
A set of simple functions to manipulate maps.
void operator()(Ts...args)
Call TypeTracker as a function (refers call to RunFunction)
Definition: TypeTracker.h:224
static size_t GetTrackedID(const TrackedType &tt)
A Tracked ID is simply the unique ID of the type being tracked.
Definition: TypeTracker.h:96
The base class of any type to be tracked.
Definition: TypeTracker.h:30
virtual size_t GetTypeTrackerID() const noexcept
Definition: TypeTracker.h:49
static constexpr size_t GetID()
Each set of types should have an ID unique within that number of types.
Definition: TypeTracker.h:87
static constexpr size_t GetID()
Each type should have a unique ID.
Definition: TypeTracker.h:83
TypeTracker_Class(REAL_T &&in)
Definition: TypeTracker.h:44
REAL_T real_t
Definition: TypeTracker.h:40
REAL_TYPE type_decoy
Definition: meta.h:94
this_t & AddFunction(std::function< void(Ts...)> fun)
Definition: TypeTracker.h:185
static size_t GetTrackedID(TrackedType *tt1, TrackedType *tt2, Ts *...ARGS)
A set of pointers to access tracked IDs.
Definition: TypeTracker.h:109
Definition: BitVector.h:785
auto Call(Ts &&...args)
A generic form of the function call operator; use arg types to determine derived form.
Definition: GenericFunction.h:69
REAL_T value
Definition: TypeTracker.h:41
bool IsType(TrackedType *tt)
Test if the tracked type points to TEST_T.
Definition: TypeTracker.h:161
bool IsType(TrackedType &tt)
Test if the tracked type is TEST_T.
Definition: TypeTracker.h:155
ID
Definition: struct.h:26
virtual ~TrackedType()
Definition: TypeTracker.h:32
Definition: TypeTracker.h:39
TypeTracker_Class(const REAL_T &in)
Definition: TypeTracker.h:43
Definition: GenericFunction.h:29
static size_t GetTrackedID(TrackedType *tt)
We should also about able to use a pointer to access tracked IDs.
Definition: TypeTracker.h:105
OUT_T Cast(TrackedType &tt)
Cast the tracked type to OUT_T. Try to do so even if NOT original type!
Definition: TypeTracker.h:176
std::unordered_map< size_t, emp::GenericFunction * > fun_map
fun_map is a hash table that maps a set of inputs to the appropriate function.
Definition: TypeTracker.h:121
OUT_T Cast(TrackedType *tt)
Cast the tracked type pointer to OUT_T. Try to do so even if NOT original type!
Definition: TypeTracker.h:180
static constexpr size_t GetCumCombos(size_t vals=2)
How many combinations are the of the given number of types OR FEWER?
Definition: TypeTracker.h:71
static constexpr size_t GetComboID()
A ComboID should be unique across all size combinations.
Definition: TypeTracker.h:91
wrap_t< REAL_T > * New(REAL_T &&val)
Create an input value in a TypeTracker_Class maintaining the value (move version) ...
Definition: TypeTracker.h:148
bool Has(const MAP_T &in_map, const KEY_T &key)
Take any map type, and run find to determine if a key is present.
Definition: map_utils.h:21
wrap_t< REAL_T > * New(REAL_T &val)
Create an input value in a TypeTracker_Class maintaining the value (reference version) ...
Definition: TypeTracker.h:142
Based on std::function, but with a common base class.
TypeTracker()
Definition: TypeTracker.h:124
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Definition: GenericFunction.h:47
virtual size_t GetTypeTrackerID() const noexcept=0
#define emp_assert(...)
Definition: assert.h:199
wrap_t< REAL_T > Wrap(REAL_T &&val)
Convert an input value into a TypeTracker_Class maintaining the value (universal version) ...
Definition: TypeTracker.h:136
constexpr int get_type_index()
Definition: meta.h:70
REAL_T ToType(TrackedType &tt)
Convert the tracked type back to REAL_T. Assert that this is type safe!
Definition: TypeTracker.h:165
static size_t GetTrackedID(const TrackedType &tt1, const TrackedType &tt2, const Ts &...ARGS)
Or set of types being tracked...
Definition: TypeTracker.h:100
static constexpr bool cur_result
Definition: TypePack.h:110
Definition: TypeTracker.h:55
this_t & AddFunction(void(*fun)(Ts...))
Definition: TypeTracker.h:208
static constexpr size_t GetTrackedComboID(Ts...ARGS)
Definition: TypeTracker.h:116
void RunFunction(Ts...args)
Run the appropriate function based on the argument types received.
Definition: TypeTracker.h:214
static constexpr size_t GetNumCombos(size_t vals=2)
How many combinations of V types are there?
Definition: TypeTracker.h:64
REAL_T ToType(TrackedType *tt)
Convert the tracked type pointer back to REAL_T. Assert that this is type safe!
Definition: TypeTracker.h:172
static constexpr size_t GetNumTypes()
How many types are we working with?
Definition: TypeTracker.h:61
constexpr bool AllTrue()
Combine bools to AND them all together.
Definition: functions.h:52