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 template <typename F, typename TUPLE, bool Done, int Total, int... N>
64 struct call_impl
65 {
66  static auto call(F& f, TUPLE && t)
67  {
68  return call_impl<F, TUPLE, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<TUPLE>(t));
69  }
70 };
71 
72 template <typename F, typename TUPLE, int Total, int... N>
73 struct call_impl<F, TUPLE, true, Total, N...>
74 {
75  static auto call(F& f, TUPLE && t)
76  {
77  return f(std::get<N>(std::forward<TUPLE>(t))...);
78  }
79 };
80 
85 template <typename F, typename TUPLE>
86 auto call(F& f, TUPLE && t)
87 {
88  typedef typename std::decay<TUPLE>::type ttype;
89  return call_impl<F, TUPLE, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<TUPLE>(t));
90 }
91 
92 template<typename> class Function; // undefined
93 
98 class GenFunction {
99  private:
100  std::string name;
101  std::string impl;
102  protected:
103  inline static bool in_register_function=false;
104 
105  public:
110  inline static std::map<const std::string, GenFunction*> function_registry;
111 
112  GenFunction(const std::string& name, const std::string& impl)
113  :name(name),
114  impl(impl){ }
115 
116  virtual ~GenFunction() { };
117 
118  std::string& get_name(){
119  return name;
120  }
121 
127  static std::string format_code(const std::string& code){
128  std::stringstream code_out("");
129  std::string command("echo \""+code+"\" | clang-format");
130  char buffer[255];
131  FILE *stream = popen(command.c_str(), "r");
132  while (fgets(buffer, 255, stream) != NULL)
133  code_out << buffer;
134  if (pclose(stream) == 0)
135  return code_out.str();
136  else
137  return code;
138  }
139 
140  static std::string summary(){
141  std::stringstream ss;
142  ss << "The following functions have been registered" << std::endl;
143  for(auto p : function_registry){
144  if (p.second == nullptr) continue;
145  ss << "-->" << p.second->name << "@" << p.second << std::endl;
146  ss << format_code(p.second->impl);
147  }
148  return ss.str();
149  }
150 
151  template <typename T>
152  static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
153  in_register_function = true;
154  Function<T>* func;
155  if (GenFunction::function_registry[name] != nullptr){
156  func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
157  if (func == nullptr){
158  ERROR("Trying to register function which has already been registered with a different type");
159  }
160  } else {
161  func = new Function<T>(name, impl, f);
162  GenFunction::function_registry[name] = func;
163  }
164  in_register_function = false;
165  return *func;
166  }
167 
168  template <typename T>
169  static Function<T>& lookup_function(const std::string& name){
170  if (GenFunction::function_registry[name] == nullptr){
171  CRITICAL("Function \"" << name << "\" not previously registered", -1);
172  } else {
173  Function<T>* func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
174  if (func == nullptr){
175  CRITICAL("Function \"" << name << "\" request and register have mismatched types", -1);
176  }
177  return *GenFunction::function_registry[name];
178  }
179  }
180 };
181 
182 
194 template <typename R, typename... ArgTypes>
195 class Function<R(ArgTypes...)> : public GenFunction {
196  private:
197  std::function<R(ArgTypes...)> f;
198 
199  public:
200  Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
201  :GenFunction(name, impl), f(f){
202  if (!in_register_function) {
203  WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
204  }
205  }
206  Function(const std::string& name, std::function<R(ArgTypes...)> f)
207  :Function(name, "N/A", f){ }
208  ~Function() { }
209 
210  R operator()(ArgTypes ...args){
211  return f(args...);
212  }
213 
214 };
215 
216 
217 #define FUNC(f) f, #f
218 
225 class GenValue;
226 typedef std::map<std::string, GenValue*> ValueSet;
227 class GenValue{
228  private:
234  std::string name;
235 
236  protected:
243  virtual void _reset() = 0;
251  inline static std::map<const std::string, GenValue*> values;
259  inline static std::map<const std::string, GenValue*> aliases;
260 
261  public:
262  GenValue(const std::string& name, const std::string& alias)
263  :name(name){
264  values[name] = this;
265  if (alias != "")
266  GenValue::alias(alias, this);
267  }
268 
269  const std::string& get_name(){
270  return name;
271  }
272 
273  void set_name(const std::string& new_name){
274  values[name] = nullptr;
275  name = new_name;
276  values[name] = this;
277  }
278 
279  static void reset(){
280  for (auto val : values){
281  if (val.second != nullptr){
282  val.second->_reset();
283  }
284  }
285  }
286 
287  static GenValue* get_value(const std::string& name){
288  if (aliases[name] != nullptr)
289  return aliases[name];
290  else if (values[name] != nullptr)
291  return values[name];
292  else{
293  ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
294  << summary());
295  CRITICAL("Aborting... :(",-1);
296  }
297  }
298 
299  static void alias(const std::string& name, GenValue* value){
300  if (aliases[name] != nullptr){
301  WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
302  }
303  aliases[name] = value;
304  }
305 
306  static GenValue* alias(const std::string& name){
307  if (values[name] != nullptr){
308  WARNING("Alias \"" << name << "\" does not exist.");
309  }
310  return aliases[name];
311  }
312 
313  static std::string summary(){
314  std::stringstream ss;
315  ss << "The following values have been created: " << std::endl;
316  for (auto value : values){
317  if (value.second == nullptr) continue;
318  ss << "\t\"" << value.first << "\" at address " << value.second << std::endl;
319  }
320  ss << "And these aliases:" << std::endl;
321  for (auto alias : aliases){
322  std::string orig("VOID");
323  if (alias.second == nullptr) continue;
324  for (auto value : values){
325  if (alias.second == value.second){
326  orig = value.second->get_name();
327  break;
328  }
329  }
330  ss << "\t\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
331  }
332  return ss.str();
333  }
334  friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
335 };
336 std::ostream& operator<<(std::ostream& os, GenValue& gv){
337  os << gv.get_name();
338  return os;
339 }
340 
341 
351 template <typename T>
352 class Value : public GenValue{
353  public:
354  Value(const std::string& name, const std::string& alias="")
355  :GenValue(name, alias){ }
358  virtual T& get_value() = 0;
359 };
360 
361 
371 template <typename T>
372 class ObservedValue : public Value<T>{
373  private:
374  T *val_ref;
375  void _reset(){ }
376 
377  public:
378  ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
379  :Value<T>(name, alias),
380  val_ref(val_ref){ }
381  T& get_value(){
382  return *val_ref;
383  }
384 };
385 
386 
402 template <typename T>
403 class DerivedValue : public Value<T>{
404  private:
405  void _reset(){
406  value_valid = false;
407  }
408  protected:
409  T value;
410  bool value_valid;
411 
420  virtual void update_value() = 0;
421  public:
422  DerivedValue(const std::string& name, const std::string& alias="")
423  :Value<T>(name, alias),
424  value_valid(false) { }
425 
426  T& get_value(){
427  if (!value_valid){
428  update_value();
429  value_valid = true;
430  }
431  return value;
432  }
433 };
434 
435 
445 template <typename T>
446 class WrapperVector : public DerivedValue<std::vector<T> >{
447  private:
448  Value<int>* size;
449  Value<T*>* data;
450 
451  void update_value(){
452  int n = size->get_value();
453  T* data_ref = data->get_value();
454  this->value.assign(data_ref, data_ref+n);
455  }
456 
457  public:
458  WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
459  :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
460  size(size), data(data){ }
461 };
462 
466 template <typename T1, typename T2>
467 class Pair : public DerivedValue<std::pair<T1, T2> >{
468  protected:
469  std::pair<Value<T1>*, Value<T2>* > value_pair;
470  void update_value(){
471  this->value.first = value_pair.first->get_value();
472  this->value.second = value_pair.second->get_value();
473  }
474 
475  public:
476  Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
477  :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
478  value_pair(value1, value2){ }
479 };
480 
481 template<typename... T> class _Zip;
482 template<>
483 class _Zip<> {
484  protected:
485 
486  int _get_size(){
487  return std::numeric_limits<int>::max();
488  }
489 
490  std::tuple<> _get_at(int idx){
491  return std::make_tuple();
492  }
493 
494  std::string _get_name(){
495  return "";
496  }
497 
498  public:
499  _Zip() { }
500 };
501 
502 template<typename Head, typename... Tail>
503 class _Zip<Head, Tail...> : private _Zip<Tail...> {
504  protected:
506 
507  int _get_size(){
508  int this_size = head->get_value().size();
509  int rest_size = _Zip<Tail...>::_get_size();
510  return std::min(this_size, rest_size);
511  }
512 
513  typename std::tuple<Head,Tail...> _get_at(int idx){
514  auto tail_tuple = _Zip<Tail...>::_get_at(idx);
515  return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
516  }
517 
518  std::string _get_name(){
519  return head->get_name()+","+_Zip<Tail...>::_get_name();
520  }
521 
522  public:
523  _Zip() { }
524 
525  _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
526  : _Zip<Tail...>(tail...),
527  head(head) { }
528 };
529 
545 template <typename... ArgTypes>
546 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
547  private _Zip<ArgTypes...>{
548  protected:
549  void update_value(){
550  this->value.clear();
551  int size = _Zip<ArgTypes...>::_get_size();
552  for(int i=0; i<size; i++){
553  this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
554  }
555  }
556 
557  std::string _get_name(){
558  return "zip("+_Zip<ArgTypes...>::_get_name()+")";
559  }
560 
561  public:
562  Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
563  :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
564  _Zip<ArgTypes...>(args...) {
565  this->set_name(_get_name());
566  }
567 };
568 
569 template<typename> class Map; // undefined
577 template <typename Ret, typename... ArgTypes>
578 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
579  private:
580  typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
581  Function<Ret(ArgTypes...)>& fn;
582  arg_type* arg;
583 
584  void update_value(){
585  this->value.clear();
586  for(auto tup : arg->get_value()){
587  this->value.push_back(call(fn,tup));
588  }
589  }
590 
591  public:
592  Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
593  :DerivedValue<std::vector<Ret>>("map("+fn.get_name()+":"+arg->get_name()+")", alias),
594  fn(fn), arg(arg){ }
595 
596 };
602 template<typename... ArgTypes>
603 class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
604  private:
605  typedef std::vector<std::tuple<ArgTypes...>> value_type;
606  Function<bool(ArgTypes...)>& filter;
607  Value<value_type>* arg;
608 
609  void update_value(){
610  this->value.clear();
611  for(auto val : arg->get_value()){
612  if(call(filter,val))
613  this->value.push_back(val);
614  }
615  }
616 
617  public:
618  TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
619  :DerivedValue<value_type>("filter("+filter.get_name()+":"+arg->get_name()+")", alias),
620  filter(filter), arg(arg) { }
621 };
622 
623 template<typename... T> class _Tuple;
624 template<>
625 class _Tuple<> {
626  protected:
627 
628  std::tuple<> _get_value(){
629  return std::make_tuple();
630  }
631 
632  std::string _get_name(){
633  return "";
634  }
635 
636  public:
637  _Tuple() { }
638 };
639 
640 template<typename Head, typename... Tail>
641 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
642  protected:
643  Value<Head>* head;
644 
645  typename std::tuple<Head,Tail...> _get_value(){
646  auto tail_tuple = _Tuple<Tail...>::_get_value();
647  return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
648  }
649 
650 
651  std::string _get_name(){
652  return head->get_name()+","+_Tuple<Tail...>::_get_name();
653  }
654 
655  public:
656  _Tuple() { }
657 
658  _Tuple(Value<Head>* head, Value<Tail>*... tail)
659  : _Tuple<Tail...>(tail...),
660  head(head) { }
661 };
662 
669 template <typename... ArgTypes>
670 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
671  private _Tuple<ArgTypes...>{
672  protected:
673  void update_value(){
674  this->value = _Tuple<ArgTypes...>::_get_value();
675  }
676 
677  std::string _get_name(){
678  return "tuple("+_Tuple<ArgTypes...>::_get_name()+")";
679  }
680 
681  public:
682  Tuple(Value<ArgTypes>*... args, const std::string& alias)
683  :DerivedValue<std::tuple<ArgTypes...>>("", alias),
684  _Tuple<ArgTypes...>(args...) {
685  this->set_name(_get_name());
686  }
687 };
688 
689 template<typename> class Apply; // undefined
694 template <typename Ret, typename... ArgTypes>
695 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
696  private:
697  Function<Ret(ArgTypes...)>& fn;
698  Tuple<ArgTypes...>* arg;
699 
700  void update_value(){
701  auto &tup = arg->get_value();
702  this->value = call(fn, tup);
703  }
704 
705  public:
706  Apply(Function<Ret(ArgTypes...)>& fn, Tuple<ArgTypes...>* arg, const std::string& alias)
707  :DerivedValue<Ret>("apply("+fn.get_name()+":"+arg->get_name()+")", alias),
708  fn(fn), arg(arg){ }
709 
710 };
711 
712 
716 template<typename T>
717 class Count : public DerivedValue<int>{
718  private:
719  Function<bool(T)>& selector;
721 
722  void update_value(){
723  value = 0;
724  for(auto val : v->get_value()){
725  if(selector(val))
726  value++;
727  }
728  }
729 
730  public:
731  Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
732  :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
733  selector(selector), v(v) { }
734 };
735 
739 template<typename T>
740 class Filter : public DerivedValue<std::vector<T>>{
741  private:
742  Function<bool(T)>& filter;
744 
745  void update_value(){
746  this->value.clear();
747  for(auto val : v->get_value()){
748  if(selector(val))
749  this->value.push_back(val);
750  }
751  }
752 
753  public:
754  Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
755  :DerivedValue<std::vector<T>>("filter("+filter.get_name()+":"+v->get_name()+")", alias),
756  filter(filter), v(v) { }
757 };
758 
759 
766 template <typename T>
767 class Reduce : public DerivedValue<T>{
768  private:
769  Function<T(std::vector<T>)>& reduce;
770 
771  void update_value(){
772  this->value = reduce(v->get_value());
773  }
774 
775  protected:
777 
778  public:
779  Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
780  :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
781  reduce(reduce), v(v) { }
782 };
783 
787 template <typename T>
788 class Max : public Reduce<T>{
789  public:
790  Max(Value<std::vector<T>>* v, const std::string alias)
791  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
792  FUNC(([](std::vector<T> vec){
793  return *std::max_element(vec.begin(), vec.end());}))),
794  v, alias) { }
795 };
796 
800 template <typename T>
801 class Min : public Reduce<T>{
802  public:
803  Min(Value<std::vector<T>>* v, const std::string alias)
804  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
805  FUNC(([](std::vector<T> vec){
806  return *std::min_element(vec.begin(), vec.end());}))),
807  v, alias) { }
808 };
809 
813 template <typename T>
814 class Mean : public Reduce<T>{
815  public:
816  Mean(Value<std::vector<T>>* v, const std::string alias)
817  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
818  FUNC(([](std::vector<T> vec){
819  int n = 0; T sum = 0;
820  for (T e : vec){ n++; sum += e; }
821  return n>0 ? sum / n : 0; }))),
822  v, alias) { }
823 };
824 
828 template <typename T>
829 class Range : public Reduce<T>{
830  public:
831  Range(Value<std::vector<T>>* v, const std::string alias)
832  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
833  FUNC(([](std::vector<T> vec){
834  auto minmax = std::minmax_element(vec.begin(), vec.end());
835  return (*minmax.second) - (*minmax.first); }))),
836  v, alias) { }
837 };
838 
842 template <typename T>
843 class ElementOf : public Reduce<T>{
844  public:
845  ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
846  :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
847  FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
848  v, alias) { }
849 };
850 
856 template <typename T>
857 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
858  private:
859  Function<std::pair<T,int>(std::vector<T>)>& reduce;
861 
862  void update_value(){
863  this->value = reduce(v->get_value());
864  }
865 
866  public:
867  ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
868  :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
869  reduce(reduce), v(v) { }
870 };
871 
875 template <typename T>
876 class MaxIndex : public ReduceIndex<T>{
877  public:
878  MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
879  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
880  FUNC(([](std::vector<T> vec){
881  auto elptr = std::max_element(vec.begin(), vec.end());
882  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
883  v, alias) { }
884 };
885 
889 template <typename T>
890 class MinIndex : public ReduceIndex<T>{
891  public:
892  MinIndex(Value<std::vector<T>>* v, const std::string alias="")
893  :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
894  FUNC(([](std::vector<T> vec){
895  auto elptr = std::min_element(vec.begin(), vec.end());
896  return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
897  v, alias) { }
898 };
899 
905 template <typename T>
906 class BoundValue : public DerivedValue<T>{
907  protected:
908  Function<T()>& f;
909  void update_value(){
910  this->value = f();
911  }
912  public:
913  BoundValue(Function<T()>& f, const std::string alias="")
914  :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
915  f(f) { }
916 };
917 
922 template <typename T>
923 class PointerValue : public DerivedValue<T*>{
924  protected:
925  void update_value(){ }
926 
927  public:
928  PointerValue(const std::string& name, T* ptr, const std::string alias="")
929  :DerivedValue<T*>(name, alias){
930  this->value = ptr;
931  }
932 };
933 
937 template <typename T>
938 class ConstantValue : public DerivedValue<T>{
939  protected:
940  void update_value(){ }
941 
942  public:
943  ConstantValue(const std::string& name, T const_value, const std::string alias="")
944  :DerivedValue<T>("const::"+name, alias),
945  Value<T>::value(const_value) { }
946 };
947 }
948 #endif // value_hpp
void update_value()
Updates the internal value.
Definition: value.hpp:909
Find and return the maximum value of a vector.
Definition: value.hpp:788
Zips a series of vectors together.
Definition: value.hpp:546
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:767
void update_value()
Updates the internal value.
Definition: value.hpp:722
void update_value()
Updates the internal value.
Definition: value.hpp:470
Find and return the minimum value of a vector and its index.
Definition: value.hpp:890
A generic value owning only a function object.
Definition: value.hpp:906
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:426
Calculate the range of the values in a vector.
Definition: value.hpp:829
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:670
A std::vector wrapper around a C-style array.
Definition: value.hpp:446
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:857
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:717
Find and return the maximum value of a vector and its index.
Definition: value.hpp:876
void update_value()
Updates the internal value.
Definition: value.hpp:771
Parent class to all Function classes.
Definition: value.hpp:98
void update_value()
Updates the internal value.
Definition: value.hpp:673
void update_value()
Updates the internal value.
Definition: value.hpp:609
A value supplied by the dataset, not derived.
Definition: value.hpp:372
Returns the elements in a vector that pass a test function.
Definition: value.hpp:740
Find and return the minimum value of a vector.
Definition: value.hpp:801
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:467
void update_value()
Updates the internal value.
Definition: value.hpp:700
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:381
void update_value()
Updates the internal value.
Definition: value.hpp:862
void update_value()
Updates the internal value.
Definition: value.hpp:584
void update_value()
Updates the internal value.
Definition: value.hpp:940
The namespace containing all filval classes and functions.
Definition: api.hpp:6
Extract the element at a specific index from a vector.
Definition: value.hpp:843
Returns the elements in a vector that pass a test function.
Definition: value.hpp:603
Calculate the mean value of a vector.
Definition: value.hpp:814
void update_value()
Updates the internal value.
Definition: value.hpp:451
A generic value.
Definition: value.hpp:352
void update_value()
Updates the internal value.
Definition: value.hpp:549
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:127
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:403
void update_value()
Updates the internal value.
Definition: value.hpp:745
void update_value()
Updates the internal value.
Definition: value.hpp:925
virtual T & get_value()=0
Calculate, if necessary, and return the value held by this object.
auto call(F &f, TUPLE &&t)
This calls a function of type F with the contents of the tuple as separate arguments.
Definition: value.hpp:86
A Value which always returns the same value, supplied in the constructor.
Definition: value.hpp:938
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:110
A Value of a pointer.
Definition: value.hpp:923