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 <limits>
51 #include <vector>
52 #include <tuple>
53 #include <initializer_list>
54 #include <functional>
55 
56 #include "log.hpp"
57 
61 namespace fv{
62 
63 template <typename F, typename Tuple, bool Done, int Total, int... N>
64 struct call_impl
65 {
66  static auto call(F f, Tuple && t)
67  {
68  return call_impl<F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<Tuple>(t));
69  }
70 };
71 
72 template <typename F, typename Tuple, int Total, int... N>
73 struct call_impl<F, Tuple, true, Total, N...>
74 {
75  static auto call(F f, Tuple && t)
76  {
77  return f(std::get<N>(std::forward<Tuple>(t))...);
78  }
79 };
80 
85 template <typename F, typename Tuple>
86 auto call(F f, Tuple && t)
87 {
88  typedef typename std::decay<Tuple>::type ttype;
89  return call_impl<F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
90 }
91 
92 template<typename> class Function; // undefined
97 class GenFunction {
98  private:
99  std::string name;
100  std::string impl;
101  protected:
102  inline static bool in_register_function=false;
103 
104  public:
109  inline static std::map<const std::string, GenFunction*> function_registry;
110 
111  GenFunction(const std::string& name, const std::string& impl)
112  :name(name),
113  impl(impl){ }
114 
115  virtual ~GenFunction() { };
116 
117  std::string& get_name(){
118  return name;
119  }
120 
126  static std::string format_code(const std::string& code){
127  std::stringstream code_out("");
128  std::string command("echo \""+code+"\" | clang-format");
129  char buffer[255];
130  FILE *stream = popen(command.c_str(), "r");
131  while (fgets(buffer, 255, stream) != NULL)
132  code_out << buffer;
133  if (pclose(stream) == 0)
134  return code_out.str();
135  else
136  return code;
137  }
138 
139  static std::string summary(){
140  std::stringstream ss;
141  ss << "The following functions have been registered" << std::endl;
142  for(auto p : function_registry){
143  if (p.second == nullptr) continue;
144  ss << "-->" << p.second->name << std::endl;
145  ss << format_code(p.second->impl);
146  }
147  return ss.str();
148  }
149 
150  template <typename T>
151  static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
152  in_register_function = true;
153  Function<T>* func;
154  if (GenFunction::function_registry[name] != nullptr){
155  func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
156  if (func == nullptr){
157  ERROR("Trying to register function which has already been registered with a different type");
158  }
159  } else {
160  func = new Function<T>(name, impl, f);
161  GenFunction::function_registry[name] = func;
162  }
163  in_register_function = false;
164  return *func;
165  }
166 };
167 
168 
180 template <typename R, typename... ArgTypes>
181 class Function<R(ArgTypes...)> : public GenFunction {
182  private:
183  std::function<R(ArgTypes...)> f;
184 
185  public:
186  Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
187  :GenFunction(name, impl), f(f){
188  if (!in_register_function) {
189  WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
190  }
191  }
192  Function(const std::string& name, std::function<R(ArgTypes...)> f)
193  :Function(name, "N/A", f){ }
194  ~Function() { }
195 
196  R operator()(ArgTypes ...args){
197  return f(args...);
198  }
199 
200 };
201 
202 
203 #define FUNC(f) f, #f
204 
211 class GenValue;
212 typedef std::map<std::string, GenValue*> ValueSet;
213 class GenValue{
214  private:
220  std::string name;
221 
222  protected:
229  virtual void _reset() = 0;
237  inline static std::map<const std::string, GenValue*> values;
245  inline static std::map<const std::string, GenValue*> aliases;
246 
247  public:
248  GenValue(const std::string& name, const std::string& alias)
249  :name(name){
250  values[name] = this;
251  if (alias != "")
252  GenValue::alias(alias, this);
253  }
254 
255  const std::string& get_name(){
256  return name;
257  }
258 
259  void set_name(const std::string& new_name){
260  values[name] = nullptr;
261  name = new_name;
262  values[name] = this;
263  }
264 
265  static void reset(){
266  for (auto val : values){
267  if (val.second != nullptr){
268  val.second->_reset();
269  }
270  }
271  }
272 
273  static GenValue* get_value(const std::string& name){
274  if (aliases[name] != nullptr)
275  return aliases[name];
276  else if (values[name] != nullptr)
277  return values[name];
278  else{
279  ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
280  << summary());
281  CRITICAL("Aborting... :(",-1);
282  }
283  }
284 
285  static void alias(const std::string& name, GenValue* value){
286  if (aliases[name] != nullptr){
287  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
288  }
289  aliases[name] = value;
290  }
291 
292  static GenValue* alias(const std::string& name){
293  if (values[name] != nullptr){
294  WARNING("Alias \"" << name << "\" does not exist.");
295  }
296  return aliases[name];
297  }
298 
299  static std::string summary(){
300  std::stringstream ss;
301  ss << "The following values have been created: " << std::endl;
302  for (auto value : values){
303  if (value.second == nullptr) continue;
304  ss << "\t\"" << value.first << "\" at address " << value.second << std::endl;
305  }
306  ss << "And these aliases:" << std::endl;
307  for (auto alias : aliases){
308  std::string orig("VOID");
309  if (alias.second == nullptr) continue;
310  for (auto value : values){
311  if (alias.second == value.second){
312  orig = value.second->get_name();
313  break;
314  }
315  }
316  ss << "\t\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
317  }
318  return ss.str();
319  }
320  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
321 };
322 std::ostream& operator<<(std::ostream& os, GenValue& gv){
323  os << gv.get_name();
324  return os;
325 }
326 
327 
337 template <typename T>
338 class Value : public GenValue{
339  public:
340  Value(const std::string& name, const std::string& alias="")
341  :GenValue(name, alias){ }
344  virtual T& get_value() = 0;
345 };
346 
347 
357 template <typename T>
358 class ObservedValue : public Value<T>{
359  private:
360  T *val_ref;
361  void _reset(){ }
362 
363  public:
364  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
365  :Value<T>(name, alias),
366  val_ref(val_ref){ }
367  T& get_value(){
368  return *val_ref;
369  }
370 };
371 
372 
388 template <typename T>
389 class DerivedValue : public Value<T>{
390  private:
391  void _reset(){
392  value_valid = false;
393  }
394  protected:
395  T value;
396  bool value_valid;
397 
406  virtual void update_value() = 0;
407  public:
408  DerivedValue(const std::string& name, const std::string& alias="")
409  :Value<T>(name, alias),
410  value_valid(false) { }
411 
412  T& get_value(){
413  /* std::cout << "getting value of " << this->get_name() << std::endl; */
414  if (!value_valid){
415  update_value();
416  value_valid = true;
417  }
418  return value;
419  }
420 };
421 
422 
432 template <typename T>
433 class WrapperVector : public DerivedValue<std::vector<T> >{
434  private:
435  Value<int>* size;
436  Value<T*>* data;
437 
438  void update_value(){
439  int n = size->get_value();
440  T* data_ref = data->get_value();
441  this->value.assign(data_ref, data_ref+n);
442  }
443 
444  public:
445  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
446  :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
447  size(size), data(data){ }
448 };
449 
453 template <typename T1, typename T2>
454 class Pair : public DerivedValue<std::pair<T1, T2> >{
455  protected:
456  std::pair<Value<T1>*, Value<T2>* > value_pair;
457  void update_value(){
458  this->value.first = value_pair.first->get_value();
459  this->value.second = value_pair.second->get_value();
460  }
461 
462  public:
463  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
464  :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
465  value_pair(value1, value2){ }
466 };
467 
468 template<typename... T> class _Zip;
469 template<>
470 class _Zip<> {
471  protected:
472 
473  int _get_size(){
474  return std::numeric_limits<int>::max();
475  }
476 
477  std::tuple<> _get_at(int idx){
478  return std::make_tuple();
479  }
480 
481  bool _verify_integrity() {
482  return true;
483  }
484 
485  std::string _get_name(){
486  return "";
487  }
488 
489  public:
490  _Zip() { }
491 };
492 
493 template<typename Head, typename... Tail>
494 class _Zip<Head, Tail...> : private _Zip<Tail...> {
495  protected:
497 
498  int _get_size(){
499  int this_size = head->get_value().size();
500  int rest_size = _Zip<Tail...>::_get_size();
501  return std::min(this_size, rest_size);
502  }
503 
504  typename std::tuple<Head,Tail...> _get_at(int idx){
505  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
506  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
507  }
508 
509  bool _verify_integrity() {
510  return (head != nullptr) &&_Zip<Tail...>::_verify_integrity();
511  }
512 
513  std::string _get_name(){
514  return head->get_name()+","+_Zip<Tail...>::_get_name();
515  }
516 
517  public:
518  _Zip() { }
519 
520  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
521  : _Zip<Tail...>(tail...),
522  head(head) { }
523 };
524 
540 template <typename... ArgTypes>
541 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
542  private _Zip<ArgTypes...>{
543  protected:
544  void update_value(){
545  this->value.clear();
546  int size = _Zip<ArgTypes...>::_get_size();
547  for(int i=0; i<size; i++){
548  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
549  }
550  }
551 
552  std::string _get_name(){
553  return "zip("+_Zip<ArgTypes...>::_get_name()+")";
554  }
555 
556  public:
557  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
558  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
559  _Zip<ArgTypes...>(args...) {
560  this->set_name(_get_name());
561  }
562 };
563 
564 template<typename> class Map; // undefined
565 template <typename Ret, typename... ArgTypes>
566 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
567  private:
568  Function<Ret(ArgTypes...)>& fn;
569  Zip<ArgTypes...>* arg;
570 
571  void update_value(){
572  this->value.clear();
573  for(auto tup : arg->get_value()){
574  this->value.push_back(call(fn,tup));
575  }
576  }
577 
578  public:
579  Map(Function<Ret(ArgTypes...)>& fn, Zip<ArgTypes...>* arg, const std::string& alias)
580  :DerivedValue<std::vector<Ret>>("map_over("+fn.get_name()+":"+arg->get_name()+")", alias),
581  fn(fn), arg(arg){ }
582 
583 };
584 
598 template <typename R, typename T>
599 class ZipMapFour : public DerivedValue<std::vector<R> >{
600  private:
602  Value<std::vector<T> >* v1;
603  Value<std::vector<T> >* v2;
604  Value<std::vector<T> >* v3;
605  Value<std::vector<T> >* v4;
606 
607  void update_value(){
608  std::vector<T> v1_val = v1->get_value();
609  std::vector<T> v2_val = v2->get_value();
610  std::vector<T> v3_val = v3->get_value();
611  std::vector<T> v4_val = v4->get_value();
612 
613  int n;
614  std::tie(n, std::ignore) = std::minmax({v1_val.size(), v2_val.size(), v3_val.size(), v4_val.size()});
615  this->value.resize(n);
616  for (int i=0; i<n; i++){
617  this->value[i] = f(v1_val[i], v2_val[i], v3_val[i], v4_val[i]);
618  }
619  }
620 
621  public:
622  ZipMapFour(Function<R(T, T, T, T)>& f,
623  Value<std::vector<T> >* v1, Value<std::vector<T> >* v2,
624  Value<std::vector<T> >* v3, Value<std::vector<T> >* v4, const std::string alias)
625  :DerivedValue<std::vector<R> >("zipmap("+f.get_name()+":"+v1->get_name()+","+v2->get_name()+","+
626  v3->get_name()+","+v4->get_name()+")", alias),
627  f(f), v1(v1), v2(v2), v3(v3), v4(v4) { }
628 
629  ZipMapFour(Function<R(T, T, T, T)>& f,
630  const std::string& label1, const std::string& label2,
631  const std::string& label3, const std::string& label4, const std::string alias)
632  :ZipMapFour(f,
633  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label1)),
634  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label2)),
635  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label3)),
636  dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label4)),
637  alias){ }
638 };
639 
643 template<typename T>
644 class Count : public DerivedValue<int>{
645  private:
646  Function<bool(T)>& selector;
648 
649  void update_value(){
650  value = 0;
651  for(auto val : v->get_value()){
652  if(selector(val))
653  value++;
654  }
655  }
656 
657  public:
658  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
659  :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
660  selector(selector), v(v) { }
661 };
662 
663 
670 template <typename T>
671 class Reduce : public DerivedValue<T>{
672  private:
673  Function<T(std::vector<T>)>& reduce;
674 
675  void update_value(){
676  this->value = reduce(v->get_value());
677  }
678 
679  protected:
681 
682  public:
683  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
684  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
685  reduce(reduce), v(v) { }
686 };
687 
691 template <typename T>
692 class Max : public Reduce<T>{
693  public:
694  Max(Value<std::vector<T>>* v, const std::string alias)
695  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
696  FUNC(([](std::vector<T> vec){
697  return *std::max_element(vec.begin(), vec.end());}))),
698  v, alias) { }
699 };
700 
704 template <typename T>
705 class Min : public Reduce<T>{
706  public:
707  Min(Value<std::vector<T>>* v, const std::string alias)
708  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
709  FUNC(([](std::vector<T> vec){
710  return *std::min_element(vec.begin(), vec.end());}))),
711  v, alias) { }
712 };
713 
717 template <typename T>
718 class Mean : public Reduce<T>{
719  public:
720  Mean(Value<std::vector<T>>* v, const std::string alias)
721  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
722  FUNC(([](std::vector<T> vec){
723  int n = 0; T sum = 0;
724  for (T e : vec){ n++; sum += e; }
725  return n>0 ? sum / n : 0; }))),
726  v, alias) { }
727 };
728 
732 template <typename T>
733 class Range : public Reduce<T>{
734  public:
735  Range(Value<std::vector<T>>* v, const std::string alias)
736  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
737  FUNC(([](std::vector<T> vec){
738  auto minmax = std::minmax_element(vec.begin(), vec.end());
739  return (*minmax.second) - (*minmax.first); }))),
740  v, alias) { }
741 };
742 
746 template <typename T>
747 class ElementOf : public Reduce<T>{
748  public:
749  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
750  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
751  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
752  v, alias) { }
753 };
754 
760 template <typename T>
761 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
762  private:
763  Function<std::pair<T,int>(std::vector<T>)>& reduce;
765 
766  void update_value(){
767  this->value = reduce(v->get_value());
768  }
769 
770  public:
771  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
772  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
773  reduce(reduce), v(v) { }
774 };
775 
779 template <typename T>
780 class MaxIndex : public ReduceIndex<T>{
781  public:
782  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
783  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
784  FUNC(([](std::vector<T> vec){
785  auto elptr = std::max_element(vec.begin(), vec.end());
786  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
787  v, alias) { }
788 };
789 
793 template <typename T>
794 class MinIndex : public ReduceIndex<T>{
795  public:
796  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
797  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
798  FUNC(([](std::vector<T> vec){
799  auto elptr = std::min_element(vec.begin(), vec.end());
800  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
801  v, alias) { }
802 };
803 
809 template <typename T>
810 class BoundValue : public DerivedValue<T>{
811  protected:
812  Function<T()>& f;
813  void update_value(){
814  this->value = f();
815  }
816  public:
817  BoundValue(Function<T()>& f, const std::string alias="")
818  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
819  f(f) { }
820 };
821 
826 template <typename T>
827 class PointerValue : public DerivedValue<T*>{
828  protected:
829  void update_value(){ }
830 
831  public:
832  PointerValue(const std::string& name, T* ptr, const std::string alias="")
833  :DerivedValue<T*>(name, alias){
834  this->value = ptr;
835  }
836 };
837 
841 template <typename T>
842 class ConstantValue : public DerivedValue<T>{
843  protected:
844  void update_value(){ }
845 
846  public:
847  ConstantValue(const std::string& name, T const_value, const std::string alias="")
848  :DerivedValue<T>("const::"+name, alias),
849  Value<T>::value(const_value) { }
850 };
851 }
852 #endif // value_hpp
Definition: value.hpp:213
void update_value()
Updates the internal value.
Definition: value.hpp:813
Find and return the maximum value of a vector.
Definition: value.hpp:692
Zips a series of vectors together.
Definition: value.hpp:541
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:671
void update_value()
Updates the internal value.
Definition: value.hpp:649
void update_value()
Updates the internal value.
Definition: value.hpp:457
Find and return the minimum value of a vector and its index.
Definition: value.hpp:794
Definition: value.hpp:468
void _reset()
Mark the internal value as invalid.
Definition: value.hpp:391
A generic value owning only a function object.
Definition: value.hpp:810
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:412
Calculate the range of the values in a vector.
Definition: value.hpp:733
A std::vector wrapper around a C-style array.
Definition: value.hpp:433
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:761
std::string name
The name of the value.
Definition: value.hpp:220
void update_value()
Updates the internal value.
Definition: value.hpp:607
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:644
Find and return the maximum value of a vector and its index.
Definition: value.hpp:780
void update_value()
Updates the internal value.
Definition: value.hpp:675
Parent class to all Function classes.
Definition: value.hpp:97
void _reset()
Mark the internal value as invalid.
Definition: value.hpp:361
Takes a set of four Value<std::vector<T> > objects and a function of four Ts and returns a std::vecto...
Definition: value.hpp:599
static std::map< const std::string, GenValue * > aliases
Composite value names are typically nested.
Definition: value.hpp:245
A generic, observed, value.
Definition: value.hpp:358
Find and return the minimum value of a vector.
Definition: value.hpp:705
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:454
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:367
void update_value()
Updates the internal value.
Definition: value.hpp:766
void update_value()
Updates the internal value.
Definition: value.hpp:571
void update_value()
Updates the internal value.
Definition: value.hpp:844
The namespace containing all filval classes and functions.
Definition: api.hpp:6
Extract the element at a specific index from a vector.
Definition: value.hpp:747
Calculate the mean value of a vector.
Definition: value.hpp:718
void update_value()
Updates the internal value.
Definition: value.hpp:438
A generic value.
Definition: value.hpp:338
void update_value()
Updates the internal value.
Definition: value.hpp:544
static std::map< const std::string, GenValue * > values
A static mapping containing all created Value objects.
Definition: value.hpp:237
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:126
Definition: value.hpp:564
A generic, derived, value.
Definition: value.hpp:389
Definition: value.hpp:64
void update_value()
Updates the internal value.
Definition: value.hpp:829
Definition: value.hpp:92
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:842
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:109
A Value of a pointer.
Definition: value.hpp:827
auto call(F f, Tuple &&t)
This calls a function of type F with the contents of the tuple as arguments.
Definition: value.hpp:86