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->logging_enabled){ */
520  /* std::cout << "Getting value for " << this->get_name() << std::endl; */
521  /* } */
522  if (!this->value_valid){
523  /* if (this->logging_enabled){ */
524  /* std::cout << "Updating value for " << this->get_name() << std::endl; */
525  /* } */
526  update_value();
527  this->value_valid = true;
528  this->log();
529  }
530  return value;
531  }
532 };
533 
534 
544 template <typename T>
545 class WrapperVector : public DerivedValue<std::vector<T> >{
546  private:
547  Value<int>* size;
548  Value<T*>* data;
549 
550  void update_value(){
551  int n = size->get_value();
552  T* data_ref = data->get_value();
553  this->value.assign(data_ref, data_ref+n);
554  }
555 
556  public:
557  static std::string fmt_name(Value<int>* size, Value<T*>* data){
558  return "wrapper_vector("+size->get_name()+","+data->get_name()+")";
559  }
560 
561  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
562  :DerivedValue<std::vector<T> >(fmt_name(size,data), alias),
563  size(size), data(data){ }
564 };
565 
569 template <typename T1, typename T2>
570 class Pair : public DerivedValue<std::pair<T1, T2> >{
571  protected:
572  std::pair<Value<T1>*, Value<T2>* > value_pair;
573  void update_value(){
574  this->value.first = value_pair.first->get_value();
575  this->value.second = value_pair.second->get_value();
576  }
577 
578  public:
579  static std::string fmt_name(Value<T1> *value1, Value<T2> *value2){
580  return "pair("+value1->get_name()+","+value2->get_name()+")";
581  }
582 
583  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
584  :DerivedValue<std::pair<T1, T2> >(fmt_name(value1, value2), alias),
585  value_pair(value1, value2){ }
586 };
587 
588 template<typename... T> class _Zip;
589 template<>
590 class _Zip<> {
591  protected:
592 
593  int _get_size(){
594  return std::numeric_limits<int>::max();
595  }
596 
597  std::tuple<> _get_at(int){
598  return std::make_tuple();
599  }
600 
601  std::string _get_name(){
602  return "";
603  }
604 
605  public:
606  _Zip() { }
607 };
608 
609 template<typename Head, typename... Tail>
610 class _Zip<Head, Tail...> : private _Zip<Tail...> {
611  protected:
613 
614  int _get_size(){
615  int this_size = head->get_value().size();
616  int rest_size = _Zip<Tail...>::_get_size();
617  return std::min(this_size, rest_size);
618  }
619 
620  typename std::tuple<Head,Tail...> _get_at(int idx){
621  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
622  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
623  }
624 
625  std::string _get_name(){
626  return head->get_name()+","+_Zip<Tail...>::_get_name();
627  }
628 
629  public:
630  _Zip() { }
631 
632  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
633  : _Zip<Tail...>(tail...),
634  head(head) { }
635 };
636 
637 namespace impl {
638  std::string zip_fmt_name(){
639  return "";
640  }
641 
642  template<typename Head>
643  std::string zip_fmt_name(Value<std::vector<Head>>* head){
644  return head->get_name();
645  }
646 
647  template<typename Head1, typename Head2, typename... Tail>
648  std::string zip_fmt_name(Value<std::vector<Head1>>* head1, Value<std::vector<Head2>>* head2, Value<std::vector<Tail>>*... tail){
649  return head1->get_name() + "," + zip_fmt_name<Head2, Tail...>(head2, tail...);
650  }
651 }
667 template <typename... ArgTypes>
668 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
669  private _Zip<ArgTypes...>{
670  protected:
671  void update_value(){
672  this->value.clear();
673  int size = _Zip<ArgTypes...>::_get_size();
674  for(int i=0; i<size; i++){
675  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
676  }
677  }
678 
679  public:
680  static std::string fmt_name(Value<std::vector<ArgTypes>>*... args){
681  return "zip("+zip_fmt_name(args...)+")";
682  }
683 
684  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
685  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>(fmt_name(args...), alias),
686  _Zip<ArgTypes...>(args...) { }
687 };
688 
689 template<typename> class Map; // undefined
697 template <typename Ret, typename... ArgTypes>
698 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
699  private:
700  typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
701  Function<Ret(ArgTypes...)>& fn;
702  arg_type* arg;
703 
704  void update_value(){
705  this->value.clear();
706  for(auto tup : arg->get_value()){
707  this->value.push_back(call(fn,tup));
708  }
709  }
710 
711  public:
712  static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, arg_type* arg){
713  return "map("+fn.get_name()+":"+arg->get_name()+")";
714  }
715 
716  Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
717  :DerivedValue<std::vector<Ret>>(fmt_name(fn, arg), alias),
718  fn(fn), arg(arg){ }
719 
720 };
721 
722 template<typename... T> class _Tuple;
723 template<>
724 class _Tuple<> {
725  protected:
726 
727  std::tuple<> _get_value(){
728  return std::make_tuple();
729  }
730 
731  public:
732  _Tuple() { }
733 };
734 
735 template<typename Head, typename... Tail>
736 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
737  protected:
738  Value<Head>* head;
739 
740  typename std::tuple<Head,Tail...> _get_value(){
741  auto tail_tuple = _Tuple<Tail...>::_get_value();
742  return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
743  }
744 
745  public:
746  _Tuple() { }
747 
748  _Tuple(Value<Head>* head, Value<Tail>*... tail)
749  : _Tuple<Tail...>(tail...),
750  head(head) { }
751 };
752 
753 namespace impl {
754  std::string tuple_fmt_name(){
755  return "";
756  }
757 
758  template<typename Head>
759  std::string tuple_fmt_name(Value<Head>* head){
760  return head->get_name();
761  }
762 
763  template<typename Head1, typename Head2, typename... Tail>
764  std::string tuple_fmt_name(Value<Head1>* head1, Value<Head2>* head2, Value<Tail>*... tail){
765  return head1->get_name() + "," + tuple_fmt_name<Head2, Tail...>(head2, tail...);
766  }
767 }
768 
775 template <typename... ArgTypes>
776 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
777  private _Tuple<ArgTypes...>{
778  protected:
779  void update_value(){
780  this->value = _Tuple<ArgTypes...>::_get_value();
781  }
782 
783  public:
784  static std::string fmt_name(Value<ArgTypes>*... args){
785  return "tuple("+impl::tuple_fmt_name(args...)+")";
786  }
787 
788  Tuple(Value<ArgTypes>*... args, const std::string& alias)
789  :DerivedValue<std::tuple<ArgTypes...>>(fmt_name(args...), alias),
790  _Tuple<ArgTypes...>(args...) { }
791 };
792 
796 template <size_t N, typename... ArgTypes>
797 class DeTup : public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
798  Value<std::tuple<ArgTypes...>> tup;
799  protected:
800  void update_value(){
801  this->value = std::get<N>(tup->get_value());
802  }
803 
804  public:
805  static std::string fmt_name(Value<std::tuple<ArgTypes...>>* tup){
806  return "detup("+tup->get_name()+")";
807  }
808 
809  DeTup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias)
810  :DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(fmt_name(tup), alias),
811  tup(tup) { }
812 };
813 
818 template <size_t N, typename... ArgTypes>
819 class DeTupVector : public DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>{
820  Value<std::vector<std::tuple<ArgTypes...>>>* tup;
821  protected:
822  void update_value(){
823  this->value.clear();
824  for( auto& t : tup->get_value()){
825  this->value.push_back(std::get<N>(t));
826  }
827  }
828 
829  public:
830  static std::string fmt_name(Value<std::vector<std::tuple<ArgTypes...>>>* tup){
831  return "detup_vec("+tup->get_name()+")";
832  }
833 
834  DeTupVector(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias)
835  :DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(fmt_name(tup), alias),
836  tup(tup) { }
837 };
838 
839 template<typename> class Apply; // undefined
844 template <typename Ret, typename... ArgTypes>
845 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
846  private:
847  Function<Ret(ArgTypes...)>& fn;
848  Value<std::tuple<ArgTypes...>>* arg;
849 
850  void update_value(){
851  auto &tup = arg->get_value();
852  this->value = call(fn, tup);
853  }
854 
855  public:
856  static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg){
857  return "apply("+fn.get_name()+":"+arg->get_name()+")";
858  }
859 
860  Apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias)
861  :DerivedValue<Ret>(fmt_name(fn,arg), alias),
862  fn(fn), arg(arg){ }
863 
864 };
865 
869 template<typename T>
870 class Count : public DerivedValue<int>{
871  private:
872  Function<bool(T)>& selector;
874 
875  void update_value(){
876  value = 0;
877  for(auto val : v->get_value()){
878  if(selector(val))
879  value++;
880  }
881  }
882 
883  public:
884  static std::string fmt_name(Function<bool(T)>& selector, Value<std::vector<T>>* v){
885  return "count("+selector.get_name()+":"+v->get_name()+")";
886  }
887 
888  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
889  :DerivedValue<int>(fmt_name(selector,v), alias),
890  selector(selector), v(v) { }
891 };
892 
896 template<typename T>
897 class Filter : public DerivedValue<std::vector<T>>{
898  private:
899  Function<bool(T)>& filter;
901 
902  void update_value(){
903  this->value.clear();
904  for(auto val : v->get_value()){
905  if(this->filter(val))
906  this->value.push_back(val);
907  }
908  }
909 
910  public:
911  static std::string fmt_name(Function<bool(T)>& filter, Value<std::vector<T>>* v){
912  return "filter("+filter.get_name()+":"+v->get_name()+")";
913  }
914 
915  Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
916  :DerivedValue<std::vector<T>>(fmt_name(filter,v), alias),
917  filter(filter), v(v) { }
918 };
919 
925 template<typename... ArgTypes>
926 class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
927  private:
928  typedef std::vector<std::tuple<ArgTypes...>> value_type;
929  Function<bool(ArgTypes...)>& filter;
930  Value<value_type>* arg;
931 
932  void update_value(){
933  this->value.clear();
934  for(auto val : arg->get_value()){
935  if(call(filter,val))
936  this->value.push_back(val);
937  }
938  }
939 
940  public:
941  static std::string fmt_name(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg){
942  return "tup_filter("+filter.get_name()+":"+arg->get_name()+")";
943  }
944 
945  TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
946  :DerivedValue<value_type>(fmt_name(filter, arg), alias),
947  filter(filter), arg(arg) { }
948 };
949 
956 template <typename T>
957 class Reduce : public DerivedValue<T>{
958  private:
959  Function<T(std::vector<T>)>& reduce;
960 
961  void update_value(){
962  this->value = reduce(v->get_value());
963  }
964 
965  protected:
967 
968  public:
969  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
970  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
971  reduce(reduce), v(v) { }
972 };
973 
977 template <typename T>
978 class Max : public Reduce<T>{
979  public:
980  static std::string fmt_name(Value<std::vector<T>>* v){
981  return "max("+v->get_name()+")";
982  }
983 
984  Max(Value<std::vector<T>>* v, const std::string alias)
985  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
986  FUNC(([](std::vector<T> vec){
987  return *std::max_element(vec.begin(), vec.end());}))),
988  v, alias) { }
989 };
990 
994 template <typename T>
995 class Min : public Reduce<T>{
996  public:
997  static std::string fmt_name(Value<std::vector<T>>* v){
998  return "min("+v->get_name()+")";
999  }
1000 
1001  Min(Value<std::vector<T>>* v, const std::string alias)
1002  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
1003  FUNC(([](std::vector<T> vec){
1004  return *std::min_element(vec.begin(), vec.end());}))),
1005  v, alias) { }
1006 };
1007 
1011 template <typename T>
1012 class Mean : public Reduce<T>{
1013  public:
1014  static std::string fmt_name(Value<std::vector<T>>* v){
1015  return "mean("+v->get_name()+")";
1016  }
1017 
1018  Mean(Value<std::vector<T>>* v, const std::string alias)
1019  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
1020  FUNC(([](std::vector<T> vec){
1021  int n = 0; T sum = 0;
1022  for (T e : vec){ n++; sum += e; }
1023  return n>0 ? sum / n : 0; }))),
1024  v, alias) { }
1025 };
1026 
1030 template <typename T>
1031 class Range : public Reduce<T>{
1032  public:
1033  static std::string fmt_name(Value<std::vector<T>>* v){
1034  return "range("+v->get_name()+")";
1035  }
1036 
1037  Range(Value<std::vector<T>>* v, const std::string alias)
1038  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
1039  FUNC(([](std::vector<T> vec){
1040  auto minmax = std::minmax_element(vec.begin(), vec.end());
1041  return (*minmax.second) - (*minmax.first); }))),
1042  v, alias) { }
1043 };
1044 
1048 template <typename T>
1049 class ElementOf : public Reduce<T>{
1050  public:
1051  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
1052  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
1053  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
1054  v, alias) { }
1055 };
1056 
1062 template <typename T>
1063 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
1064  private:
1065  Function<std::pair<T,int>(std::vector<T>)>& reduce;
1066  Value<std::vector<T> >* v;
1067 
1069  this->value = reduce(v->get_value());
1070  }
1071 
1072  public:
1073  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
1074  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
1075  reduce(reduce), v(v) { }
1076 };
1077 
1081 template <typename T>
1082 class MaxIndex : public ReduceIndex<T>{
1083  public:
1084  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
1085  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
1086  FUNC(([](std::vector<T> vec){
1087  auto elptr = std::max_element(vec.begin(), vec.end());
1088  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1089  v, alias) { }
1090 };
1091 
1095 template <typename T>
1096 class MinIndex : public ReduceIndex<T>{
1097  public:
1098  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
1099  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
1100  FUNC(([](std::vector<T> vec){
1101  auto elptr = std::min_element(vec.begin(), vec.end());
1102  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1103  v, alias) { }
1104 };
1105 
1109 template <typename T, int Size>
1110 class Combinations : public DerivedValue<std::vector<typename HomoTuple<T,Size>::type>>{
1111  private:
1112  Value<std::vector<T>>* val;
1113  typedef typename HomoTuple<T,Size>::type tuple_type;
1114 
1116  auto& v = val->get_value();
1117  int data_size = v.size();
1118  this->value.clear();
1119 
1120  std::vector<bool> selector(data_size);
1121  std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}), true);
1122  do {
1123  std::array<T, Size> perm;
1124  int idx = 0;
1125  for (int i=0; i<data_size; i++){
1126  if (selector[i]){
1127  perm[idx] = v[i];
1128  idx++;
1129  if (idx == Size) break;
1130  }
1131  }
1132  this->value.push_back(a2t(perm));
1133  } while(std::prev_permutation(selector.begin(), selector.end()));
1134  }
1135 
1136  public:
1137  static std::string fmt_name(Value<std::vector<T>>* val){
1138  std::stringstream ss;
1139  ss << "combinations(" << Size << "," << val->get_name() << ")";
1140  return ss.str();
1141  }
1142 
1143  Combinations(Value<std::vector<T>>* val, const std::string alias="")
1144  :DerivedValue<std::vector<tuple_type>>(fmt_name(val), alias),
1145  val(val) { }
1146 
1147 };
1148 
1152 template <typename FST, typename SND>
1153 class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
1154  private:
1155  Value<std::vector<FST>>* val1;
1156  Value<std::vector<SND>>* val2;
1157 
1159  this->value.clear();
1160  auto& v1 = val1->get_value();
1161  auto& v2 = val2->get_value();
1162  for(int i=0; i<v1.size(); i++){
1163  for(int j=0; j<v2.size(); j++){
1164  this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1165  }
1166  }
1167  }
1168 
1169  static std::string calc_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1170  std::stringstream ss;
1171  ss << "cartProduct("
1172  << val1->get_name() << ", " << val2->get_name()
1173  << ")";
1174  return ss.str();
1175  }
1176 
1177  public:
1178  static std::string fmt_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1179  return "cartProduct("+val1->get_name()+", "+val2->get_name()+")";
1180  }
1181 
1182  CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
1183  :DerivedValue<std::vector<std::tuple<FST,SND>>>(calc_name(val1, val2), alias),
1184  val1(val1), val2(val2) { }
1185 };
1186 
1192 template <typename T>
1193 class BoundValue : public DerivedValue<T>{
1194  protected:
1195  Function<T()>& f;
1197  this->value = f();
1198  }
1199  public:
1200  BoundValue(Function<T()>& f, const std::string alias="")
1201  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
1202  f(f) { }
1203 };
1204 
1209 template <typename T>
1210 class PointerValue : public DerivedValue<T*>{
1211  protected:
1212  void update_value(){ }
1213 
1214  public:
1215  PointerValue(const std::string& name, T* ptr, const std::string alias="")
1216  :DerivedValue<T*>(name, alias){
1217  this->value = ptr;
1218  }
1219 };
1220 
1224 template <typename T>
1225 class ConstantValue : public DerivedValue<T>{
1226  protected:
1227  void update_value(){ }
1228 
1229  public:
1230  ConstantValue(const std::string& name, T const_value, const std::string alias="")
1231  :DerivedValue<T>("const::"+name, alias),
1232  Value<T>::value(const_value) { }
1233 };
1234 }
1235 #endif // value_hpp
void update_value()
Updates the internal value.
Definition: value.hpp:1115
void update_value()
Updates the internal value.
Definition: value.hpp:1196
Find and return the maximum value of a vector.
Definition: value.hpp:978
Zips a series of vectors together.
Definition: value.hpp:668
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:957
void update_value()
Updates the internal value.
Definition: value.hpp:875
void update_value()
Updates the internal value.
Definition: value.hpp:573
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1096
Find combinations of items from an input vector.
Definition: value.hpp:1110
A generic value owning only a function object.
Definition: value.hpp:1193
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:1031
void update_value()
Updates the internal value.
Definition: value.hpp:822
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:776
A std::vector wrapper around a C-style array.
Definition: value.hpp:545
STL namespace.
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:1063
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:870
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1082
void update_value()
Updates the internal value.
Definition: value.hpp:961
Parent class to all Function classes.
Definition: value.hpp:139
void update_value()
Updates the internal value.
Definition: value.hpp:779
void update_value()
Updates the internal value.
Definition: value.hpp:932
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:897
Gets the Nth element from a tuple value.
Definition: value.hpp:797
Find and return the minimum value of a vector.
Definition: value.hpp:995
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:819
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:570
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:850
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:1068
void update_value()
Updates the internal value.
Definition: value.hpp:704
void update_value()
Updates the internal value.
Definition: value.hpp:1227
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:1049
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:926
Calculate the mean value of a vector.
Definition: value.hpp:1012
void update_value()
Updates the internal value.
Definition: value.hpp:550
A templated value.
Definition: value.hpp:265
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1153
void update_value()
Updates the internal value.
Definition: value.hpp:1158
void update_value()
Updates the internal value.
Definition: value.hpp:671
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:902
void update_value()
Updates the internal value.
Definition: value.hpp:1212
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:1225
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:1210
void update_value()
Updates the internal value.
Definition: value.hpp:800