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
93 
98 class GenFunction {
99  private:
100  std::string name;
101  std::string impl;
102  protected:
103  inline static bool in_register_function=false;
104 
105  public:
110  inline static std::map<const std::string, GenFunction*> function_registry;
111 
112  GenFunction(const std::string& name, const std::string& impl)
113  :name(name),
114  impl(impl){ }
115 
116  virtual ~GenFunction() { };
117 
118  std::string& get_name(){
119  return name;
120  }
121 
127  static std::string format_code(const std::string& code){
128  std::stringstream code_out("");
129  std::string command("echo \""+code+"\" | clang-format");
130  char buffer[255];
131  FILE *stream = popen(command.c_str(), "r");
132  while (fgets(buffer, 255, stream) != NULL)
133  code_out << buffer;
134  if (pclose(stream) == 0)
135  return code_out.str();
136  else
137  return code;
138  }
139 
140  static std::string summary(){
141  std::stringstream ss;
142  ss << "The following functions have been registered" << std::endl;
143  for(auto p : function_registry){
144  if (p.second == nullptr) continue;
145  ss << "-->" << p.second->name << "@" << p.second << std::endl;
146  ss << format_code(p.second->impl);
147  }
148  return ss.str();
149  }
150 
151  template <typename T>
152  static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
153  in_register_function = true;
154  Function<T>* func;
155  if (GenFunction::function_registry[name] != nullptr){
156  func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
157  if (func == nullptr){
158  ERROR("Trying to register function which has already been registered with a different type");
159  }
160  } else {
161  func = new Function<T>(name, impl, f);
162  GenFunction::function_registry[name] = func;
163  }
164  in_register_function = false;
165  return *func;
166  }
167 };
168 
169 
181 template <typename R, typename... ArgTypes>
182 class Function<R(ArgTypes...)> : public GenFunction {
183  private:
184  std::function<R(ArgTypes...)> f;
185 
186  public:
187  Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
188  :GenFunction(name, impl), f(f){
189  if (!in_register_function) {
190  WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
191  }
192  }
193  Function(const std::string& name, std::function<R(ArgTypes...)> f)
194  :Function(name, "N/A", f){ }
195  ~Function() { }
196 
197  R operator()(ArgTypes ...args){
198  return f(args...);
199  }
200 
201 };
202 
203 
204 #define FUNC(f) f, #f
205 
212 class GenValue;
213 typedef std::map<std::string, GenValue*> ValueSet;
214 class GenValue{
215  private:
221  std::string name;
222 
223  protected:
230  virtual void _reset() = 0;
238  inline static std::map<const std::string, GenValue*> values;
246  inline static std::map<const std::string, GenValue*> aliases;
247 
248  public:
249  GenValue(const std::string& name, const std::string& alias)
250  :name(name){
251  values[name] = this;
252  if (alias != "")
253  GenValue::alias(alias, this);
254  }
255 
256  const std::string& get_name(){
257  return name;
258  }
259 
260  void set_name(const std::string& new_name){
261  values[name] = nullptr;
262  name = new_name;
263  values[name] = this;
264  }
265 
266  static void reset(){
267  for (auto val : values){
268  if (val.second != nullptr){
269  val.second->_reset();
270  }
271  }
272  }
273 
274  static GenValue* get_value(const std::string& name){
275  if (aliases[name] != nullptr)
276  return aliases[name];
277  else if (values[name] != nullptr)
278  return values[name];
279  else{
280  ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
281  << summary());
282  CRITICAL("Aborting... :(",-1);
283  }
284  }
285 
286  static void alias(const std::string& name, GenValue* value){
287  if (aliases[name] != nullptr){
288  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
289  }
290  aliases[name] = value;
291  }
292 
293  static GenValue* alias(const std::string& name){
294  if (values[name] != nullptr){
295  WARNING("Alias \"" << name << "\" does not exist.");
296  }
297  return aliases[name];
298  }
299 
300  static std::string summary(){
301  std::stringstream ss;
302  ss << "The following values have been created: " << std::endl;
303  for (auto value : values){
304  if (value.second == nullptr) continue;
305  ss << "\t\"" << value.first << "\" at address " << value.second << std::endl;
306  }
307  ss << "And these aliases:" << std::endl;
308  for (auto alias : aliases){
309  std::string orig("VOID");
310  if (alias.second == nullptr) continue;
311  for (auto value : values){
312  if (alias.second == value.second){
313  orig = value.second->get_name();
314  break;
315  }
316  }
317  ss << "\t\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
318  }
319  return ss.str();
320  }
321  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
322 };
323 std::ostream& operator<<(std::ostream& os, GenValue& gv){
324  os << gv.get_name();
325  return os;
326 }
327 
328 
338 template <typename T>
339 class Value : public GenValue{
340  public:
341  Value(const std::string& name, const std::string& alias="")
342  :GenValue(name, alias){ }
345  virtual T& get_value() = 0;
346 };
347 
348 
358 template <typename T>
359 class ObservedValue : public Value<T>{
360  private:
361  T *val_ref;
362  void _reset(){ }
363 
364  public:
365  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
366  :Value<T>(name, alias),
367  val_ref(val_ref){ }
368  T& get_value(){
369  return *val_ref;
370  }
371 };
372 
373 
389 template <typename T>
390 class DerivedValue : public Value<T>{
391  private:
392  void _reset(){
393  value_valid = false;
394  }
395  protected:
396  T value;
397  bool value_valid;
398 
407  virtual void update_value() = 0;
408  public:
409  DerivedValue(const std::string& name, const std::string& alias="")
410  :Value<T>(name, alias),
411  value_valid(false) { }
412 
413  T& get_value(){
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  std::string _get_name(){
482  return "";
483  }
484 
485  public:
486  _Zip() { }
487 };
488 
489 template<typename Head, typename... Tail>
490 class _Zip<Head, Tail...> : private _Zip<Tail...> {
491  protected:
493 
494  int _get_size(){
495  int this_size = head->get_value().size();
496  int rest_size = _Zip<Tail...>::_get_size();
497  return std::min(this_size, rest_size);
498  }
499 
500  typename std::tuple<Head,Tail...> _get_at(int idx){
501  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
502  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
503  }
504 
505  std::string _get_name(){
506  return head->get_name()+","+_Zip<Tail...>::_get_name();
507  }
508 
509  public:
510  _Zip() { }
511 
512  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
513  : _Zip<Tail...>(tail...),
514  head(head) { }
515 };
516 
532 template <typename... ArgTypes>
533 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
534  private _Zip<ArgTypes...>{
535  protected:
536  void update_value(){
537  this->value.clear();
538  int size = _Zip<ArgTypes...>::_get_size();
539  for(int i=0; i<size; i++){
540  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
541  }
542  }
543 
544  std::string _get_name(){
545  return "zip("+_Zip<ArgTypes...>::_get_name()+")";
546  }
547 
548  public:
549  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
550  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
551  _Zip<ArgTypes...>(args...) {
552  this->set_name(_get_name());
553  }
554 };
555 
556 template<typename> class Map; // undefined
564 template <typename Ret, typename... ArgTypes>
565 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
566  private:
567  Function<Ret(ArgTypes...)>& fn;
568  Zip<ArgTypes...>* arg;
569 
570  void update_value(){
571  this->value.clear();
572  for(auto tup : arg->get_value()){
573  this->value.push_back(call(fn,tup));
574  }
575  }
576 
577  public:
578  Map(Function<Ret(ArgTypes...)>& fn, Zip<ArgTypes...>* arg, const std::string& alias)
579  :DerivedValue<std::vector<Ret>>("map("+fn.get_name()+":"+arg->get_name()+")", alias),
580  fn(fn), arg(arg){ }
581 
582 };
583 
584 template<typename... T> class _Tuple;
585 template<>
586 class _Tuple<> {
587  protected:
588 
589  std::tuple<> _get_value(){
590  return std::make_tuple();
591  }
592 
593  std::string _get_name(){
594  return "";
595  }
596 
597  public:
598  _Tuple() { }
599 };
600 
601 template<typename Head, typename... Tail>
602 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
603  protected:
604  Value<Head>* head;
605 
606  typename std::tuple<Head,Tail...> _get_value(){
607  auto tail_tuple = _Tuple<Tail...>::_get_value();
608  return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
609  }
610 
611 
612  std::string _get_name(){
613  return head->get_name()+","+_Tuple<Tail...>::_get_name();
614  }
615 
616  public:
617  _Tuple() { }
618 
619  _Tuple(Value<Head>* head, Value<Tail>*... tail)
620  : _Tuple<Tail...>(tail...),
621  head(head) { }
622 };
623 
630 template <typename... ArgTypes>
631 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
632  private _Tuple<ArgTypes...>{
633  protected:
634  void update_value(){
635  this->value = _Tuple<ArgTypes...>::_get_value();
636  }
637 
638  std::string _get_name(){
639  return "tuple("+_Tuple<ArgTypes...>::_get_name()+")";
640  }
641 
642  public:
643  Tuple(Value<ArgTypes>*... args, const std::string& alias)
644  :DerivedValue<std::tuple<ArgTypes...>>("", alias),
645  _Tuple<ArgTypes...>(args...) {
646  this->set_name(_get_name());
647  }
648 };
649 
650 template<typename> class Apply; // undefined
655 template <typename Ret, typename... ArgTypes>
656 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
657  private:
658  Function<Ret(ArgTypes...)>& fn;
659  Tuple<ArgTypes...>* arg;
660 
661  void update_value(){
662  auto &tup = arg->get_value();
663  this->value = call(fn, tup);
664  }
665 
666  public:
667  Apply(Function<Ret(ArgTypes...)>& fn, Tuple<ArgTypes...>* arg, const std::string& alias)
668  :DerivedValue<Ret>("apply("+fn.get_name()+":"+arg->get_name()+")", alias),
669  fn(fn), arg(arg){ }
670 
671 };
672 
673 
677 template<typename T>
678 class Count : public DerivedValue<int>{
679  private:
680  Function<bool(T)>& selector;
682 
683  void update_value(){
684  value = 0;
685  for(auto val : v->get_value()){
686  if(selector(val))
687  value++;
688  }
689  }
690 
691  public:
692  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
693  :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
694  selector(selector), v(v) { }
695 };
696 
697 
704 template <typename T>
705 class Reduce : public DerivedValue<T>{
706  private:
707  Function<T(std::vector<T>)>& reduce;
708 
709  void update_value(){
710  this->value = reduce(v->get_value());
711  }
712 
713  protected:
715 
716  public:
717  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
718  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
719  reduce(reduce), v(v) { }
720 };
721 
725 template <typename T>
726 class Max : public Reduce<T>{
727  public:
728  Max(Value<std::vector<T>>* v, const std::string alias)
729  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
730  FUNC(([](std::vector<T> vec){
731  return *std::max_element(vec.begin(), vec.end());}))),
732  v, alias) { }
733 };
734 
738 template <typename T>
739 class Min : public Reduce<T>{
740  public:
741  Min(Value<std::vector<T>>* v, const std::string alias)
742  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
743  FUNC(([](std::vector<T> vec){
744  return *std::min_element(vec.begin(), vec.end());}))),
745  v, alias) { }
746 };
747 
751 template <typename T>
752 class Mean : public Reduce<T>{
753  public:
754  Mean(Value<std::vector<T>>* v, const std::string alias)
755  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
756  FUNC(([](std::vector<T> vec){
757  int n = 0; T sum = 0;
758  for (T e : vec){ n++; sum += e; }
759  return n>0 ? sum / n : 0; }))),
760  v, alias) { }
761 };
762 
766 template <typename T>
767 class Range : public Reduce<T>{
768  public:
769  Range(Value<std::vector<T>>* v, const std::string alias)
770  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
771  FUNC(([](std::vector<T> vec){
772  auto minmax = std::minmax_element(vec.begin(), vec.end());
773  return (*minmax.second) - (*minmax.first); }))),
774  v, alias) { }
775 };
776 
780 template <typename T>
781 class ElementOf : public Reduce<T>{
782  public:
783  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
784  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
785  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
786  v, alias) { }
787 };
788 
794 template <typename T>
795 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
796  private:
797  Function<std::pair<T,int>(std::vector<T>)>& reduce;
799 
800  void update_value(){
801  this->value = reduce(v->get_value());
802  }
803 
804  public:
805  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
806  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
807  reduce(reduce), v(v) { }
808 };
809 
813 template <typename T>
814 class MaxIndex : public ReduceIndex<T>{
815  public:
816  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
817  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
818  FUNC(([](std::vector<T> vec){
819  auto elptr = std::max_element(vec.begin(), vec.end());
820  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
821  v, alias) { }
822 };
823 
827 template <typename T>
828 class MinIndex : public ReduceIndex<T>{
829  public:
830  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
831  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
832  FUNC(([](std::vector<T> vec){
833  auto elptr = std::min_element(vec.begin(), vec.end());
834  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
835  v, alias) { }
836 };
837 
843 template <typename T>
844 class BoundValue : public DerivedValue<T>{
845  protected:
846  Function<T()>& f;
847  void update_value(){
848  this->value = f();
849  }
850  public:
851  BoundValue(Function<T()>& f, const std::string alias="")
852  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
853  f(f) { }
854 };
855 
860 template <typename T>
861 class PointerValue : public DerivedValue<T*>{
862  protected:
863  void update_value(){ }
864 
865  public:
866  PointerValue(const std::string& name, T* ptr, const std::string alias="")
867  :DerivedValue<T*>(name, alias){
868  this->value = ptr;
869  }
870 };
871 
875 template <typename T>
876 class ConstantValue : public DerivedValue<T>{
877  protected:
878  void update_value(){ }
879 
880  public:
881  ConstantValue(const std::string& name, T const_value, const std::string alias="")
882  :DerivedValue<T>("const::"+name, alias),
883  Value<T>::value(const_value) { }
884 };
885 }
886 #endif // value_hpp
void update_value()
Updates the internal value.
Definition: value.hpp:847
Find and return the maximum value of a vector.
Definition: value.hpp:726
Zips a series of vectors together.
Definition: value.hpp:533
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:705
void update_value()
Updates the internal value.
Definition: value.hpp:683
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:828
A generic value owning only a function object.
Definition: value.hpp:844
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:413
Calculate the range of the values in a vector.
Definition: value.hpp:767
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:631
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:795
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:678
Find and return the maximum value of a vector and its index.
Definition: value.hpp:814
void update_value()
Updates the internal value.
Definition: value.hpp:709
Parent class to all Function classes.
Definition: value.hpp:98
void update_value()
Updates the internal value.
Definition: value.hpp:634
A value supplied by the dataset, not derived.
Definition: value.hpp:359
Find and return the minimum value of a vector.
Definition: value.hpp:739
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:454
void update_value()
Updates the internal value.
Definition: value.hpp:661
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:368
void update_value()
Updates the internal value.
Definition: value.hpp:800
void update_value()
Updates the internal value.
Definition: value.hpp:570
void update_value()
Updates the internal value.
Definition: value.hpp:878
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:781
Calculate the mean value of a vector.
Definition: value.hpp:752
void update_value()
Updates the internal value.
Definition: value.hpp:438
A generic value.
Definition: value.hpp:339
void update_value()
Updates the internal value.
Definition: value.hpp:536
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:127
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:390
void update_value()
Updates the internal value.
Definition: value.hpp:863
virtual T & get_value()=0
Calculate, if necessary, and return the value held by this object.
auto call(F &f, TUPLE &&t)
This calls a function of type F with the contents of the tuple as separate arguments.
Definition: value.hpp:86
A Value which always returns the same value, supplied in the constructor.
Definition: value.hpp:876
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:110
A Value of a pointer.
Definition: value.hpp:861