TTTT Analysis  0.1
value.hpp
Go to the documentation of this file.
1 
42 #ifndef value_hpp
43 #define value_hpp
44 #include <algorithm>
45 #include <functional>
46 #include <initializer_list>
47 #include <iomanip>
48 #include <iostream>
49 #include <limits>
50 #include <map>
51 #include <sstream>
52 #include <tuple>
53 #include <typeindex>
54 #include <utility>
55 #include <vector>
56 
57 #include "log.hpp"
58 
62 namespace fv{
63 
64 namespace detail {
65  template<typename T, int N, bool Done, typename... TYPES>
66  struct _HomoTuple {
67  typedef _HomoTuple<T, N, sizeof...(TYPES)+1==N, TYPES..., T> stype;
68  typedef typename stype::type type;
69  };
70 
71  template<typename T, int N, typename... TYPES>
72  struct _HomoTuple<T, N, true, TYPES...> {
73  typedef std::tuple<TYPES...> type;
74  };
75 }
76 
77 template<typename T, int N>
78 struct HomoTuple {
79  typedef detail::_HomoTuple<T, N, N==0> stype;
80  typedef typename stype::type type;
81 };
82 
83 namespace detail {
84  // Convert array into a tuple
85  template<typename Array, std::size_t... I>
86  decltype(auto) a2t_impl(const Array& a, std::index_sequence<I...>){
87  return std::make_tuple(a[I]...);
88  }
89 }
90 
94 template<typename T, std::size_t N, typename Indices = std::make_index_sequence<N>>
95 decltype(auto) a2t(const std::array<T, N>& a){
96  return detail::a2t_impl(a, Indices());
97 }
98 
99 namespace detail {
100  // Convert tuple into a vector
101  template<typename R, typename Tuple, std::size_t... Is>
102  decltype(auto) t2v_impl(const Tuple& t, std::index_sequence<Is...>){
103  /* return std::make_tuple(a[I]...); */
104  return std::vector<R>({std::get<Is>(t)...});
105  }
106 }
107 
111 template<typename R, typename... ArgTypes>
112 std::vector<R> t2v(const std::tuple<ArgTypes...>& t){
113  return detail::t2v_impl<R, std::tuple<ArgTypes...>>(t, std::index_sequence_for<ArgTypes...>{});
114 }
115 
116 namespace detail {
117  template <class F, class Tuple, std::size_t... I>
118  constexpr decltype(auto) call_impl(F &&f, Tuple &&t, std::index_sequence<I...>){
119  return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
120  }
121 }
122 
126 template <class F, class Tuple>
127 constexpr decltype(auto) call(F &&f, Tuple &&t){
128  return detail::call_impl(
129  std::forward<F>(f), std::forward<Tuple>(t),
130  std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
131 }
132 
133 template<typename> class Function; // undefined
134 
139 class GenFunction {
140  private:
141  std::string name;
142  std::string impl;
143  protected:
144  inline static bool in_register_function=false;
145 
146  public:
151  inline static std::map<const std::string, GenFunction*> function_registry;
152 
153  GenFunction(const std::string& name, const std::string& impl)
154  :name(name),
155  impl(impl){ }
156 
157  virtual ~GenFunction() { };
158 
159  std::string& get_name(){
160  return name;
161  }
162 
163  std::string& get_impl(){
164  return impl;
165  }
166 
172  static std::string format_code(const std::string& code){
173  std::stringstream code_out("");
174  std::string command("echo \""+code+"\" | clang-format");
175  char buffer[255];
176  FILE *stream = popen(command.c_str(), "r");
177  while (fgets(buffer, 255, stream) != NULL)
178  code_out << buffer;
179  if (pclose(stream) == 0)
180  return code_out.str();
181  else
182  return code;
183  }
184 
185  static std::string summary(){
186  std::stringstream ss;
187  ss << "The following functions have been registered" << std::endl;
188  for(auto p : function_registry){
189  if (p.second == nullptr) continue;
190  ss << "FUNCTION::" << p.second->name << "@" << p.second << std::endl;
191  ss << format_code(p.second->impl);
192  }
193  return ss.str();
194  }
195 
196  template <typename T>
197  static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
198  in_register_function = true;
199  Function<T>* func;
200  if (GenFunction::function_registry[name] != nullptr){
201  func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
202  if (func == nullptr){
203  ERROR("Trying to register function which has already been registered with a different type");
204  }
205  } else {
206  func = new Function<T>(name, impl, f);
207  GenFunction::function_registry[name] = func;
208  }
209  in_register_function = false;
210  return *func;
211  }
212 
213  template <typename T>
214  static Function<T>& lookup_function(const std::string& name){
215  if (GenFunction::function_registry[name] == nullptr){
216  CRITICAL("Function \"" << name << "\" not previously registered", -1);
217  } else {
218  Function<T>* func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
219  if (func == nullptr){
220  CRITICAL("Function \"" << name << "\" request and register have mismatched types", -1);
221  }
222  return *GenFunction::function_registry[name];
223  }
224  }
225 };
226 
227 
239 template <typename R, typename... ArgTypes>
240 class Function<R(ArgTypes...)> : public GenFunction {
241  private:
242  std::function<R(ArgTypes...)> f;
243 
244  public:
245  Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
246  :GenFunction(name, impl), f(f){
247  if (!in_register_function) {
248  WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
249  }
250  }
251  Function(const std::string& name, std::function<R(ArgTypes...)> f)
252  :Function(name, "N/A", f){ }
253  ~Function() { }
254 
255  R operator()(ArgTypes ...args){
256  return f(args...);
257  }
258 
259 };
260 
261 
262 #define FUNC(f) f, #f
263 
264 template <typename T>
265 class Value;
272 class GenValue;
273 typedef std::map<std::string, GenValue*> ValueSet;
274 class GenValue{
275  private:
281  std::string name;
282 
283  protected:
290  bool value_valid;
291 
292  void _reset(){
293  this->value_valid = false;
294  }
295 
303  inline static std::map<std::pair<const std::type_index, const std::string>, GenValue*> values;
304 
312  inline static std::map<std::pair<const std::type_index, const std::string>, GenValue*> aliases;
313 
314  bool logging_enabled;
315 
316  public:
317  GenValue(const std::type_index&& ti, const std::string& name, const std::string& alias)
318  :name(name), value_valid(false), logging_enabled(false){
319  if (alias != "")
320  INFO("Registered value: \"" << name << "\" with alias: \"" << alias << "\"");
321  else
322  INFO("Registered value: \"" << name);
323  values[std::make_pair(ti,name)] = this;
324  if (alias != "")
325  GenValue::alias(ti, alias, this);
326  }
327 
328  const std::string& get_name(){
329  return name;
330  }
331 
332 
339  virtual void log() = 0;
340 
341  static void reset(){
342  for (auto val : values){
343  if (val.second != nullptr){
344  val.second->_reset();
345  }
346  }
347  }
348 
349  template<typename T>
350  static Value<T>* get_value(const std::string& name){
351  const std::type_index& ti = typeid(T);
352  auto lookup_id = std::make_pair(ti,name);
353  if (aliases[lookup_id] != nullptr)
354  return (Value<T>*)aliases[lookup_id];
355  else
356  return (Value<T>*)values[lookup_id];
357  }
358 
359 
360  static void alias(const std::type_index& ti, const std::string& name, GenValue* value){
361  auto lookup_id = std::make_pair(ti,name);
362  if (aliases[lookup_id] != nullptr){
363  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
364  }
365  aliases[lookup_id] = value;
366  }
367 
368  template<typename T>
369  static void alias(const std::string& name, Value<T>* value){
370  alias(typeid(T), name, value);
371  }
372 
373  static std::string summary(){
374  std::stringstream ss;
375  ss << "The following values have been created:" << std::endl;
376  for (auto item : values){
377  auto& key = item.first;
378  auto& value = item.second;
379  if (value == nullptr) continue;
380  ss << "\tVALUE::\"" << key.second << "\" at address " << value << std::endl;
381  }
382  ss << "And these aliases:" << std::endl;
383  for (auto item : aliases){
384  auto& key = item.first;
385  auto& value = item.second;
386  std::string orig("VOID");
387  if (value == nullptr) continue;
388  for (auto v_item : values){
389  auto& v_value = v_item.second;
390  if (v_value == value){
391  orig = v_value->get_name();
392  break;
393  }
394  }
395  ss << "\tALIAS::\"" << key.second << "\" referring to \"" << orig << "\"" << std::endl;
396  }
397  return ss.str();
398  }
399  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
400 };
401 std::ostream& operator<<(std::ostream& os, GenValue& gv){
402  os << gv.get_name();
403  return os;
404 }
405 
406 
416 template <typename T>
417 class Value : public GenValue{
418  protected:
419  std::function<std::string(T)> value_to_string;
420 
421  public:
422  Value(const std::string& name, const std::string& alias="")
423  :value_to_string([](T){return "";}),
424  GenValue(typeid(T), name, alias){ }
427  virtual T& get_value() = 0;
428 
429  void enable_logging(const std::function<std::string(T)>& value_to_string = [](T){return "";}){
430  logging_enabled = true;
431  this->value_to_string = value_to_string;
432  }
433 
434  void disable_logging(){
435  logging_enabled = false;
436  }
437 };
438 
439 
449 template <typename T>
450 class ObservedValue : public Value<T>{
451  private:
452  T *val_ref;
453 
454  public:
455  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
456  :Value<T>(name, alias),
457  val_ref(val_ref){ }
458 
459  void log(){
460  if(this->logging_enabled){
461  INFO(this->get_name() << ": " << this->value_to_string(*val_ref));
462  }
463  }
464 
465  static std::string fmt_name(const std::string& name){
466  return name;
467  }
468 
469  T& get_value(){
470  if (!this->value_valid){
471  this->value_valid = true;
472  this->log();
473  }
474  return *val_ref;
475  }
476 };
477 
478 
494 template <typename T>
495 class DerivedValue : public Value<T>{
496  protected:
497  T value;
498 
507  virtual void update_value() = 0;
508  public:
509  DerivedValue(const std::string& name, const std::string& alias="")
510  :Value<T>(name, alias){ }
511 
512  void log(){
513  if(this->logging_enabled){
514  INFO(this->get_name() << ": " << this->value_to_string(value));
515  }
516  }
517 
518  T& get_value(){
519  if (!this->value_valid){
520  update_value();
521  this->value_valid = true;
522  this->log();
523  }
524  return value;
525  }
526 };
527 
528 
538 template <typename T>
539 class WrapperVector : public DerivedValue<std::vector<T> >{
540  private:
541  Value<int>* size;
542  Value<T*>* data;
543 
544  void update_value(){
545  int n = size->get_value();
546  T* data_ref = data->get_value();
547  this->value.assign(data_ref, data_ref+n);
548  }
549 
550  public:
551  static std::string fmt_name(Value<int>* size, Value<T*>* data){
552  return "wrapper_vector("+size->get_name()+","+data->get_name()+")";
553  }
554 
555  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
556  :DerivedValue<std::vector<T> >(fmt_name(size,data), alias),
557  size(size), data(data){ }
558 };
559 
563 template <typename T1, typename T2>
564 class Pair : public DerivedValue<std::pair<T1, T2> >{
565  protected:
566  std::pair<Value<T1>*, Value<T2>* > value_pair;
567  void update_value(){
568  this->value.first = value_pair.first->get_value();
569  this->value.second = value_pair.second->get_value();
570  }
571 
572  public:
573  static std::string fmt_name(Value<T1> *value1, Value<T2> *value2){
574  return "pair("+value1->get_name()+","+value2->get_name()+")";
575  }
576 
577  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
578  :DerivedValue<std::pair<T1, T2> >(fmt_name(value1, value2), alias),
579  value_pair(value1, value2){ }
580 };
581 
582 template<typename... T> class _Zip;
583 template<>
584 class _Zip<> {
585  protected:
586 
587  int _get_size(){
588  return std::numeric_limits<int>::max();
589  }
590 
591  std::tuple<> _get_at(int){
592  return std::make_tuple();
593  }
594 
595  std::string _get_name(){
596  return "";
597  }
598 
599  public:
600  _Zip() { }
601 };
602 
603 template<typename Head, typename... Tail>
604 class _Zip<Head, Tail...> : private _Zip<Tail...> {
605  protected:
607 
608  int _get_size(){
609  int this_size = head->get_value().size();
610  int rest_size = _Zip<Tail...>::_get_size();
611  return std::min(this_size, rest_size);
612  }
613 
614  typename std::tuple<Head,Tail...> _get_at(int idx){
615  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
616  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
617  }
618 
619  std::string _get_name(){
620  return head->get_name()+","+_Zip<Tail...>::_get_name();
621  }
622 
623  public:
624  _Zip() { }
625 
626  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
627  : _Zip<Tail...>(tail...),
628  head(head) { }
629 };
630 
631 namespace impl {
632  std::string zip_fmt_name(){
633  return "";
634  }
635 
636  template<typename Head>
637  std::string zip_fmt_name(Value<std::vector<Head>>* head){
638  return head->get_name();
639  }
640 
641  template<typename Head1, typename Head2, typename... Tail>
642  std::string zip_fmt_name(Value<std::vector<Head1>>* head1, Value<std::vector<Head2>>* head2, Value<std::vector<Tail>>*... tail){
643  return head1->get_name() + "," + zip_fmt_name<Head2, Tail...>(head2, tail...);
644  }
645 }
661 template <typename... ArgTypes>
662 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
663  private _Zip<ArgTypes...>{
664  protected:
665  void update_value(){
666  this->value.clear();
667  int size = _Zip<ArgTypes...>::_get_size();
668  for(int i=0; i<size; i++){
669  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
670  }
671  }
672 
673  public:
674  static std::string fmt_name(Value<std::vector<ArgTypes>>*... args){
675  return "zip("+zip_fmt_name(args...)+")";
676  }
677 
678  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
679  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>(fmt_name(args...), alias),
680  _Zip<ArgTypes...>(args...) { }
681 };
682 
683 template<typename> class Map; // undefined
691 template <typename Ret, typename... ArgTypes>
692 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
693  private:
694  typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
695  Function<Ret(ArgTypes...)>& fn;
696  arg_type* arg;
697 
698  void update_value(){
699  this->value.clear();
700  for(auto tup : arg->get_value()){
701  this->value.push_back(call(fn,tup));
702  }
703  }
704 
705  public:
706  static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, arg_type* arg){
707  return "map("+fn.get_name()+":"+arg->get_name()+")";
708  }
709 
710  Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
711  :DerivedValue<std::vector<Ret>>(fmt_name(fn, arg), alias),
712  fn(fn), arg(arg){ }
713 
714 };
715 
716 template<typename... T> class _Tuple;
717 template<>
718 class _Tuple<> {
719  protected:
720 
721  std::tuple<> _get_value(){
722  return std::make_tuple();
723  }
724 
725  public:
726  _Tuple() { }
727 };
728 
729 template<typename Head, typename... Tail>
730 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
731  protected:
732  Value<Head>* head;
733 
734  typename std::tuple<Head,Tail...> _get_value(){
735  auto tail_tuple = _Tuple<Tail...>::_get_value();
736  return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
737  }
738 
739  public:
740  _Tuple() { }
741 
742  _Tuple(Value<Head>* head, Value<Tail>*... tail)
743  : _Tuple<Tail...>(tail...),
744  head(head) { }
745 };
746 
747 namespace impl {
748  std::string tuple_fmt_name(){
749  return "";
750  }
751 
752  template<typename Head>
753  std::string tuple_fmt_name(Value<Head>* head){
754  return head->get_name();
755  }
756 
757  template<typename Head1, typename Head2, typename... Tail>
758  std::string tuple_fmt_name(Value<Head1>* head1, Value<Head2>* head2, Value<Tail>*... tail){
759  return head1->get_name() + "," + tuple_fmt_name<Head2, Tail...>(head2, tail...);
760  }
761 }
762 
769 template <typename... ArgTypes>
770 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
771  private _Tuple<ArgTypes...>{
772  protected:
773  void update_value(){
774  this->value = _Tuple<ArgTypes...>::_get_value();
775  }
776 
777  public:
778  static std::string fmt_name(Value<ArgTypes>*... args){
779  return "tuple("+impl::tuple_fmt_name(args...)+")";
780  }
781 
782  Tuple(Value<ArgTypes>*... args, const std::string& alias)
783  :DerivedValue<std::tuple<ArgTypes...>>(fmt_name(args...), alias),
784  _Tuple<ArgTypes...>(args...) { }
785 };
786 
790 template <size_t N, typename... ArgTypes>
791 class DeTup : public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
792  Value<std::tuple<ArgTypes...>> tup;
793  protected:
794  void update_value(){
795  this->value = std::get<N>(tup->get_value());
796  }
797 
798  public:
799  static std::string fmt_name(Value<std::tuple<ArgTypes...>>* tup){
800  return "detup("+tup->get_name()+")";
801  }
802 
803  DeTup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias)
804  :DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(fmt_name(tup), alias),
805  tup(tup) { }
806 };
807 
812 template <size_t N, typename... ArgTypes>
813 class DeTupVector : public DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>{
814  Value<std::vector<std::tuple<ArgTypes...>>>* tup;
815  protected:
816  void update_value(){
817  this->value.clear();
818  for( auto& t : tup->get_value()){
819  this->value.push_back(std::get<N>(t));
820  }
821  }
822 
823  public:
824  static std::string fmt_name(Value<std::vector<std::tuple<ArgTypes...>>>* tup){
825  return "detup_vec("+tup->get_name()+")";
826  }
827 
828  DeTupVector(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias)
829  :DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(fmt_name(tup), alias),
830  tup(tup) { }
831 };
832 
833 template<typename> class Apply; // undefined
838 template <typename Ret, typename... ArgTypes>
839 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
840  private:
841  Function<Ret(ArgTypes...)>& fn;
842  Value<std::tuple<ArgTypes...>>* arg;
843 
844  void update_value(){
845  auto &tup = arg->get_value();
846  this->value = call(fn, tup);
847  }
848 
849  public:
850  static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg){
851  return "apply("+fn.get_name()+":"+arg->get_name()+")";
852  }
853 
854  Apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias)
855  :DerivedValue<Ret>(fmt_name(fn,arg), alias),
856  fn(fn), arg(arg){ }
857 
858 };
859 
863 template<typename T>
864 class Count : public DerivedValue<int>{
865  private:
866  Function<bool(T)>& selector;
868 
869  void update_value(){
870  value = 0;
871  for(auto val : v->get_value()){
872  if(selector(val))
873  value++;
874  }
875  }
876 
877  public:
878  static std::string fmt_name(Function<bool(T)>& selector, Value<std::vector<T>>* v){
879  return "count("+selector.get_name()+":"+v->get_name()+")";
880  }
881 
882  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
883  :DerivedValue<int>(fmt_name(selector,v), alias),
884  selector(selector), v(v) { }
885 };
886 
890 template<typename T>
891 class Filter : public DerivedValue<std::vector<T>>{
892  private:
893  Function<bool(T)>& filter;
895 
896  void update_value(){
897  this->value.clear();
898  for(auto val : v->get_value()){
899  if(this->filter(val))
900  this->value.push_back(val);
901  }
902  }
903 
904  public:
905  static std::string fmt_name(Function<bool(T)>& filter, Value<std::vector<T>>* v){
906  return "filter("+filter.get_name()+":"+v->get_name()+")";
907  }
908 
909  Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
910  :DerivedValue<std::vector<T>>(fmt_name(filter,v), alias),
911  filter(filter), v(v) { }
912 };
913 
919 template<typename... ArgTypes>
920 class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
921  private:
922  typedef std::vector<std::tuple<ArgTypes...>> value_type;
923  Function<bool(ArgTypes...)>& filter;
924  Value<value_type>* arg;
925 
926  void update_value(){
927  this->value.clear();
928  for(auto val : arg->get_value()){
929  if(call(filter,val))
930  this->value.push_back(val);
931  }
932  }
933 
934  public:
935  static std::string fmt_name(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg){
936  return "tup_filter("+filter.get_name()+":"+arg->get_name()+")";
937  }
938 
939  TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
940  :DerivedValue<value_type>(fmt_name(filter, arg), alias),
941  filter(filter), arg(arg) { }
942 };
943 
950 template <typename T>
951 class Reduce : public DerivedValue<T>{
952  private:
953  Function<T(std::vector<T>)>& reduce;
954 
955  void update_value(){
956  this->value = reduce(v->get_value());
957  }
958 
959  protected:
961 
962  public:
963  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
964  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
965  reduce(reduce), v(v) { }
966 };
967 
971 template <typename T>
972 class Max : public Reduce<T>{
973  public:
974  static std::string fmt_name(Value<std::vector<T>>* v){
975  return "max("+v->get_name()+")";
976  }
977 
978  Max(Value<std::vector<T>>* v, const std::string alias)
979  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
980  FUNC(([](std::vector<T> vec){
981  return *std::max_element(vec.begin(), vec.end());}))),
982  v, alias) { }
983 };
984 
988 template <typename T>
989 class Min : public Reduce<T>{
990  public:
991  static std::string fmt_name(Value<std::vector<T>>* v){
992  return "min("+v->get_name()+")";
993  }
994 
995  Min(Value<std::vector<T>>* v, const std::string alias)
996  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
997  FUNC(([](std::vector<T> vec){
998  return *std::min_element(vec.begin(), vec.end());}))),
999  v, alias) { }
1000 };
1001 
1005 template <typename T>
1006 class Mean : public Reduce<T>{
1007  public:
1008  static std::string fmt_name(Value<std::vector<T>>* v){
1009  return "mean("+v->get_name()+")";
1010  }
1011 
1012  Mean(Value<std::vector<T>>* v, const std::string alias)
1013  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
1014  FUNC(([](std::vector<T> vec){
1015  int n = 0; T sum = 0;
1016  for (T e : vec){ n++; sum += e; }
1017  return n>0 ? sum / n : 0; }))),
1018  v, alias) { }
1019 };
1020 
1024 template <typename T>
1025 class Range : public Reduce<T>{
1026  public:
1027  static std::string fmt_name(Value<std::vector<T>>* v){
1028  return "range("+v->get_name()+")";
1029  }
1030 
1031  Range(Value<std::vector<T>>* v, const std::string alias)
1032  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
1033  FUNC(([](std::vector<T> vec){
1034  auto minmax = std::minmax_element(vec.begin(), vec.end());
1035  return (*minmax.second) - (*minmax.first); }))),
1036  v, alias) { }
1037 };
1038 
1042 template <typename T>
1043 class ElementOf : public Reduce<T>{
1044  public:
1045  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
1046  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
1047  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
1048  v, alias) { }
1049 };
1050 
1056 template <typename T>
1057 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
1058  private:
1059  Function<std::pair<T,int>(std::vector<T>)>& reduce;
1060  Value<std::vector<T> >* v;
1061 
1063  this->value = reduce(v->get_value());
1064  }
1065 
1066  public:
1067  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
1068  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
1069  reduce(reduce), v(v) { }
1070 };
1071 
1075 template <typename T>
1076 class MaxIndex : public ReduceIndex<T>{
1077  public:
1078  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
1079  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
1080  FUNC(([](std::vector<T> vec){
1081  auto elptr = std::max_element(vec.begin(), vec.end());
1082  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1083  v, alias) { }
1084 };
1085 
1089 template <typename T>
1090 class MinIndex : public ReduceIndex<T>{
1091  public:
1092  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
1093  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
1094  FUNC(([](std::vector<T> vec){
1095  auto elptr = std::min_element(vec.begin(), vec.end());
1096  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1097  v, alias) { }
1098 };
1099 
1103 template <typename T, int Size>
1104 class Combinations : public DerivedValue<std::vector<typename HomoTuple<T,Size>::type>>{
1105  private:
1106  Value<std::vector<T>>* val;
1107  typedef typename HomoTuple<T,Size>::type tuple_type;
1108 
1110  auto& v = val->get_value();
1111  int data_size = v.size();
1112  this->value.clear();
1113 
1114  std::vector<bool> selector(data_size);
1115  std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}), true);
1116  do {
1117  std::array<T, Size> perm;
1118  int idx = 0;
1119  for (int i=0; i<data_size; i++){
1120  if (selector[i]){
1121  perm[idx] = v[i];
1122  idx++;
1123  if (idx == Size) break;
1124  }
1125  }
1126  this->value.push_back(a2t(perm));
1127  } while(std::prev_permutation(selector.begin(), selector.end()));
1128  }
1129 
1130  public:
1131  static std::string fmt_name(Value<std::vector<T>>* val){
1132  std::stringstream ss;
1133  ss << "combinations(" << Size << "," << val->get_name() << ")";
1134  return ss.str();
1135  }
1136 
1137  Combinations(Value<std::vector<T>>* val, const std::string alias="")
1138  :DerivedValue<std::vector<tuple_type>>(fmt_name(val), alias),
1139  val(val) { }
1140 
1141 };
1142 
1146 template <typename FST, typename SND>
1147 class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
1148  private:
1149  Value<std::vector<FST>>* val1;
1150  Value<std::vector<SND>>* val2;
1151 
1153  this->value.clear();
1154  auto& v1 = val1->get_value();
1155  auto& v2 = val2->get_value();
1156  for(int i=0; i<v1.size(); i++){
1157  for(int j=0; j<v2.size(); j++){
1158  this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1159  }
1160  }
1161  }
1162 
1163  static std::string calc_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1164  std::stringstream ss;
1165  ss << "cartProduct("
1166  << val1->get_name() << ", " << val2->get_name()
1167  << ")";
1168  return ss.str();
1169  }
1170 
1171  public:
1172  static std::string fmt_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1173  return "cartProduct("+val1->get_name()+", "+val2->get_name()+")";
1174  }
1175 
1176  CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
1177  :DerivedValue<std::vector<std::tuple<FST,SND>>>(calc_name(val1, val2), alias),
1178  val1(val1), val2(val2) { }
1179 };
1180 
1186 template <typename T>
1187 class BoundValue : public DerivedValue<T>{
1188  protected:
1189  Function<T()>& f;
1191  this->value = f();
1192  }
1193 
1194  public:
1195  static std::string fmt_name(Function<T()> f){
1196  return f.get_name()+"(<bound>)";
1197  }
1198 
1199  BoundValue(Function<T()>& f, const std::string alias="")
1200  :DerivedValue<T>(fmt_name(f), alias),
1201  f(f) { }
1202 };
1203 
1208 template <typename T>
1209 class PointerValue : public DerivedValue<T*>{
1210  protected:
1211  void update_value(){ }
1212 
1213  public:
1214  PointerValue(const std::string& name, T* ptr, const std::string alias="")
1215  :DerivedValue<T*>(name, alias){
1216  this->value = ptr;
1217  }
1218 };
1219 
1223 template <typename T>
1224 class ConstantValue : public DerivedValue<T>{
1225  protected:
1226  void update_value(){ }
1227 
1228  public:
1229  static std::string fmt_name(const std::string& name){
1230  return "const::"+name;
1231  }
1232  ConstantValue(const std::string& name, T const_value, const std::string alias="")
1233  :DerivedValue<T>(fmt_name(name), alias) {
1234  this->value = const_value;
1235  }
1236 };
1237 }
1238 #endif // value_hpp
void update_value()
Updates the internal value.
Definition: value.hpp:1109
void update_value()
Updates the internal value.
Definition: value.hpp:1190
Find and return the maximum value of a vector.
Definition: value.hpp:972
Zips a series of vectors together.
Definition: value.hpp:662
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:951
void update_value()
Updates the internal value.
Definition: value.hpp:869
void update_value()
Updates the internal value.
Definition: value.hpp:567
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1090
Find combinations of items from an input vector.
Definition: value.hpp:1104
A generic value owning only a function object.
Definition: value.hpp:1187
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:518
Calculate the range of the values in a vector.
Definition: value.hpp:1025
void update_value()
Updates the internal value.
Definition: value.hpp:816
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:770
A std::vector wrapper around a C-style array.
Definition: value.hpp:539
STL namespace.
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:1057
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:864
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1076
void update_value()
Updates the internal value.
Definition: value.hpp:955
Parent class to all Function classes.
Definition: value.hpp:139
void update_value()
Updates the internal value.
Definition: value.hpp:773
void update_value()
Updates the internal value.
Definition: value.hpp:926
A value supplied by the dataset, not derived.
Definition: value.hpp:450
Returns the elements in a vector that pass a test function.
Definition: value.hpp:891
Gets the Nth element from a tuple value.
Definition: value.hpp:791
Find and return the minimum value of a vector.
Definition: value.hpp:989
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:813
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:564
decltype(auto) a2t(const std::array< T, N > &a)
Converts a std::array to a std::tuple.
Definition: value.hpp:95
void update_value()
Updates the internal value.
Definition: value.hpp:844
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:469
void update_value()
Updates the internal value.
Definition: value.hpp:1062
void update_value()
Updates the internal value.
Definition: value.hpp:698
void update_value()
Updates the internal value.
Definition: value.hpp:1226
The namespace containing all filval classes and functions.
Definition: api.hpp:46
Extract the element at a specific index from a vector.
Definition: value.hpp:1043
decltype(auto) constexpr call(F &&f, Tuple &&t)
Call a function f with the elements of the tuple t as arguments.
Definition: value.hpp:127
Returns the elements in a vector that pass a test function.
Definition: value.hpp:920
Calculate the mean value of a vector.
Definition: value.hpp:1006
void update_value()
Updates the internal value.
Definition: value.hpp:544
A templated value.
Definition: value.hpp:265
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1147
void update_value()
Updates the internal value.
Definition: value.hpp:1152
void update_value()
Updates the internal value.
Definition: value.hpp:665
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:172
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:495
void update_value()
Updates the internal value.
Definition: value.hpp:896
void update_value()
Updates the internal value.
Definition: value.hpp:1211
std::vector< R > t2v(const std::tuple< ArgTypes... > &t)
Converts a std::tuple to a std::vector.
Definition: value.hpp:112
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:1224
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:151
A Value of a pointer.
Definition: value.hpp:1209
void update_value()
Updates the internal value.
Definition: value.hpp:794