TTTT Analysis  0.1
value.hpp
Go to the documentation of this file.
1 
42 #ifndef value_hpp
43 #define value_hpp
44 #include <iomanip>
45 #include <iostream>
46 #include <sstream>
47 #include <utility>
48 #include <algorithm>
49 #include <map>
50 #include <limits>
51 #include <vector>
52 #include <tuple>
53 #include <initializer_list>
54 #include <functional>
55 
56 #include "log.hpp"
57 
61 namespace fv{
62 
63 namespace detail {
64  template<typename T, int N, bool Done, typename... TYPES>
65  struct _HomoTuple {
66  typedef _HomoTuple<T, N, sizeof...(TYPES)+1==N, TYPES..., T> stype;
67  typedef typename stype::type type;
68  };
69 
70  template<typename T, int N, typename... TYPES>
71  struct _HomoTuple<T, N, true, TYPES...> {
72  typedef std::tuple<TYPES...> type;
73  };
74 }
75 
76 template<typename T, int N>
77 struct HomoTuple {
78  typedef detail::_HomoTuple<T, N, N==0> stype;
79  typedef typename stype::type type;
80 };
81 
82 namespace detail {
83  // Convert array into a tuple
84  template<typename Array, std::size_t... I>
85  decltype(auto) a2t_impl(const Array& a, std::index_sequence<I...>){
86  return std::make_tuple(a[I]...);
87  }
88 }
89 
93 template<typename T, std::size_t N, typename Indices = std::make_index_sequence<N>>
94 decltype(auto) a2t(const std::array<T, N>& a){
95  return detail::a2t_impl(a, Indices());
96 }
97 
98 namespace detail {
99  template <class F, class Tuple, std::size_t... I>
100  constexpr decltype(auto) call_impl(F &&f, Tuple &&t, std::index_sequence<I...>){
101  return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
102  }
103 }
104 
105 template <class F, class Tuple>
106 constexpr decltype(auto) call(F &&f, Tuple &&t){
107  return detail::call_impl(
108  std::forward<F>(f), std::forward<Tuple>(t),
109  std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
110 }
111 
112 namespace detail{
113  template <typename T, int N, int I>
114  struct t2s_impl{
115  public:
116  static std::string cvt(typename HomoTuple<T,N>::type& tup, std::function<std::string(T)>& f){
117  std::stringstream ss;
118  ss << f(std::get<N-I>(tup)) << ", " << t2s_impl<T, N, I+1>::cvt(tup, f);
119  return ss.str();
120  }
121  };
122 
123  template <typename T, int N>
124  struct t2s_impl<T, N, 0>{
125  public:
126  static std::string cvt(typename HomoTuple<T,N>::type&, std::function<std::string(T)>&){
127  return "";
128  }
129  };
130 }
131 
132 template <typename T, int N>
133 std::string t2s(typename HomoTuple<T,N>::type& tup, std::function<std::string(T)>& f){
134  return detail::t2s_impl<T, N, N>(tup, f);
135 }
136 
137 template<typename> class Function; // undefined
138 
143 class GenFunction {
144  private:
145  std::string name;
146  std::string impl;
147  protected:
148  inline static bool in_register_function=false;
149 
150  public:
155  inline static std::map<const std::string, GenFunction*> function_registry;
156 
157  GenFunction(const std::string& name, const std::string& impl)
158  :name(name),
159  impl(impl){ }
160 
161  virtual ~GenFunction() { };
162 
163  std::string& get_name(){
164  return name;
165  }
166 
167  std::string& get_impl(){
168  return impl;
169  }
170 
176  static std::string format_code(const std::string& code){
177  std::stringstream code_out("");
178  std::string command("echo \""+code+"\" | clang-format");
179  char buffer[255];
180  FILE *stream = popen(command.c_str(), "r");
181  while (fgets(buffer, 255, stream) != NULL)
182  code_out << buffer;
183  if (pclose(stream) == 0)
184  return code_out.str();
185  else
186  return code;
187  }
188 
189  static std::string summary(){
190  std::stringstream ss;
191  ss << "The following functions have been registered" << std::endl;
192  for(auto p : function_registry){
193  if (p.second == nullptr) continue;
194  ss << "FUNCTION::" << p.second->name << "@" << p.second << std::endl;
195  ss << format_code(p.second->impl);
196  }
197  return ss.str();
198  }
199 
200  template <typename T>
201  static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
202  in_register_function = true;
203  Function<T>* func;
204  if (GenFunction::function_registry[name] != nullptr){
205  func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
206  if (func == nullptr){
207  ERROR("Trying to register function which has already been registered with a different type");
208  }
209  } else {
210  func = new Function<T>(name, impl, f);
211  GenFunction::function_registry[name] = func;
212  }
213  in_register_function = false;
214  return *func;
215  }
216 
217  template <typename T>
218  static Function<T>& lookup_function(const std::string& name){
219  if (GenFunction::function_registry[name] == nullptr){
220  CRITICAL("Function \"" << name << "\" not previously registered", -1);
221  } else {
222  Function<T>* func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
223  if (func == nullptr){
224  CRITICAL("Function \"" << name << "\" request and register have mismatched types", -1);
225  }
226  return *GenFunction::function_registry[name];
227  }
228  }
229 };
230 
231 
243 template <typename R, typename... ArgTypes>
244 class Function<R(ArgTypes...)> : public GenFunction {
245  private:
246  std::function<R(ArgTypes...)> f;
247 
248  public:
249  Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
250  :GenFunction(name, impl), f(f){
251  if (!in_register_function) {
252  WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
253  }
254  }
255  Function(const std::string& name, std::function<R(ArgTypes...)> f)
256  :Function(name, "N/A", f){ }
257  ~Function() { }
258 
259  R operator()(ArgTypes ...args){
260  return f(args...);
261  }
262 
263 };
264 
265 
266 #define FUNC(f) f, #f
267 
274 class GenValue;
275 typedef std::map<std::string, GenValue*> ValueSet;
276 class GenValue{
277  private:
283  std::string name;
284 
285  protected:
292  bool value_valid;
293  void _reset(){
294  /* if (this->logging_enabled){ */
295  /* std::cout << "Resetting validity for " << this->get_name() << std::endl; */
296  /* } */
297  /* std::cout << "Resetting validity for " << this->get_name() << std::endl; */
298  this->value_valid = false;
299  }
307  inline static std::map<const std::string, GenValue*> values;
315  inline static std::map<const std::string, GenValue*> aliases;
316 
317  bool logging_enabled;
318 
319  public:
320  GenValue(const std::string& name, const std::string& alias)
321  :name(name),
322  value_valid(false),
323  logging_enabled(false){
324  INFO("Registered value: \"" << name << "\" with alias: \"" << alias << "\"");
325  values[name] = this;
326  if (alias != "")
327  GenValue::alias(alias, this);
328  }
329 
330  const std::string& get_name(){
331  return name;
332  }
333 
334  void set_name(const std::string& new_name){
335  values[name] = nullptr;
336  name = new_name;
337  values[name] = this;
338  }
339 
340  virtual void log() = 0;
341 
342  static void reset(){
343  for (auto val : values){
344  if (val.second != nullptr){
345  val.second->_reset();
346  }
347  }
348  }
349 
350  static GenValue* get_value(const std::string& name){
351  if (aliases[name] != nullptr)
352  return aliases[name];
353  else if (values[name] != nullptr)
354  return values[name];
355  else{
356  ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
357  << summary());
358  CRITICAL("Aborting... :(",-1);
359  }
360  }
361 
362  static void alias(const std::string& name, GenValue* value){
363  if (aliases[name] != nullptr){
364  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
365  }
366  aliases[name] = value;
367  }
368 
369  static GenValue* alias(const std::string& name){
370  if (values[name] != nullptr){
371  WARNING("Alias \"" << name << "\" does not exist.");
372  }
373  return aliases[name];
374  }
375 
376  static std::string summary(){
377  std::stringstream ss;
378  ss << "The following values have been created:" << std::endl;
379  for (auto value : values){
380  if (value.second == nullptr) continue;
381  ss << "\tVALUE::\"" << value.first << "\" at address " << value.second << std::endl;
382  }
383  ss << "And these aliases:" << std::endl;
384  for (auto alias : aliases){
385  std::string orig("VOID");
386  if (alias.second == nullptr) continue;
387  for (auto value : values){
388  if (alias.second == value.second){
389  orig = value.second->get_name();
390  break;
391  }
392  }
393  ss << "\tALIAS::\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
394  }
395  return ss.str();
396  }
397  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
398 };
399 std::ostream& operator<<(std::ostream& os, GenValue& gv){
400  os << gv.get_name();
401  return os;
402 }
403 
404 
414 template <typename T>
415 class Value : public GenValue{
416  protected:
417  std::function<std::string(T)> value_to_string;
418 
419  public:
420  Value(const std::string& name, const std::string& alias="")
421  :value_to_string([](T){return "";}),
422  GenValue(name, alias){ }
425  virtual T& get_value() = 0;
426 
427  void enable_logging(const std::function<std::string(T)>& value_to_string = [](T){return "";}){
428  logging_enabled = true;
429  this->value_to_string = value_to_string;
430  }
431 
432  void disable_logging(){
433  logging_enabled = false;
434  }
435 };
436 
437 
447 template <typename T>
448 class ObservedValue : public Value<T>{
449  private:
450  T *val_ref;
451 
452  public:
453  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
454  :Value<T>(name, alias),
455  val_ref(val_ref){ }
456 
457  void log(){
458  if(this->logging_enabled){
459  INFO(this->get_name() << ": " << this->value_to_string(*val_ref));
460  }
461  }
462 
463  T& get_value(){
464  if (!this->value_valid){
465  this->value_valid = true;
466  this->log();
467  }
468  return *val_ref;
469  }
470 };
471 
472 
488 template <typename T>
489 class DerivedValue : public Value<T>{
490  protected:
491  T value;
492 
501  virtual void update_value() = 0;
502  public:
503  DerivedValue(const std::string& name, const std::string& alias="")
504  :Value<T>(name, alias){ }
505 
506  void log(){
507  if(this->logging_enabled){
508  INFO(this->get_name() << ": " << this->value_to_string(value));
509  }
510  }
511 
512  T& get_value(){
513  /* if (this->logging_enabled){ */
514  /* std::cout << "Getting value for " << this->get_name() << std::endl; */
515  /* } */
516  if (!this->value_valid){
517  /* if (this->logging_enabled){ */
518  /* std::cout << "Updating value for " << this->get_name() << std::endl; */
519  /* } */
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  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
552  :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
553  size(size), data(data){ }
554 };
555 
559 template <typename T1, typename T2>
560 class Pair : public DerivedValue<std::pair<T1, T2> >{
561  protected:
562  std::pair<Value<T1>*, Value<T2>* > value_pair;
563  void update_value(){
564  this->value.first = value_pair.first->get_value();
565  this->value.second = value_pair.second->get_value();
566  }
567 
568  public:
569  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
570  :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
571  value_pair(value1, value2){ }
572 };
573 
574 template<typename... T> class _Zip;
575 template<>
576 class _Zip<> {
577  protected:
578 
579  int _get_size(){
580  return std::numeric_limits<int>::max();
581  }
582 
583  std::tuple<> _get_at(int){
584  return std::make_tuple();
585  }
586 
587  std::string _get_name(){
588  return "";
589  }
590 
591  public:
592  _Zip() { }
593 };
594 
595 template<typename Head, typename... Tail>
596 class _Zip<Head, Tail...> : private _Zip<Tail...> {
597  protected:
599 
600  int _get_size(){
601  int this_size = head->get_value().size();
602  int rest_size = _Zip<Tail...>::_get_size();
603  return std::min(this_size, rest_size);
604  }
605 
606  typename std::tuple<Head,Tail...> _get_at(int idx){
607  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
608  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
609  }
610 
611  std::string _get_name(){
612  return head->get_name()+","+_Zip<Tail...>::_get_name();
613  }
614 
615  public:
616  _Zip() { }
617 
618  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
619  : _Zip<Tail...>(tail...),
620  head(head) { }
621 };
622 
638 template <typename... ArgTypes>
639 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
640  private _Zip<ArgTypes...>{
641  protected:
642  void update_value(){
643  this->value.clear();
644  int size = _Zip<ArgTypes...>::_get_size();
645  for(int i=0; i<size; i++){
646  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
647  }
648  }
649 
650  std::string _get_name(){
651  return "zip("+_Zip<ArgTypes...>::_get_name()+")";
652  }
653 
654  public:
655  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
656  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
657  _Zip<ArgTypes...>(args...) {
658  this->set_name(_get_name());
659  }
660 };
661 
662 template<typename> class Map; // undefined
670 template <typename Ret, typename... ArgTypes>
671 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
672  private:
673  typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
674  Function<Ret(ArgTypes...)>& fn;
675  arg_type* arg;
676 
677  void update_value(){
678  this->value.clear();
679  for(auto tup : arg->get_value()){
680  this->value.push_back(call(fn,tup));
681  }
682  }
683 
684  public:
685  Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
686  :DerivedValue<std::vector<Ret>>("map("+fn.get_name()+":"+arg->get_name()+")", alias),
687  fn(fn), arg(arg){ }
688 
689 };
690 
691 template<typename... T> class _Tuple;
692 template<>
693 class _Tuple<> {
694  protected:
695 
696  std::tuple<> _get_value(){
697  return std::make_tuple();
698  }
699 
700  std::string _get_name(){
701  return "";
702  }
703 
704  public:
705  _Tuple() { }
706 };
707 
708 template<typename Head, typename... Tail>
709 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
710  protected:
711  Value<Head>* head;
712 
713  typename std::tuple<Head,Tail...> _get_value(){
714  auto tail_tuple = _Tuple<Tail...>::_get_value();
715  return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
716  }
717 
718 
719  std::string _get_name(){
720  return head->get_name()+","+_Tuple<Tail...>::_get_name();
721  }
722 
723  public:
724  _Tuple() { }
725 
726  _Tuple(Value<Head>* head, Value<Tail>*... tail)
727  : _Tuple<Tail...>(tail...),
728  head(head) { }
729 };
730 
737 template <typename... ArgTypes>
738 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
739  private _Tuple<ArgTypes...>{
740  protected:
741  void update_value(){
742  this->value = _Tuple<ArgTypes...>::_get_value();
743  }
744 
745  std::string _get_name(){
746  return "tuple("+_Tuple<ArgTypes...>::_get_name()+")";
747  }
748 
749  public:
750  Tuple(Value<ArgTypes>*... args, const std::string& alias)
751  :DerivedValue<std::tuple<ArgTypes...>>("", alias),
752  _Tuple<ArgTypes...>(args...) {
753  this->set_name(_get_name());
754  }
755 };
756 
760 template <size_t N, typename... ArgTypes>
761 class DeTup : public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
762  Value<std::tuple<ArgTypes...>> tup;
763  protected:
764  void update_value(){
765  this->value = std::get<N>(tup->get_value());
766  }
767 
768  public:
769  DeTup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias)
770  :DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>("detup("+tup->get_name()+")", alias),
771  tup(tup) { }
772 };
773 
778 template <size_t N, typename... ArgTypes>
779 class DeTupVector : public DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>{
780  Value<std::vector<std::tuple<ArgTypes...>>>* tup;
781  protected:
782  void update_value(){
783  this->value.clear();
784  for( auto& t : tup->get_value()){
785  this->value.push_back(std::get<N>(t));
786  }
787  }
788 
789  public:
790  DeTupVector(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias)
791  :DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>("detup("+tup->get_name()+")", alias),
792  tup(tup) { }
793 };
794 
795 template<typename> class Apply; // undefined
800 template <typename Ret, typename... ArgTypes>
801 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
802  private:
803  Function<Ret(ArgTypes...)>& fn;
804  Value<std::tuple<ArgTypes...>>* arg;
805 
806  void update_value(){
807  auto &tup = arg->get_value();
808  this->value = call(fn, tup);
809  }
810 
811  public:
812  Apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias)
813  :DerivedValue<Ret>("apply("+fn.get_name()+":"+arg->get_name()+")", alias),
814  fn(fn), arg(arg){ }
815 
816 };
817 
821 template<typename T>
822 class Count : public DerivedValue<int>{
823  private:
824  Function<bool(T)>& selector;
826 
827  void update_value(){
828  value = 0;
829  for(auto val : v->get_value()){
830  if(selector(val))
831  value++;
832  }
833  }
834 
835  public:
836  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
837  :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
838  selector(selector), v(v) { }
839 };
840 
844 template<typename T>
845 class Filter : public DerivedValue<std::vector<T>>{
846  private:
847  Function<bool(T)>& filter;
849 
850  void update_value(){
851  this->value.clear();
852  for(auto val : v->get_value()){
853  if(this->filter(val))
854  this->value.push_back(val);
855  }
856  }
857 
858  public:
859  Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
860  :DerivedValue<std::vector<T>>("filter("+filter.get_name()+":"+v->get_name()+")", alias),
861  filter(filter), v(v) { }
862 };
863 
869 template<typename... ArgTypes>
870 class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
871  private:
872  typedef std::vector<std::tuple<ArgTypes...>> value_type;
873  Function<bool(ArgTypes...)>& filter;
874  Value<value_type>* arg;
875 
876  void update_value(){
877  this->value.clear();
878  for(auto val : arg->get_value()){
879  if(call(filter,val))
880  this->value.push_back(val);
881  }
882  }
883 
884  public:
885  TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
886  :DerivedValue<value_type>("tupfilter("+filter.get_name()+":"+arg->get_name()+")", alias),
887  filter(filter), arg(arg) { }
888 };
889 
896 template <typename T>
897 class Reduce : public DerivedValue<T>{
898  private:
899  Function<T(std::vector<T>)>& reduce;
900 
901  void update_value(){
902  this->value = reduce(v->get_value());
903  }
904 
905  protected:
907 
908  public:
909  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
910  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
911  reduce(reduce), v(v) { }
912 };
913 
917 template <typename T>
918 class Max : public Reduce<T>{
919  public:
920  Max(Value<std::vector<T>>* v, const std::string alias)
921  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
922  FUNC(([](std::vector<T> vec){
923  return *std::max_element(vec.begin(), vec.end());}))),
924  v, alias) { }
925 };
926 
930 template <typename T>
931 class Min : public Reduce<T>{
932  public:
933  Min(Value<std::vector<T>>* v, const std::string alias)
934  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
935  FUNC(([](std::vector<T> vec){
936  return *std::min_element(vec.begin(), vec.end());}))),
937  v, alias) { }
938 };
939 
943 template <typename T>
944 class Mean : public Reduce<T>{
945  public:
946  Mean(Value<std::vector<T>>* v, const std::string alias)
947  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
948  FUNC(([](std::vector<T> vec){
949  int n = 0; T sum = 0;
950  for (T e : vec){ n++; sum += e; }
951  return n>0 ? sum / n : 0; }))),
952  v, alias) { }
953 };
954 
958 template <typename T>
959 class Range : public Reduce<T>{
960  public:
961  Range(Value<std::vector<T>>* v, const std::string alias)
962  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
963  FUNC(([](std::vector<T> vec){
964  auto minmax = std::minmax_element(vec.begin(), vec.end());
965  return (*minmax.second) - (*minmax.first); }))),
966  v, alias) { }
967 };
968 
972 template <typename T>
973 class ElementOf : public Reduce<T>{
974  public:
975  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
976  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
977  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
978  v, alias) { }
979 };
980 
986 template <typename T>
987 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
988  private:
989  Function<std::pair<T,int>(std::vector<T>)>& reduce;
991 
992  void update_value(){
993  this->value = reduce(v->get_value());
994  }
995 
996  public:
997  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
998  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
999  reduce(reduce), v(v) { }
1000 };
1001 
1005 template <typename T>
1006 class MaxIndex : public ReduceIndex<T>{
1007  public:
1008  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
1009  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
1010  FUNC(([](std::vector<T> vec){
1011  auto elptr = std::max_element(vec.begin(), vec.end());
1012  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1013  v, alias) { }
1014 };
1015 
1019 template <typename T>
1020 class MinIndex : public ReduceIndex<T>{
1021  public:
1022  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
1023  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
1024  FUNC(([](std::vector<T> vec){
1025  auto elptr = std::min_element(vec.begin(), vec.end());
1026  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1027  v, alias) { }
1028 };
1029 
1033 template <typename T, int Size>
1034 class Combinations : public DerivedValue<std::vector<typename HomoTuple<T,Size>::type>>{
1035  private:
1036  Value<std::vector<T>>* val;
1037  typedef typename HomoTuple<T,Size>::type tuple_type;
1038 
1040  auto& v = val->get_value();
1041  int data_size = v.size();
1042  this->value.clear();
1043 
1044  std::vector<bool> selector(data_size);
1045  std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}), true);
1046  do {
1047  std::array<T, Size> perm;
1048  int idx = 0;
1049  for (int i=0; i<data_size; i++){
1050  if (selector[i]){
1051  perm[idx] = v[i];
1052  idx++;
1053  if (idx == Size) break;
1054  }
1055  }
1056  this->value.push_back(a2t(perm));
1057  } while(std::prev_permutation(selector.begin(), selector.end()));
1058  }
1059 
1060  static std::string calc_name(Value<std::vector<T>>* val){
1061  std::stringstream ss;
1062  ss << "combinations(" << Size << "," << val->get_name() << ")";
1063  return ss.str();
1064  }
1065 
1066  public:
1067  Combinations(Value<std::vector<T>>* val, const std::string alias="")
1068  :DerivedValue<std::vector<tuple_type>>(calc_name(val), alias),
1069  val(val) { }
1070 
1071 };
1072 
1076 template <typename FST, typename SND>
1077 class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
1078  private:
1079  Value<std::vector<FST>>* val1;
1080  Value<std::vector<SND>>* val2;
1081 
1083  this->value.clear();
1084  auto& v1 = val1->get_value();
1085  auto& v2 = val2->get_value();
1086  for(int i=0; i<v1.size(); i++){
1087  for(int j=0; j<v2.size(); j++){
1088  this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1089  }
1090  }
1091  }
1092 
1093  static std::string calc_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1094  std::stringstream ss;
1095  ss << "cartProduct("
1096  << val1->get_name() << ", " << val2->get_name()
1097  << ")";
1098  return ss.str();
1099  }
1100 
1101  public:
1102  CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
1103  :DerivedValue<std::vector<std::tuple<FST,SND>>>(calc_name(val1, val2), alias),
1104  val1(val1),
1105  val2(val2) { }
1106 };
1107 
1113 template <typename T>
1114 class BoundValue : public DerivedValue<T>{
1115  protected:
1116  Function<T()>& f;
1118  this->value = f();
1119  }
1120  public:
1121  BoundValue(Function<T()>& f, const std::string alias="")
1122  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
1123  f(f) { }
1124 };
1125 
1130 template <typename T>
1131 class PointerValue : public DerivedValue<T*>{
1132  protected:
1133  void update_value(){ }
1134 
1135  public:
1136  PointerValue(const std::string& name, T* ptr, const std::string alias="")
1137  :DerivedValue<T*>(name, alias){
1138  this->value = ptr;
1139  }
1140 };
1141 
1145 template <typename T>
1146 class ConstantValue : public DerivedValue<T>{
1147  protected:
1148  void update_value(){ }
1149 
1150  public:
1151  ConstantValue(const std::string& name, T const_value, const std::string alias="")
1152  :DerivedValue<T>("const::"+name, alias),
1153  Value<T>::value(const_value) { }
1154 };
1155 }
1156 #endif // value_hpp
void update_value()
Updates the internal value.
Definition: value.hpp:1039
void update_value()
Updates the internal value.
Definition: value.hpp:1117
Find and return the maximum value of a vector.
Definition: value.hpp:918
Zips a series of vectors together.
Definition: value.hpp:639
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:897
void update_value()
Updates the internal value.
Definition: value.hpp:827
void update_value()
Updates the internal value.
Definition: value.hpp:563
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1020
Find combinations of items from an input vector.
Definition: value.hpp:1034
A generic value owning only a function object.
Definition: value.hpp:1114
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:512
Calculate the range of the values in a vector.
Definition: value.hpp:959
void update_value()
Updates the internal value.
Definition: value.hpp:782
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:738
A std::vector wrapper around a C-style array.
Definition: value.hpp:539
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:987
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:822
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1006
void update_value()
Updates the internal value.
Definition: value.hpp:901
Parent class to all Function classes.
Definition: value.hpp:143
void update_value()
Updates the internal value.
Definition: value.hpp:741
void update_value()
Updates the internal value.
Definition: value.hpp:876
A value supplied by the dataset, not derived.
Definition: value.hpp:448
Returns the elements in a vector that pass a test function.
Definition: value.hpp:845
Gets the Nth element from a tuple value.
Definition: value.hpp:761
Find and return the minimum value of a vector.
Definition: value.hpp:931
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:779
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:560
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:806
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:463
void update_value()
Updates the internal value.
Definition: value.hpp:992
void update_value()
Updates the internal value.
Definition: value.hpp:677
void update_value()
Updates the internal value.
Definition: value.hpp:1148
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:973
Returns the elements in a vector that pass a test function.
Definition: value.hpp:870
Calculate the mean value of a vector.
Definition: value.hpp:944
void update_value()
Updates the internal value.
Definition: value.hpp:544
A generic value.
Definition: value.hpp:415
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1077
void update_value()
Updates the internal value.
Definition: value.hpp:1082
void update_value()
Updates the internal value.
Definition: value.hpp:642
static std::string format_code(const std::string &code)
Attempt to invoke clang-format for the purpose of printing out nicely formatted functions to the log ...
Definition: value.hpp:176
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:489
void update_value()
Updates the internal value.
Definition: value.hpp:850
void update_value()
Updates the internal value.
Definition: value.hpp:1133
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:1146
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:1131
void update_value()
Updates the internal value.
Definition: value.hpp:764