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 namespace detail {
64  template<typename T, int N, bool Done, typename... TYPES>
65  struct _HomoTuple {
66  typedef _HomoTuple<T, N, sizeof...(TYPES)+1==N, TYPES..., T> stype;
67  typedef typename stype::type type;
68  };
69 
70  template<typename T, int N, typename... TYPES>
71  struct _HomoTuple<T, N, true, TYPES...> {
72  typedef std::tuple<TYPES...> type;
73  };
74 }
75 
76 template<typename T, int N>
77 struct HomoTuple {
78  typedef detail::_HomoTuple<T, N, N==0> stype;
79  typedef typename stype::type type;
80 };
81 
82 namespace detail {
83  // Convert array into a tuple
84  template<typename Array, std::size_t... I>
85  decltype(auto) a2t_impl(const Array& a, std::index_sequence<I...>){
86  return std::make_tuple(a[I]...);
87  }
88 }
89 
93 template<typename T, std::size_t N, typename Indices = std::make_index_sequence<N>>
94 decltype(auto) a2t(const std::array<T, N>& a){
95  return detail::a2t_impl(a, Indices());
96 }
97 
98 namespace detail {
99  template <class F, class Tuple, std::size_t... I>
100  constexpr decltype(auto) call_impl(F &&f, Tuple &&t, std::index_sequence<I...>){
101  return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
102  }
103 }
104 
105 template <class F, class Tuple>
106 constexpr decltype(auto) call(F &&f, Tuple &&t){
107  return detail::call_impl(
108  std::forward<F>(f), std::forward<Tuple>(t),
109  std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
110 }
111 
112 namespace detail{
113  template <typename T, int N, int I>
114  struct t2s_impl{
115  public:
116  static std::string cvt(typename HomoTuple<T,N>::type& tup, std::function<std::string(T)>& f){
117  std::stringstream ss;
118  ss << f(std::get<N-I>(tup)) << ", " << t2s_impl<T, N, I+1>::cvt(tup, f);
119  return ss.str();
120  }
121  };
122 
123  template <typename T, int N>
124  struct t2s_impl<T, N, 0>{
125  public:
126  static std::string cvt(typename HomoTuple<T,N>::type&, std::function<std::string(T)>&){
127  return "";
128  }
129  };
130 }
131 
132 template <typename T, int N>
133 std::string t2s(typename HomoTuple<T,N>::type& tup, std::function<std::string(T)>& f){
134  return detail::t2s_impl<T, N, N>(tup, f);
135 }
136 
137 template<typename> class Function; // undefined
138 
143 class GenFunction {
144  private:
145  std::string name;
146  std::string impl;
147  protected:
148  inline static bool in_register_function=false;
149 
150  public:
155  inline static std::map<const std::string, GenFunction*> function_registry;
156 
157  GenFunction(const std::string& name, const std::string& impl)
158  :name(name),
159  impl(impl){ }
160 
161  virtual ~GenFunction() { };
162 
163  std::string& get_name(){
164  return name;
165  }
166 
167  std::string& get_impl(){
168  return impl;
169  }
170 
176  static std::string format_code(const std::string& code){
177  std::stringstream code_out("");
178  std::string command("echo \""+code+"\" | clang-format");
179  char buffer[255];
180  FILE *stream = popen(command.c_str(), "r");
181  while (fgets(buffer, 255, stream) != NULL)
182  code_out << buffer;
183  if (pclose(stream) == 0)
184  return code_out.str();
185  else
186  return code;
187  }
188 
189  static std::string summary(){
190  std::stringstream ss;
191  ss << "The following functions have been registered" << std::endl;
192  for(auto p : function_registry){
193  if (p.second == nullptr) continue;
194  ss << "FUNCTION::" << p.second->name << "@" << p.second << std::endl;
195  ss << format_code(p.second->impl);
196  }
197  return ss.str();
198  }
199 
200  template <typename T>
201  static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
202  in_register_function = true;
203  Function<T>* func;
204  if (GenFunction::function_registry[name] != nullptr){
205  func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
206  if (func == nullptr){
207  ERROR("Trying to register function which has already been registered with a different type");
208  }
209  } else {
210  func = new Function<T>(name, impl, f);
211  GenFunction::function_registry[name] = func;
212  }
213  in_register_function = false;
214  return *func;
215  }
216 
217  template <typename T>
218  static Function<T>& lookup_function(const std::string& name){
219  if (GenFunction::function_registry[name] == nullptr){
220  CRITICAL("Function \"" << name << "\" not previously registered", -1);
221  } else {
222  Function<T>* func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
223  if (func == nullptr){
224  CRITICAL("Function \"" << name << "\" request and register have mismatched types", -1);
225  }
226  return *GenFunction::function_registry[name];
227  }
228  }
229 };
230 
231 
243 template <typename R, typename... ArgTypes>
244 class Function<R(ArgTypes...)> : public GenFunction {
245  private:
246  std::function<R(ArgTypes...)> f;
247 
248  public:
249  Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
250  :GenFunction(name, impl), f(f){
251  if (!in_register_function) {
252  WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
253  }
254  }
255  Function(const std::string& name, std::function<R(ArgTypes...)> f)
256  :Function(name, "N/A", f){ }
257  ~Function() { }
258 
259  R operator()(ArgTypes ...args){
260  return f(args...);
261  }
262 
263 };
264 
265 
266 #define FUNC(f) f, #f
267 
274 class GenValue;
275 typedef std::map<std::string, GenValue*> ValueSet;
276 class GenValue{
277  private:
283  std::string name;
284 
285  protected:
292  bool value_valid;
293 
294  void _reset(){
295  this->value_valid = false;
296  }
297 
305  inline static std::map<const std::string, GenValue*> values;
306 
314  inline static std::map<const std::string, GenValue*> aliases;
315 
316  bool logging_enabled;
317 
318  public:
319  GenValue(const std::string& name, const std::string& alias)
320  :name(name),
321  value_valid(false),
322  logging_enabled(false){
323  INFO("Registered value: \"" << name << "\" with alias: \"" << alias << "\"");
324  values[name] = this;
325  if (alias != "")
326  GenValue::alias(alias, this);
327  }
328 
329  const std::string& get_name(){
330  return name;
331  }
332 
333  void set_name(const std::string& new_name){
334  values[name] = nullptr;
335  name = new_name;
336  values[name] = this;
337  }
338 
345  virtual void log() = 0;
346 
347  static void reset(){
348  for (auto val : values){
349  if (val.second != nullptr){
350  val.second->_reset();
351  }
352  }
353  }
354 
355  static GenValue* get_value(const std::string& name){
356  if (aliases[name] != nullptr)
357  return aliases[name];
358  else
359  return values[name];
360  }
361 
362  static void alias(const std::string& name, GenValue* value){
363  if (aliases[name] != nullptr){
364  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
365  }
366  aliases[name] = value;
367  }
368 
369  static GenValue* alias(const std::string& name){
370  if (values[name] != nullptr){
371  WARNING("Alias \"" << name << "\" does not exist.");
372  }
373  return aliases[name];
374  }
375 
376  static std::string summary(){
377  std::stringstream ss;
378  ss << "The following values have been created:" << std::endl;
379  for (auto value : values){
380  if (value.second == nullptr) continue;
381  ss << "\tVALUE::\"" << value.first << "\" at address " << value.second << std::endl;
382  }
383  ss << "And these aliases:" << std::endl;
384  for (auto alias : aliases){
385  std::string orig("VOID");
386  if (alias.second == nullptr) continue;
387  for (auto value : values){
388  if (alias.second == value.second){
389  orig = value.second->get_name();
390  break;
391  }
392  }
393  ss << "\tALIAS::\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
394  }
395  return ss.str();
396  }
397  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
398 };
399 std::ostream& operator<<(std::ostream& os, GenValue& gv){
400  os << gv.get_name();
401  return os;
402 }
403 
404 
414 template <typename T>
415 class Value : public GenValue{
416  protected:
417  std::function<std::string(T)> value_to_string;
418 
419  public:
420  Value(const std::string& name, const std::string& alias="")
421  :value_to_string([](T){return "";}),
422  GenValue(name, alias){ }
425  virtual T& get_value() = 0;
426 
427  void enable_logging(const std::function<std::string(T)>& value_to_string = [](T){return "";}){
428  logging_enabled = true;
429  this->value_to_string = value_to_string;
430  }
431 
432  void disable_logging(){
433  logging_enabled = false;
434  }
435 };
436 
437 
447 template <typename T>
448 class ObservedValue : public Value<T>{
449  private:
450  T *val_ref;
451 
452  public:
453  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
454  :Value<T>(name, alias),
455  val_ref(val_ref){ }
456 
457  void log(){
458  if(this->logging_enabled){
459  INFO(this->get_name() << ": " << this->value_to_string(*val_ref));
460  }
461  }
462 
463  static std::string fmt_name(const std::string& name){
464  return name;
465  }
466 
467  T& get_value(){
468  if (!this->value_valid){
469  this->value_valid = true;
470  this->log();
471  }
472  return *val_ref;
473  }
474 };
475 
476 
492 template <typename T>
493 class DerivedValue : public Value<T>{
494  protected:
495  T value;
496 
505  virtual void update_value() = 0;
506  public:
507  DerivedValue(const std::string& name, const std::string& alias="")
508  :Value<T>(name, alias){ }
509 
510  void log(){
511  if(this->logging_enabled){
512  INFO(this->get_name() << ": " << this->value_to_string(value));
513  }
514  }
515 
516  T& get_value(){
517  /* if (this->logging_enabled){ */
518  /* std::cout << "Getting value for " << this->get_name() << std::endl; */
519  /* } */
520  if (!this->value_valid){
521  /* if (this->logging_enabled){ */
522  /* std::cout << "Updating value for " << this->get_name() << std::endl; */
523  /* } */
524  update_value();
525  this->value_valid = true;
526  this->log();
527  }
528  return value;
529  }
530 };
531 
532 
542 template <typename T>
543 class WrapperVector : public DerivedValue<std::vector<T> >{
544  private:
545  Value<int>* size;
546  Value<T*>* data;
547 
548  void update_value(){
549  int n = size->get_value();
550  T* data_ref = data->get_value();
551  this->value.assign(data_ref, data_ref+n);
552  }
553 
554  public:
555  static std::string fmt_name(Value<int>* size, Value<T*>* data){
556  return "wrapper_vector("+size->get_name()+","+data->get_name()+")";
557  }
558 
559  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
560  :DerivedValue<std::vector<T> >(fmt_name(size,data), alias),
561  size(size), data(data){ }
562 };
563 
567 template <typename T1, typename T2>
568 class Pair : public DerivedValue<std::pair<T1, T2> >{
569  protected:
570  std::pair<Value<T1>*, Value<T2>* > value_pair;
571  void update_value(){
572  this->value.first = value_pair.first->get_value();
573  this->value.second = value_pair.second->get_value();
574  }
575 
576  public:
577  static std::string fmt_name(Value<T1> *value1, Value<T2> *value2){
578  return "pair("+value1->get_name()+","+value2->get_name()+")";
579  }
580 
581  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
582  :DerivedValue<std::pair<T1, T2> >(fmt_name(value1, value2), alias),
583  value_pair(value1, value2){ }
584 };
585 
586 template<typename... T> class _Zip;
587 template<>
588 class _Zip<> {
589  protected:
590 
591  int _get_size(){
592  return std::numeric_limits<int>::max();
593  }
594 
595  std::tuple<> _get_at(int){
596  return std::make_tuple();
597  }
598 
599  std::string _get_name(){
600  return "";
601  }
602 
603  public:
604  _Zip() { }
605 };
606 
607 template<typename Head, typename... Tail>
608 class _Zip<Head, Tail...> : private _Zip<Tail...> {
609  protected:
611 
612  int _get_size(){
613  int this_size = head->get_value().size();
614  int rest_size = _Zip<Tail...>::_get_size();
615  return std::min(this_size, rest_size);
616  }
617 
618  typename std::tuple<Head,Tail...> _get_at(int idx){
619  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
620  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
621  }
622 
623  std::string _get_name(){
624  return head->get_name()+","+_Zip<Tail...>::_get_name();
625  }
626 
627  public:
628  _Zip() { }
629 
630  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
631  : _Zip<Tail...>(tail...),
632  head(head) { }
633 };
634 
635 namespace impl {
636  std::string zip_fmt_name(){
637  return "";
638  }
639 
640  template<typename Head>
641  std::string zip_fmt_name(Value<std::vector<Head>>* head){
642  return head->get_name();
643  }
644 
645  template<typename Head1, typename Head2, typename... Tail>
646  std::string zip_fmt_name(Value<std::vector<Head1>>* head1, Value<std::vector<Head2>>* head2, Value<std::vector<Tail>>*... tail){
647  return head1->get_name() + "," + zip_fmt_name<Head2, Tail...>(head2, tail...);
648  }
649 }
665 template <typename... ArgTypes>
666 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
667  private _Zip<ArgTypes...>{
668  protected:
669  void update_value(){
670  this->value.clear();
671  int size = _Zip<ArgTypes...>::_get_size();
672  for(int i=0; i<size; i++){
673  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
674  }
675  }
676 
677  public:
678  static std::string fmt_name(Value<std::vector<ArgTypes>>*... args){
679  return "zip("+zip_fmt_name(args...)+")";
680  }
681 
682  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
683  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>(fmt_name(args...), alias),
684  _Zip<ArgTypes...>(args...) { }
685 };
686 
687 template<typename> class Map; // undefined
695 template <typename Ret, typename... ArgTypes>
696 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
697  private:
698  typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
699  Function<Ret(ArgTypes...)>& fn;
700  arg_type* arg;
701 
702  void update_value(){
703  this->value.clear();
704  for(auto tup : arg->get_value()){
705  this->value.push_back(call(fn,tup));
706  }
707  }
708 
709  public:
710  static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, arg_type* arg){
711  return "map("+fn.get_name()+":"+arg->get_name()+")";
712  }
713 
714  Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
715  :DerivedValue<std::vector<Ret>>(fmt_name(fn, arg), alias),
716  fn(fn), arg(arg){ }
717 
718 };
719 
720 template<typename... T> class _Tuple;
721 template<>
722 class _Tuple<> {
723  protected:
724 
725  std::tuple<> _get_value(){
726  return std::make_tuple();
727  }
728 
729  public:
730  _Tuple() { }
731 };
732 
733 template<typename Head, typename... Tail>
734 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
735  protected:
736  Value<Head>* head;
737 
738  typename std::tuple<Head,Tail...> _get_value(){
739  auto tail_tuple = _Tuple<Tail...>::_get_value();
740  return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
741  }
742 
743  public:
744  _Tuple() { }
745 
746  _Tuple(Value<Head>* head, Value<Tail>*... tail)
747  : _Tuple<Tail...>(tail...),
748  head(head) { }
749 };
750 
751 namespace impl {
752  std::string tuple_fmt_name(){
753  return "";
754  }
755 
756  template<typename Head>
757  std::string tuple_fmt_name(Value<Head>* head){
758  return head->get_name();
759  }
760 
761  template<typename Head1, typename Head2, typename... Tail>
762  std::string tuple_fmt_name(Value<Head1>* head1, Value<Head2>* head2, Value<Tail>*... tail){
763  return head1->get_name() + "," + tuple_fmt_name<Head2, Tail...>(head2, tail...);
764  }
765 }
766 
773 template <typename... ArgTypes>
774 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
775  private _Tuple<ArgTypes...>{
776  protected:
777  void update_value(){
778  this->value = _Tuple<ArgTypes...>::_get_value();
779  }
780 
781  public:
782  static std::string fmt_name(Value<ArgTypes>*... args){
783  return "tuple("+impl::tuple_fmt_name(args...)+")";
784  }
785 
786  Tuple(Value<ArgTypes>*... args, const std::string& alias)
787  :DerivedValue<std::tuple<ArgTypes...>>(fmt_name(args...), alias),
788  _Tuple<ArgTypes...>(args...) { }
789 };
790 
794 template <size_t N, typename... ArgTypes>
795 class DeTup : public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
796  Value<std::tuple<ArgTypes...>> tup;
797  protected:
798  void update_value(){
799  this->value = std::get<N>(tup->get_value());
800  }
801 
802  public:
803  static std::string fmt_name(Value<std::tuple<ArgTypes...>>* tup){
804  return "detup("+tup->get_name()+")";
805  }
806 
807  DeTup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias)
808  :DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(fmt_name(tup), alias),
809  tup(tup) { }
810 };
811 
816 template <size_t N, typename... ArgTypes>
817 class DeTupVector : public DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>{
818  Value<std::vector<std::tuple<ArgTypes...>>>* tup;
819  protected:
820  void update_value(){
821  this->value.clear();
822  for( auto& t : tup->get_value()){
823  this->value.push_back(std::get<N>(t));
824  }
825  }
826 
827  public:
828  static std::string fmt_name(Value<std::vector<std::tuple<ArgTypes...>>>* tup){
829  return "detup_vec("+tup->get_name()+")";
830  }
831 
832  DeTupVector(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias)
833  :DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(fmt_name(tup), alias),
834  tup(tup) { }
835 };
836 
837 template<typename> class Apply; // undefined
842 template <typename Ret, typename... ArgTypes>
843 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
844  private:
845  Function<Ret(ArgTypes...)>& fn;
846  Value<std::tuple<ArgTypes...>>* arg;
847 
848  void update_value(){
849  auto &tup = arg->get_value();
850  this->value = call(fn, tup);
851  }
852 
853  public:
854  static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg){
855  return "apply("+fn.get_name()+":"+arg->get_name()+")";
856  }
857 
858  Apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias)
859  :DerivedValue<Ret>(fmt_name(fn,arg), alias),
860  fn(fn), arg(arg){ }
861 
862 };
863 
867 template<typename T>
868 class Count : public DerivedValue<int>{
869  private:
870  Function<bool(T)>& selector;
872 
873  void update_value(){
874  value = 0;
875  for(auto val : v->get_value()){
876  if(selector(val))
877  value++;
878  }
879  }
880 
881  public:
882  static std::string fmt_name(Function<bool(T)>& selector, Value<std::vector<T>>* v){
883  return "count("+selector.get_name()+":"+v->get_name()+")";
884  }
885 
886  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
887  :DerivedValue<int>(fmt_name(selector,v), alias),
888  selector(selector), v(v) { }
889 };
890 
894 template<typename T>
895 class Filter : public DerivedValue<std::vector<T>>{
896  private:
897  Function<bool(T)>& filter;
899 
900  void update_value(){
901  this->value.clear();
902  for(auto val : v->get_value()){
903  if(this->filter(val))
904  this->value.push_back(val);
905  }
906  }
907 
908  public:
909  static std::string fmt_name(Function<bool(T)>& filter, Value<std::vector<T>>* v){
910  return "filter("+filter.get_name()+":"+v->get_name()+")";
911  }
912 
913  Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
914  :DerivedValue<std::vector<T>>(fmt_name(filter,v), alias),
915  filter(filter), v(v) { }
916 };
917 
923 template<typename... ArgTypes>
924 class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
925  private:
926  typedef std::vector<std::tuple<ArgTypes...>> value_type;
927  Function<bool(ArgTypes...)>& filter;
928  Value<value_type>* arg;
929 
930  void update_value(){
931  this->value.clear();
932  for(auto val : arg->get_value()){
933  if(call(filter,val))
934  this->value.push_back(val);
935  }
936  }
937 
938  public:
939  static std::string fmt_name(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg){
940  return "tup_filter("+filter.get_name()+":"+arg->get_name()+")";
941  }
942 
943  TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
944  :DerivedValue<value_type>(fmt_name(filter, arg), alias),
945  filter(filter), arg(arg) { }
946 };
947 
954 template <typename T>
955 class Reduce : public DerivedValue<T>{
956  private:
957  Function<T(std::vector<T>)>& reduce;
958 
959  void update_value(){
960  this->value = reduce(v->get_value());
961  }
962 
963  protected:
965 
966  public:
967  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
968  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
969  reduce(reduce), v(v) { }
970 };
971 
975 template <typename T>
976 class Max : public Reduce<T>{
977  public:
978  static std::string fmt_name(Value<std::vector<T>>* v){
979  return "max("+v->get_name()+")";
980  }
981 
982  Max(Value<std::vector<T>>* v, const std::string alias)
983  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
984  FUNC(([](std::vector<T> vec){
985  return *std::max_element(vec.begin(), vec.end());}))),
986  v, alias) { }
987 };
988 
992 template <typename T>
993 class Min : public Reduce<T>{
994  public:
995  static std::string fmt_name(Value<std::vector<T>>* v){
996  return "min("+v->get_name()+")";
997  }
998 
999  Min(Value<std::vector<T>>* v, const std::string alias)
1000  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
1001  FUNC(([](std::vector<T> vec){
1002  return *std::min_element(vec.begin(), vec.end());}))),
1003  v, alias) { }
1004 };
1005 
1009 template <typename T>
1010 class Mean : public Reduce<T>{
1011  public:
1012  static std::string fmt_name(Value<std::vector<T>>* v){
1013  return "mean("+v->get_name()+")";
1014  }
1015 
1016  Mean(Value<std::vector<T>>* v, const std::string alias)
1017  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
1018  FUNC(([](std::vector<T> vec){
1019  int n = 0; T sum = 0;
1020  for (T e : vec){ n++; sum += e; }
1021  return n>0 ? sum / n : 0; }))),
1022  v, alias) { }
1023 };
1024 
1028 template <typename T>
1029 class Range : public Reduce<T>{
1030  public:
1031  static std::string fmt_name(Value<std::vector<T>>* v){
1032  return "range("+v->get_name()+")";
1033  }
1034 
1035  Range(Value<std::vector<T>>* v, const std::string alias)
1036  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
1037  FUNC(([](std::vector<T> vec){
1038  auto minmax = std::minmax_element(vec.begin(), vec.end());
1039  return (*minmax.second) - (*minmax.first); }))),
1040  v, alias) { }
1041 };
1042 
1046 template <typename T>
1047 class ElementOf : public Reduce<T>{
1048  public:
1049  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
1050  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
1051  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
1052  v, alias) { }
1053 };
1054 
1060 template <typename T>
1061 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
1062  private:
1063  Function<std::pair<T,int>(std::vector<T>)>& reduce;
1064  Value<std::vector<T> >* v;
1065 
1067  this->value = reduce(v->get_value());
1068  }
1069 
1070  public:
1071  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
1072  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
1073  reduce(reduce), v(v) { }
1074 };
1075 
1079 template <typename T>
1080 class MaxIndex : public ReduceIndex<T>{
1081  public:
1082  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
1083  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
1084  FUNC(([](std::vector<T> vec){
1085  auto elptr = std::max_element(vec.begin(), vec.end());
1086  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1087  v, alias) { }
1088 };
1089 
1093 template <typename T>
1094 class MinIndex : public ReduceIndex<T>{
1095  public:
1096  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
1097  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
1098  FUNC(([](std::vector<T> vec){
1099  auto elptr = std::min_element(vec.begin(), vec.end());
1100  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1101  v, alias) { }
1102 };
1103 
1107 template <typename T, int Size>
1108 class Combinations : public DerivedValue<std::vector<typename HomoTuple<T,Size>::type>>{
1109  private:
1110  Value<std::vector<T>>* val;
1111  typedef typename HomoTuple<T,Size>::type tuple_type;
1112 
1114  auto& v = val->get_value();
1115  int data_size = v.size();
1116  this->value.clear();
1117 
1118  std::vector<bool> selector(data_size);
1119  std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}), true);
1120  do {
1121  std::array<T, Size> perm;
1122  int idx = 0;
1123  for (int i=0; i<data_size; i++){
1124  if (selector[i]){
1125  perm[idx] = v[i];
1126  idx++;
1127  if (idx == Size) break;
1128  }
1129  }
1130  this->value.push_back(a2t(perm));
1131  } while(std::prev_permutation(selector.begin(), selector.end()));
1132  }
1133 
1134  public:
1135  static std::string fmt_name(Value<std::vector<T>>* val){
1136  std::stringstream ss;
1137  ss << "combinations(" << Size << "," << val->get_name() << ")";
1138  return ss.str();
1139  }
1140 
1141  Combinations(Value<std::vector<T>>* val, const std::string alias="")
1142  :DerivedValue<std::vector<tuple_type>>(fmt_name(val), alias),
1143  val(val) { }
1144 
1145 };
1146 
1150 template <typename FST, typename SND>
1151 class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
1152  private:
1153  Value<std::vector<FST>>* val1;
1154  Value<std::vector<SND>>* val2;
1155 
1157  this->value.clear();
1158  auto& v1 = val1->get_value();
1159  auto& v2 = val2->get_value();
1160  for(int i=0; i<v1.size(); i++){
1161  for(int j=0; j<v2.size(); j++){
1162  this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1163  }
1164  }
1165  }
1166 
1167  static std::string calc_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1168  std::stringstream ss;
1169  ss << "cartProduct("
1170  << val1->get_name() << ", " << val2->get_name()
1171  << ")";
1172  return ss.str();
1173  }
1174 
1175  public:
1176  static std::string fmt_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1177  return "cartProduct("+val1->get_name()+", "+val2->get_name()+")";
1178  }
1179 
1180  CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
1181  :DerivedValue<std::vector<std::tuple<FST,SND>>>(calc_name(val1, val2), alias),
1182  val1(val1), val2(val2) { }
1183 };
1184 
1190 template <typename T>
1191 class BoundValue : public DerivedValue<T>{
1192  protected:
1193  Function<T()>& f;
1195  this->value = f();
1196  }
1197  public:
1198  BoundValue(Function<T()>& f, const std::string alias="")
1199  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
1200  f(f) { }
1201 };
1202 
1207 template <typename T>
1208 class PointerValue : public DerivedValue<T*>{
1209  protected:
1210  void update_value(){ }
1211 
1212  public:
1213  PointerValue(const std::string& name, T* ptr, const std::string alias="")
1214  :DerivedValue<T*>(name, alias){
1215  this->value = ptr;
1216  }
1217 };
1218 
1222 template <typename T>
1223 class ConstantValue : public DerivedValue<T>{
1224  protected:
1225  void update_value(){ }
1226 
1227  public:
1228  ConstantValue(const std::string& name, T const_value, const std::string alias="")
1229  :DerivedValue<T>("const::"+name, alias),
1230  Value<T>::value(const_value) { }
1231 };
1232 }
1233 #endif // value_hpp
void update_value()
Updates the internal value.
Definition: value.hpp:1113
void update_value()
Updates the internal value.
Definition: value.hpp:1194
Find and return the maximum value of a vector.
Definition: value.hpp:976
Zips a series of vectors together.
Definition: value.hpp:666
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:955
void update_value()
Updates the internal value.
Definition: value.hpp:873
void update_value()
Updates the internal value.
Definition: value.hpp:571
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1094
Find combinations of items from an input vector.
Definition: value.hpp:1108
A generic value owning only a function object.
Definition: value.hpp:1191
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:516
Calculate the range of the values in a vector.
Definition: value.hpp:1029
void update_value()
Updates the internal value.
Definition: value.hpp:820
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:774
A std::vector wrapper around a C-style array.
Definition: value.hpp:543
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:1061
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:868
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1080
void update_value()
Updates the internal value.
Definition: value.hpp:959
Parent class to all Function classes.
Definition: value.hpp:143
void update_value()
Updates the internal value.
Definition: value.hpp:777
void update_value()
Updates the internal value.
Definition: value.hpp:930
A value supplied by the dataset, not derived.
Definition: value.hpp:448
Returns the elements in a vector that pass a test function.
Definition: value.hpp:895
Gets the Nth element from a tuple value.
Definition: value.hpp:795
Find and return the minimum value of a vector.
Definition: value.hpp:993
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:817
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:568
decltype(auto) a2t(const std::array< T, N > &a)
Converts a std::vector to a std::tuple.
Definition: value.hpp:94
void update_value()
Updates the internal value.
Definition: value.hpp:848
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:467
void update_value()
Updates the internal value.
Definition: value.hpp:1066
void update_value()
Updates the internal value.
Definition: value.hpp:702
void update_value()
Updates the internal value.
Definition: value.hpp:1225
The namespace containing all filval classes and functions.
Definition: api.hpp:38
Extract the element at a specific index from a vector.
Definition: value.hpp:1047
Returns the elements in a vector that pass a test function.
Definition: value.hpp:924
Calculate the mean value of a vector.
Definition: value.hpp:1010
void update_value()
Updates the internal value.
Definition: value.hpp:548
A templated value.
Definition: value.hpp:415
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1151
void update_value()
Updates the internal value.
Definition: value.hpp:1156
void update_value()
Updates the internal value.
Definition: value.hpp:669
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:176
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:493
void update_value()
Updates the internal value.
Definition: value.hpp:900
void update_value()
Updates the internal value.
Definition: value.hpp:1210
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:1223
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:155
A Value of a pointer.
Definition: value.hpp:1208
void update_value()
Updates the internal value.
Definition: value.hpp:798