TTTT Analysis  0.1
value.hpp
Go to the documentation of this file.
1 
42 #ifndef value_hpp
43 #define value_hpp
44 #include <iomanip>
45 #include <iostream>
46 #include <sstream>
47 #include <utility>
48 #include <algorithm>
49 #include <map>
50 #include <vector>
51 #include <tuple>
52 #include <initializer_list>
53 #include <functional>
54 
55 #include "log.hpp"
56 
60 namespace fv{
61 
62 /* bool in_register_function = false; */
63 template<typename> class Function; // undefined
68 class GenFunction {
69  private:
70  std::string name;
71  std::string impl;
72  protected:
73  inline static bool in_register_function=false;
74 
75  public:
80  inline static std::map<const std::string, GenFunction*> function_registry;
81 
82  GenFunction(const std::string& name, const std::string& impl)
83  :impl(impl),
84  name(name){
85  }
86  virtual ~GenFunction() { };
87 
88  std::string& get_name(){
89  return name;
90  }
91 
97  static std::string format_code(const std::string& code){
98  std::stringstream code_out("");
99  std::string command("echo \""+code+"\" | clang-format");
100  char buffer[255];
101  FILE *stream = popen(command.c_str(), "r");
102  while (fgets(buffer, 255, stream) != NULL)
103  code_out << buffer;
104  if (pclose(stream) == 0)
105  return code_out.str();
106  else
107  return code;
108  }
109 
110  static std::string summary(){
111  std::stringstream ss;
112  ss << "The following functions have been registered" << std::endl;
113  for(auto p : function_registry){
114  if (p.second == nullptr) continue;
115  ss << "-->" << p.second->name << std::endl;
116  ss << format_code(p.second->impl);
117  }
118  return ss.str();
119  }
120 
121  template <typename T>
122  static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
123  in_register_function = true;
124  Function<T>* func;
125  if (GenFunction::function_registry[name] != nullptr){
126  func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
127  if (func == nullptr){
128  ERROR("Trying to register function which has already been registered with a different type");
129  }
130  } else {
131  func = new Function<T>(name, impl, f);
132  GenFunction::function_registry[name] = func;
133  }
134  in_register_function = false;
135  return *func;
136  }
137 };
138 
139 
151 template <typename R, typename... ArgTypes>
152 class Function<R(ArgTypes...)> : public GenFunction {
153  private:
154  std::function<R(ArgTypes...)> f;
155 
156  public:
157  Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
158  :GenFunction(name, impl), f(f){
159  if (!in_register_function) {
160  WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
161  }
162  }
163  Function(const std::string& name, std::function<R(ArgTypes...)> f)
164  :Function(name, "N/A", f){ }
165  ~Function() { }
166 
167  R operator()(ArgTypes ...args){
168  return f(args...);
169  }
170 
171 };
172 
173 
174 #define FUNC(f) f, #f
175 
182 class GenValue;
183 typedef std::map<std::string, GenValue*> ValueSet;
184 class GenValue{
185  private:
191  std::string name;
192  protected:
199  virtual void _reset() = 0;
207  inline static std::map<const std::string, GenValue*> values;
215  inline static std::map<const std::string, GenValue*> aliases;
216  public:
217  GenValue(const std::string& name, const std::string& alias)
218  :name(name){
219  values[name] = this;
220  if (alias != "")
221  GenValue::alias(alias, this);
222  }
223 
224  const std::string& get_name(){
225  return name;
226  }
227 
228  static void reset(){
229  for (auto val : values){
230  val.second->_reset();
231  }
232  }
233 
234  static GenValue* get_value(const std::string& name){
235  if (aliases[name] != nullptr)
236  return aliases[name];
237  else if (values[name] != nullptr)
238  return values[name];
239  else{
240  ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
241  << summary());
242  CRITICAL("Aborting... :(", -1);
243  }
244  }
245 
246  static void alias(const std::string& name, GenValue* value){
247  if (aliases[name] != nullptr){
248  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
249  }
250  aliases[name] = value;
251  }
252 
253  static GenValue* alias(const std::string& name){
254  if (values[name] != nullptr){
255  WARNING("Alias \"" << name << "\" does not exist.");
256  }
257  return aliases[name];
258  }
259 
260  static std::string summary(){
261  std::stringstream ss;
262  ss << "The following values have been created: " << std::endl;
263  for (auto value : values){
264  if (value.second == nullptr) continue;
265  ss << "\t\"" << value.first << "\" at address " << value.second << std::endl;
266  }
267  ss << "And these aliases:" << std::endl;
268  for (auto alias : aliases){
269  std::string orig("VOID");
270  if (alias.second == nullptr) continue;
271  for (auto value : values){
272  if (alias.second == value.second){
273  orig = value.second->get_name();
274  break;
275  }
276  }
277  ss << "\t\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
278  }
279  return ss.str();
280  }
281  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
282 };
283 std::ostream& operator<<(std::ostream& os, GenValue& gv){
284  os << gv.get_name();
285  return os;
286 }
287 
288 
298 template <typename T>
299 class Value : public GenValue{
300  public:
301  Value(const std::string& name, const std::string& alias="")
302  :GenValue(name, alias){ }
305  virtual T& get_value() = 0;
306 };
307 
308 
318 template <typename T>
319 class ObservedValue : public Value<T>{
320  private:
321  T *val_ref;
322  void _reset(){ }
323  public:
324  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
325  :Value<T>(name, alias),
326  val_ref(val_ref){ }
327  T& get_value(){
328  return *val_ref;
329  }
330 };
331 
332 
348 template <typename T>
349 class DerivedValue : public Value<T>{
350  private:
351  void _reset(){
352  value_valid = false;
353  }
354  protected:
355  T value;
356  bool value_valid;
357 
366  virtual void update_value() = 0;
367  public:
368  DerivedValue(const std::string& name, const std::string& alias="")
369  :Value<T>(name, alias),
370  value_valid(false) { }
371 
372  T& get_value(){
373  if (!value_valid){
374  update_value();
375  value_valid = true;
376  }
377  return value;
378  }
379 };
380 
381 
391 template <typename T>
392 class WrapperVector : public DerivedValue<std::vector<T> >{
393  private:
394  Value<int>* size;
395  Value<T*>* data;
396 
397  void update_value(){
398  int n = size->get_value();
399  T* data_ref = data->get_value();
400  this->value.assign(data_ref, data_ref+n);
401  }
402 
403  public:
404  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
405  :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
406  size(size), data(data){ }
407 
408  WrapperVector(const std::string &label_size, const std::string &label_data, const std::string& alias="")
409  :WrapperVector(dynamic_cast<Value<int>*>(GenValue::get_value(label_size)),
410  dynamic_cast<Value<T*>*>(GenValue::get_value(label_data)), alias) { }
411 };
412 
416 template <typename T1, typename T2>
417 class Pair : public DerivedValue<std::pair<T1, T2> >{
418  protected:
419  std::pair<Value<T1>*, Value<T2>* > value_pair;
420  void update_value(){
421  this->value.first = value_pair.first->get_value();
422  this->value.second = value_pair.second->get_value();
423  }
424  public:
425  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
426  :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
427  value_pair(value1, value2){ }
428  Pair(const std::string& label1, const std::string& label2, const std::string alias="")
429  :Pair(dynamic_cast<Value<T1>*>(GenValue::get_value(label1)),
430  dynamic_cast<Value<T1>*>(GenValue::get_value(label2)),
431  alias){ }
432 };
433 
447 template <typename R, typename T>
448 class ZipMapFour : public DerivedValue<std::vector<R> >{
449  private:
451  Value<std::vector<T> >* v1;
452  Value<std::vector<T> >* v2;
453  Value<std::vector<T> >* v3;
454  Value<std::vector<T> >* v4;
455 
456  void update_value(){
457  std::vector<T> v1_val = v1->get_value();
458  std::vector<T> v2_val = v2->get_value();
459  std::vector<T> v3_val = v3->get_value();
460  std::vector<T> v4_val = v4->get_value();
461 
462  int n;
463  std::tie(n, std::ignore) = std::minmax({v1_val.size(), v2_val.size(), v3_val.size(), v4_val.size()});
464  this->value.resize(n);
465  for (int i=0; i<n; i++){
466  this->value[i] = f(v1_val[i], v2_val[i], v3_val[i], v4_val[i]);
467  }
468  }
469 
470  public:
471  ZipMapFour(Function<R(T, T, T, T)>& f,
472  Value<std::vector<T> >* v1, Value<std::vector<T> >* v2,
473  Value<std::vector<T> >* v3, Value<std::vector<T> >* v4, const std::string alias="")
474  :DerivedValue<std::vector<R> >("zipmap("+f.get_name()+":"+v1->get_name()+","+v2->get_name()+","+
475  v3->get_name()+","+v4->get_name()+")", alias),
476  f(f), v1(v1), v2(v2), v3(v3), v4(v4) { }
477 
478  ZipMapFour(Function<R(T, T, T, T)>& f,
479  const std::string& label1, const std::string& label2,
480  const std::string& label3, const std::string& label4, const std::string alias="")
481  :ZipMapFour(f,
482  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label1)),
483  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label2)),
484  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label3)),
485  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label4)),
486  alias){ }
487 };
488 
492 template<typename T>
493 class Count : public DerivedValue<int>{
494  private:
495  Function<bool(T)>& selector;
497  void update_value(){
498  value = 0;
499  for(auto val : v->get_value()){
500  if(selector(val))
501  value++;
502  }
503  }
504  public:
505  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias="")
506  :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
507  selector(selector), v(v) { }
508 
509  Count(Function<bool(T)>& selector, const std::string& v_name, const std::string alias="")
510  :Count(selector, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name)), alias) { }
511 };
512 
513 
520 template <typename T>
521 class Reduce : public DerivedValue<T>{
522  private:
523  Function<T(std::vector<T>)>& reduce;
525  void update_value(){
526  this->value = reduce(v->get_value());
527  }
528  public:
529  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
530  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
531  reduce(reduce), v(v) { }
532 
533  Reduce(Function<T(std::vector<T>)>& reduce, const std::string& v_name, const std::string alias="")
534  :Reduce(reduce, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name)), alias) { }
535 };
536 
540 template <typename T>
541 class Max : public Reduce<T>{
542  public:
543  Max(const std::string& v_name, const std::string alias="")
544  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
545  FUNC(([](std::vector<T> vec){
546  return *std::max_element(vec.begin(), vec.end());}))),
547  v_name, alias) { }
548 };
549 
553 template <typename T>
554 class Min : public Reduce<T>{
555  public:
556  Min(const std::string& v_name, const std::string alias="")
557  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
558  FUNC(([](std::vector<T> vec){
559  return *std::min_element(vec.begin(), vec.end());}))),
560  v_name, alias) { }
561 };
562 
566 template <typename T>
567 class Mean : public Reduce<T>{
568  public:
569  Mean(const std::string& v_name, const std::string alias="")
570  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
571  FUNC(([](std::vector<T> vec){
572  int n = 0; T sum = 0;
573  for (T e : vec){ n++; sum += e; }
574  return n>0 ? sum / n : 0; }))),
575  v_name, alias) { }
576 };
577 
581 template <typename T>
582 class Range : public Reduce<T>{
583  public:
584  Range(const std::string& v_name, const std::string alias="")
585  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
586  FUNC(([](std::vector<T> vec){
587  auto minmax = std::minmax_element(vec.begin(), vec.end());
588  return (*minmax.second) - (*minmax.first); }))),
589  v_name, alias) { }
590 };
591 
595 template <typename T>
596 class ElementOf : public Reduce<T>{
597  public:
598  ElementOf(Value<int>* index, const std::string& v_name, const std::string alias="")
599  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
600  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
601  v_name, alias) { }
602  ElementOf(const std::string& name, int index, const std::string& v_name, const std::string alias="")
603  :Reduce<T>(name, [index](std::vector<T> vec){return vec[index];}, v_name, alias) { }
604 };
605 
611 template <typename T>
612 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
613  private:
614  Function<std::pair<T,int>(std::vector<T>)>& reduce;
616  void update_value(){
617  this->value = reduce(v->get_value());
618  }
619  public:
620  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
621  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
622  reduce(reduce), v(v) { }
623 
624  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, const std::string& v_name, const std::string alias="")
625  :ReduceIndex(reduce, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name)), alias) { }
626 };
627 
631 template <typename T>
632 class MaxIndex : public ReduceIndex<T>{
633  public:
634  MaxIndex(const std::string& v_name, const std::string alias="")
635  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
636  FUNC(([](std::vector<T> vec){
637  auto elptr = std::max_element(vec.begin(), vec.end());
638  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }
639  ))), v_name, alias) { }
640 };
641 
645 template <typename T>
646 class MinIndex : public ReduceIndex<T>{
647  public:
648  MinIndex(const std::string& v_name, const std::string alias="")
649  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
650  FUNC(([](std::vector<T> vec){
651  auto elptr = std::min_element(vec.begin(), vec.end());
652  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }
653  ))), v_name, alias) { }
654 };
655 
661 template <typename T>
662 class BoundValue : public DerivedValue<T>{
663  protected:
664  Function<T()>& f;
665  void update_value(){
666  this->value = f();
667  }
668  public:
669  BoundValue(Function<T()>& f, const std::string alias="")
670  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
671  f(f) { }
672 };
673 
678 template <typename T>
679 class PointerValue : public DerivedValue<T*>{
680  protected:
681  void update_value(){ }
682  public:
683  PointerValue(const std::string& name, T* ptr, const std::string alias="")
684  :DerivedValue<T*>(name, alias){
685  this->value = ptr;
686  }
687 };
688 
692 template <typename T>
693 class ConstantValue : public DerivedValue<T>{
694  protected:
695  T const_value;
696  void update_value(){
697  this->value = const_value;
698  }
699  public:
700  ConstantValue(const std::string& name, T const_value, const std::string alias="")
701  :DerivedValue<T>("const::"+name, alias),
702  const_value(const_value) { }
703 };
704 }
705 #endif // value_hpp
Definition: value.hpp:184
void update_value()
Updates the internal value.
Definition: value.hpp:665
Find and return the maximum value of a vector.
Definition: value.hpp:541
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:521
void update_value()
Updates the internal value.
Definition: value.hpp:497
void update_value()
Updates the internal value.
Definition: value.hpp:420
Find and return the minimum value of a vector and its index.
Definition: value.hpp:646
void _reset()
Mark the internal value as invalid.
Definition: value.hpp:351
A generic value owning only a function object.
Definition: value.hpp:662
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:372
Calculate the range of the values in a vector.
Definition: value.hpp:582
A std::vector wrapper around a C-style array.
Definition: value.hpp:392
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:612
std::string name
The name of the value.
Definition: value.hpp:191
void update_value()
Updates the internal value.
Definition: value.hpp:456
Definition: value.hpp:493
Find and return the maximum value of a vector and its index.
Definition: value.hpp:632
void update_value()
Updates the internal value.
Definition: value.hpp:525
Parent class to all Function classes.
Definition: value.hpp:68
void _reset()
Mark the internal value as invalid.
Definition: value.hpp:322
Takes a set of four Value<std::vector<T> > objects and a function of four Ts and returns a std::vecto...
Definition: value.hpp:448
static std::map< const std::string, GenValue * > aliases
Composite value names are typically nested.
Definition: value.hpp:215
A generic, observed, value.
Definition: value.hpp:319
Find and return the minimum value of a vector.
Definition: value.hpp:554
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:417
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:327
void update_value()
Updates the internal value.
Definition: value.hpp:616
void update_value()
Updates the internal value.
Definition: value.hpp:696
The namespace containing all filval classes and functions.
Extract the element at a specific index from a vector.
Definition: value.hpp:596
Calculate the mean value of a vector.
Definition: value.hpp:567
void update_value()
Updates the internal value.
Definition: value.hpp:397
A generic value.
Definition: value.hpp:299
static std::map< const std::string, GenValue * > values
A static mapping containing all created Value objects.
Definition: value.hpp:207
static std::string format_code(const std::string &code)
Attempt to invoke clang-format for the purpose of printing out nicely formatted functions to the log ...
Definition: value.hpp:97
A generic, derived, value.
Definition: value.hpp:349
void update_value()
Updates the internal value.
Definition: value.hpp:681
Definition: value.hpp:63
virtual T & get_value()=0
Calculate, if necessary, and return the value held by this object.
A Value which always returns the same value, supplied in the constructor.
Definition: value.hpp:693
static std::map< const std::string, GenFunction * > function_registry
Static mapping of functions from their name to the object wrapper of the function.
Definition: value.hpp:80
A Value of a pointer.
Definition: value.hpp:679