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 
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 
270 class GenValue;
271 typedef std::map<std::string, GenValue*> ValueSet;
272 class GenValue{
273  private:
279  std::string name;
280 
281  protected:
288  bool value_valid;
289  void _reset(){
290  /* if (this->logging_enabled){ */
291  /* std::cout << "Resetting validity for " << this->get_name() << std::endl; */
292  /* } */
293  /* std::cout << "Resetting validity for " << this->get_name() << std::endl; */
294  this->value_valid = false;
295  }
303  inline static std::map<const std::string, GenValue*> values;
311  inline static std::map<const std::string, GenValue*> aliases;
312 
313  bool logging_enabled;
314 
315  public:
316  GenValue(const std::string& name, const std::string& alias)
317  :name(name),
318  value_valid(false),
319  logging_enabled(false){
320  INFO("Registered value: \"" << name << "\" with alias: \"" << alias << "\"");
321  values[name] = this;
322  if (alias != "")
323  GenValue::alias(alias, this);
324  }
325 
326  const std::string& get_name(){
327  return name;
328  }
329 
330  void set_name(const std::string& new_name){
331  values[name] = nullptr;
332  name = new_name;
333  values[name] = this;
334  }
335 
336  virtual void log() = 0;
337 
338  static void reset(){
339  for (auto val : values){
340  if (val.second != nullptr){
341  val.second->_reset();
342  }
343  }
344  }
345 
346  static GenValue* get_value(const std::string& name){
347  if (aliases[name] != nullptr)
348  return aliases[name];
349  else if (values[name] != nullptr)
350  return values[name];
351  else{
352  ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
353  << summary());
354  CRITICAL("Aborting... :(",-1);
355  }
356  }
357 
358  static void alias(const std::string& name, GenValue* value){
359  if (aliases[name] != nullptr){
360  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
361  }
362  aliases[name] = value;
363  }
364 
365  static GenValue* alias(const std::string& name){
366  if (values[name] != nullptr){
367  WARNING("Alias \"" << name << "\" does not exist.");
368  }
369  return aliases[name];
370  }
371 
372  static std::string summary(){
373  std::stringstream ss;
374  ss << "The following values have been created:" << std::endl;
375  for (auto value : values){
376  if (value.second == nullptr) continue;
377  ss << "\tVALUE::\"" << value.first << "\" at address " << value.second << std::endl;
378  }
379  ss << "And these aliases:" << std::endl;
380  for (auto alias : aliases){
381  std::string orig("VOID");
382  if (alias.second == nullptr) continue;
383  for (auto value : values){
384  if (alias.second == value.second){
385  orig = value.second->get_name();
386  break;
387  }
388  }
389  ss << "\tALIAS::\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
390  }
391  return ss.str();
392  }
393  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
394 };
395 std::ostream& operator<<(std::ostream& os, GenValue& gv){
396  os << gv.get_name();
397  return os;
398 }
399 
400 
410 template <typename T>
411 class Value : public GenValue{
412  protected:
413  std::function<std::string(T)> value_to_string;
414 
415  public:
416  Value(const std::string& name, const std::string& alias="")
417  :value_to_string([](T){return "";}),
418  GenValue(name, alias){ }
421  virtual T& get_value() = 0;
422 
423  void enable_logging(const std::function<std::string(T)>& value_to_string = [](T){return "";}){
424  logging_enabled = true;
425  this->value_to_string = value_to_string;
426  }
427 
428  void disable_logging(){
429  logging_enabled = false;
430  }
431 };
432 
433 
443 template <typename T>
444 class ObservedValue : public Value<T>{
445  private:
446  T *val_ref;
447 
448  public:
449  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
450  :Value<T>(name, alias),
451  val_ref(val_ref){ }
452 
453  void log(){
454  if(this->logging_enabled){
455  INFO(this->get_name() << ": " << this->value_to_string(*val_ref));
456  }
457  }
458 
459  T& get_value(){
460  if (!this->value_valid){
461  this->value_valid = true;
462  this->log();
463  }
464  return *val_ref;
465  }
466 };
467 
468 
484 template <typename T>
485 class DerivedValue : public Value<T>{
486  protected:
487  T value;
488 
497  virtual void update_value() = 0;
498  public:
499  DerivedValue(const std::string& name, const std::string& alias="")
500  :Value<T>(name, alias){ }
501 
502  void log(){
503  if(this->logging_enabled){
504  INFO(this->get_name() << ": " << this->value_to_string(value));
505  }
506  }
507 
508  T& get_value(){
509  /* if (this->logging_enabled){ */
510  /* std::cout << "Getting value for " << this->get_name() << std::endl; */
511  /* } */
512  if (!this->value_valid){
513  /* if (this->logging_enabled){ */
514  /* std::cout << "Updating value for " << this->get_name() << std::endl; */
515  /* } */
516  update_value();
517  this->value_valid = true;
518  this->log();
519  }
520  return value;
521  }
522 };
523 
524 
534 template <typename T>
535 class WrapperVector : public DerivedValue<std::vector<T> >{
536  private:
537  Value<int>* size;
538  Value<T*>* data;
539 
540  void update_value(){
541  int n = size->get_value();
542  T* data_ref = data->get_value();
543  this->value.assign(data_ref, data_ref+n);
544  }
545 
546  public:
547  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
548  :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
549  size(size), data(data){ }
550 };
551 
555 template <typename T1, typename T2>
556 class Pair : public DerivedValue<std::pair<T1, T2> >{
557  protected:
558  std::pair<Value<T1>*, Value<T2>* > value_pair;
559  void update_value(){
560  this->value.first = value_pair.first->get_value();
561  this->value.second = value_pair.second->get_value();
562  }
563 
564  public:
565  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
566  :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
567  value_pair(value1, value2){ }
568 };
569 
570 template<typename... T> class _Zip;
571 template<>
572 class _Zip<> {
573  protected:
574 
575  int _get_size(){
576  return std::numeric_limits<int>::max();
577  }
578 
579  std::tuple<> _get_at(int){
580  return std::make_tuple();
581  }
582 
583  std::string _get_name(){
584  return "";
585  }
586 
587  public:
588  _Zip() { }
589 };
590 
591 template<typename Head, typename... Tail>
592 class _Zip<Head, Tail...> : private _Zip<Tail...> {
593  protected:
595 
596  int _get_size(){
597  int this_size = head->get_value().size();
598  int rest_size = _Zip<Tail...>::_get_size();
599  return std::min(this_size, rest_size);
600  }
601 
602  typename std::tuple<Head,Tail...> _get_at(int idx){
603  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
604  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
605  }
606 
607  std::string _get_name(){
608  return head->get_name()+","+_Zip<Tail...>::_get_name();
609  }
610 
611  public:
612  _Zip() { }
613 
614  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
615  : _Zip<Tail...>(tail...),
616  head(head) { }
617 };
618 
634 template <typename... ArgTypes>
635 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
636  private _Zip<ArgTypes...>{
637  protected:
638  void update_value(){
639  this->value.clear();
640  int size = _Zip<ArgTypes...>::_get_size();
641  for(int i=0; i<size; i++){
642  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
643  }
644  }
645 
646  std::string _get_name(){
647  return "zip("+_Zip<ArgTypes...>::_get_name()+")";
648  }
649 
650  public:
651  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
652  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
653  _Zip<ArgTypes...>(args...) {
654  this->set_name(_get_name());
655  }
656 };
657 
658 template<typename> class Map; // undefined
666 template <typename Ret, typename... ArgTypes>
667 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
668  private:
669  typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
670  Function<Ret(ArgTypes...)>& fn;
671  arg_type* arg;
672 
673  void update_value(){
674  this->value.clear();
675  for(auto tup : arg->get_value()){
676  this->value.push_back(call(fn,tup));
677  }
678  }
679 
680  public:
681  Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
682  :DerivedValue<std::vector<Ret>>("map("+fn.get_name()+":"+arg->get_name()+")", alias),
683  fn(fn), arg(arg){ }
684 
685 };
686 
687 template<typename... T> class _Tuple;
688 template<>
689 class _Tuple<> {
690  protected:
691 
692  std::tuple<> _get_value(){
693  return std::make_tuple();
694  }
695 
696  std::string _get_name(){
697  return "";
698  }
699 
700  public:
701  _Tuple() { }
702 };
703 
704 template<typename Head, typename... Tail>
705 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
706  protected:
707  Value<Head>* head;
708 
709  typename std::tuple<Head,Tail...> _get_value(){
710  auto tail_tuple = _Tuple<Tail...>::_get_value();
711  return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
712  }
713 
714 
715  std::string _get_name(){
716  return head->get_name()+","+_Tuple<Tail...>::_get_name();
717  }
718 
719  public:
720  _Tuple() { }
721 
722  _Tuple(Value<Head>* head, Value<Tail>*... tail)
723  : _Tuple<Tail...>(tail...),
724  head(head) { }
725 };
726 
733 template <typename... ArgTypes>
734 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
735  private _Tuple<ArgTypes...>{
736  protected:
737  void update_value(){
738  this->value = _Tuple<ArgTypes...>::_get_value();
739  }
740 
741  std::string _get_name(){
742  return "tuple("+_Tuple<ArgTypes...>::_get_name()+")";
743  }
744 
745  public:
746  Tuple(Value<ArgTypes>*... args, const std::string& alias)
747  :DerivedValue<std::tuple<ArgTypes...>>("", alias),
748  _Tuple<ArgTypes...>(args...) {
749  this->set_name(_get_name());
750  }
751 };
752 
756 template <size_t N, typename... ArgTypes>
757 class DeTup : public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
758  Value<std::tuple<ArgTypes...>> tup;
759  protected:
760  void update_value(){
761  this->value = std::get<N>(tup->get_value());
762  }
763 
764  public:
765  DeTup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias)
766  :DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>("detup("+tup->get_name()+")", alias),
767  tup(tup) { }
768 };
769 
774 template <size_t N, typename... ArgTypes>
775 class DeTupVector : public DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>{
776  Value<std::vector<std::tuple<ArgTypes...>>>* tup;
777  protected:
778  void update_value(){
779  this->value.clear();
780  for( auto& t : tup->get_value()){
781  this->value.push_back(std::get<N>(t));
782  }
783  }
784 
785  public:
786  DeTupVector(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias)
787  :DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>("detup("+tup->get_name()+")", alias),
788  tup(tup) { }
789 };
790 
791 template<typename> class Apply; // undefined
796 template <typename Ret, typename... ArgTypes>
797 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
798  private:
799  Function<Ret(ArgTypes...)>& fn;
800  Value<std::tuple<ArgTypes...>>* arg;
801 
802  void update_value(){
803  auto &tup = arg->get_value();
804  this->value = call(fn, tup);
805  }
806 
807  public:
808  Apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias)
809  :DerivedValue<Ret>("apply("+fn.get_name()+":"+arg->get_name()+")", alias),
810  fn(fn), arg(arg){ }
811 
812 };
813 
817 template<typename T>
818 class Count : public DerivedValue<int>{
819  private:
820  Function<bool(T)>& selector;
822 
823  void update_value(){
824  value = 0;
825  for(auto val : v->get_value()){
826  if(selector(val))
827  value++;
828  }
829  }
830 
831  public:
832  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
833  :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
834  selector(selector), v(v) { }
835 };
836 
840 template<typename T>
841 class Filter : public DerivedValue<std::vector<T>>{
842  private:
843  Function<bool(T)>& filter;
845 
846  void update_value(){
847  this->value.clear();
848  for(auto val : v->get_value()){
849  if(this->filter(val))
850  this->value.push_back(val);
851  }
852  }
853 
854  public:
855  Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
856  :DerivedValue<std::vector<T>>("filter("+filter.get_name()+":"+v->get_name()+")", alias),
857  filter(filter), v(v) { }
858 };
859 
865 template<typename... ArgTypes>
866 class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
867  private:
868  typedef std::vector<std::tuple<ArgTypes...>> value_type;
869  Function<bool(ArgTypes...)>& filter;
870  Value<value_type>* arg;
871 
872  void update_value(){
873  this->value.clear();
874  for(auto val : arg->get_value()){
875  if(call(filter,val))
876  this->value.push_back(val);
877  }
878  }
879 
880  public:
881  TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
882  :DerivedValue<value_type>("tupfilter("+filter.get_name()+":"+arg->get_name()+")", alias),
883  filter(filter), arg(arg) { }
884 };
885 
892 template <typename T>
893 class Reduce : public DerivedValue<T>{
894  private:
895  Function<T(std::vector<T>)>& reduce;
896 
897  void update_value(){
898  this->value = reduce(v->get_value());
899  }
900 
901  protected:
903 
904  public:
905  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
906  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
907  reduce(reduce), v(v) { }
908 };
909 
913 template <typename T>
914 class Max : public Reduce<T>{
915  public:
916  Max(Value<std::vector<T>>* v, const std::string alias)
917  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
918  FUNC(([](std::vector<T> vec){
919  return *std::max_element(vec.begin(), vec.end());}))),
920  v, alias) { }
921 };
922 
926 template <typename T>
927 class Min : public Reduce<T>{
928  public:
929  Min(Value<std::vector<T>>* v, const std::string alias)
930  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
931  FUNC(([](std::vector<T> vec){
932  return *std::min_element(vec.begin(), vec.end());}))),
933  v, alias) { }
934 };
935 
939 template <typename T>
940 class Mean : public Reduce<T>{
941  public:
942  Mean(Value<std::vector<T>>* v, const std::string alias)
943  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
944  FUNC(([](std::vector<T> vec){
945  int n = 0; T sum = 0;
946  for (T e : vec){ n++; sum += e; }
947  return n>0 ? sum / n : 0; }))),
948  v, alias) { }
949 };
950 
954 template <typename T>
955 class Range : public Reduce<T>{
956  public:
957  Range(Value<std::vector<T>>* v, const std::string alias)
958  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
959  FUNC(([](std::vector<T> vec){
960  auto minmax = std::minmax_element(vec.begin(), vec.end());
961  return (*minmax.second) - (*minmax.first); }))),
962  v, alias) { }
963 };
964 
968 template <typename T>
969 class ElementOf : public Reduce<T>{
970  public:
971  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
972  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
973  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
974  v, alias) { }
975 };
976 
982 template <typename T>
983 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
984  private:
985  Function<std::pair<T,int>(std::vector<T>)>& reduce;
987 
988  void update_value(){
989  this->value = reduce(v->get_value());
990  }
991 
992  public:
993  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
994  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
995  reduce(reduce), v(v) { }
996 };
997 
1001 template <typename T>
1002 class MaxIndex : public ReduceIndex<T>{
1003  public:
1004  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
1005  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
1006  FUNC(([](std::vector<T> vec){
1007  auto elptr = std::max_element(vec.begin(), vec.end());
1008  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1009  v, alias) { }
1010 };
1011 
1015 template <typename T>
1016 class MinIndex : public ReduceIndex<T>{
1017  public:
1018  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
1019  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
1020  FUNC(([](std::vector<T> vec){
1021  auto elptr = std::min_element(vec.begin(), vec.end());
1022  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1023  v, alias) { }
1024 };
1025 
1029 template <typename T, int Size>
1030 class Combinations : public DerivedValue<std::vector<typename HomoTuple<T,Size>::type>>{
1031  private:
1032  Value<std::vector<T>>* val;
1033  typedef typename HomoTuple<T,Size>::type tuple_type;
1034 
1036  auto& v = val->get_value();
1037  int data_size = v.size();
1038  this->value.clear();
1039 
1040  std::vector<bool> selector(data_size);
1041  std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}), true);
1042  do {
1043  std::array<T, Size> perm;
1044  int idx = 0;
1045  for (int i=0; i<data_size; i++){
1046  if (selector[i]){
1047  perm[idx] = v[i];
1048  idx++;
1049  if (idx == Size) break;
1050  }
1051  }
1052  this->value.push_back(a2t(perm));
1053  } while(std::prev_permutation(selector.begin(), selector.end()));
1054  }
1055 
1056  static std::string calc_name(Value<std::vector<T>>* val){
1057  std::stringstream ss;
1058  ss << "combinations(" << Size << "," << val->get_name() << ")";
1059  return ss.str();
1060  }
1061 
1062  public:
1063  Combinations(Value<std::vector<T>>* val, const std::string alias="")
1064  :DerivedValue<std::vector<tuple_type>>(calc_name(val), alias),
1065  val(val) { }
1066 
1067 };
1068 
1072 template <typename FST, typename SND>
1073 class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
1074  private:
1075  Value<std::vector<FST>>* val1;
1076  Value<std::vector<SND>>* val2;
1077 
1079  this->value.clear();
1080  auto& v1 = val1->get_value();
1081  auto& v2 = val2->get_value();
1082  for(int i=0; i<v1.size(); i++){
1083  for(int j=0; j<v2.size(); j++){
1084  this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1085  }
1086  }
1087  }
1088 
1089  static std::string calc_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1090  std::stringstream ss;
1091  ss << "cartProduct("
1092  << val1->get_name() << ", " << val2->get_name()
1093  << ")";
1094  return ss.str();
1095  }
1096 
1097  public:
1098  CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
1099  :DerivedValue<std::vector<std::tuple<FST,SND>>>(calc_name(val1, val2), alias),
1100  val1(val1),
1101  val2(val2) { }
1102 };
1103 
1109 template <typename T>
1110 class BoundValue : public DerivedValue<T>{
1111  protected:
1112  Function<T()>& f;
1114  this->value = f();
1115  }
1116  public:
1117  BoundValue(Function<T()>& f, const std::string alias="")
1118  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
1119  f(f) { }
1120 };
1121 
1126 template <typename T>
1127 class PointerValue : public DerivedValue<T*>{
1128  protected:
1129  void update_value(){ }
1130 
1131  public:
1132  PointerValue(const std::string& name, T* ptr, const std::string alias="")
1133  :DerivedValue<T*>(name, alias){
1134  this->value = ptr;
1135  }
1136 };
1137 
1141 template <typename T>
1142 class ConstantValue : public DerivedValue<T>{
1143  protected:
1144  void update_value(){ }
1145 
1146  public:
1147  ConstantValue(const std::string& name, T const_value, const std::string alias="")
1148  :DerivedValue<T>("const::"+name, alias),
1149  Value<T>::value(const_value) { }
1150 };
1151 }
1152 #endif // value_hpp
void update_value()
Updates the internal value.
Definition: value.hpp:1035
void update_value()
Updates the internal value.
Definition: value.hpp:1113
Find and return the maximum value of a vector.
Definition: value.hpp:914
Zips a series of vectors together.
Definition: value.hpp:635
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:893
void update_value()
Updates the internal value.
Definition: value.hpp:823
void update_value()
Updates the internal value.
Definition: value.hpp:559
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1016
Find combinations of items from an input vector.
Definition: value.hpp:1030
A generic value owning only a function object.
Definition: value.hpp:1110
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:508
Calculate the range of the values in a vector.
Definition: value.hpp:955
void update_value()
Updates the internal value.
Definition: value.hpp:778
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:734
A std::vector wrapper around a C-style array.
Definition: value.hpp:535
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:983
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:818
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1002
void update_value()
Updates the internal value.
Definition: value.hpp:897
Parent class to all Function classes.
Definition: value.hpp:143
void update_value()
Updates the internal value.
Definition: value.hpp:737
void update_value()
Updates the internal value.
Definition: value.hpp:872
A value supplied by the dataset, not derived.
Definition: value.hpp:444
Returns the elements in a vector that pass a test function.
Definition: value.hpp:841
Gets the Nth element from a tuple value.
Definition: value.hpp:757
Find and return the minimum value of a vector.
Definition: value.hpp:927
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:775
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:556
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:802
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:459
void update_value()
Updates the internal value.
Definition: value.hpp:988
void update_value()
Updates the internal value.
Definition: value.hpp:673
void update_value()
Updates the internal value.
Definition: value.hpp:1144
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:969
Returns the elements in a vector that pass a test function.
Definition: value.hpp:866
Calculate the mean value of a vector.
Definition: value.hpp:940
void update_value()
Updates the internal value.
Definition: value.hpp:540
A generic value.
Definition: value.hpp:411
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1073
void update_value()
Updates the internal value.
Definition: value.hpp:1078
void update_value()
Updates the internal value.
Definition: value.hpp:638
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:485
void update_value()
Updates the internal value.
Definition: value.hpp:846
void update_value()
Updates the internal value.
Definition: value.hpp:1129
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:1142
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:1127
void update_value()
Updates the internal value.
Definition: value.hpp:760