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
294 void _reset(){
295 this->value_valid = false;
296 }
297
305 inline static std::map<const std::string, GenValue*> values;
306
314 inline static std::map<const std::string, GenValue*> aliases;
315
316 bool logging_enabled;
317
318 public:
319 GenValue(const std::string& name, const std::string& alias)
320 :name(name),
321 value_valid(false),
322 logging_enabled(false){
323 INFO("Registered value: \"" << name << "\" with alias: \"" << alias << "\"");
324 values[name] = this;
325 if (alias != "")
326 GenValue::alias(alias, this);
327 }
328
329 const std::string& get_name(){
330 return name;
331 }
332
333 void set_name(const std::string& new_name){
334 values[name] = nullptr;
335 name = new_name;
336 values[name] = this;
337 }
338
345 virtual void log() = 0;
346
347 static void reset(){
348 for (auto val : values){
349 if (val.second != nullptr){
350 val.second->_reset();
351 }
352 }
353 }
354
355 static GenValue* get_value(const std::string& name){
356 if (aliases[name] != nullptr)
357 return aliases[name];
358 else
359 return values[name];
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 static std::string fmt_name(const std::string& name){
464 return name;
465 }
466
467 T& get_value(){
468 if (!this->value_valid){
469 this->value_valid = true;
470 this->log();
471 }
472 return *val_ref;
473 }
474 };
475
476
492 template <typename T>
493 class DerivedValue : public Value<T>{
494 protected:
495 T value;
496
505 virtual void update_value() = 0;
506 public:
507 DerivedValue(const std::string& name, const std::string& alias="")
508 :Value<T>(name, alias){ }
509
510 void log(){
511 if(this->logging_enabled){
512 INFO(this->get_name() << ": " << this->value_to_string(value));
513 }
514 }
515
516 T& get_value(){
517 /* if (this->logging_enabled){ */
518 /* std::cout << "Getting value for " << this->get_name() << std::endl; */
519 /* } */
520 if (!this->value_valid){
521 /* if (this->logging_enabled){ */
522 /* std::cout << "Updating value for " << this->get_name() << std::endl; */
523 /* } */
524 update_value();
525 this->value_valid = true;
526 this->log();
527 }
528 return value;
529 }
530 };
531
532
542 template <typename T>
543 class WrapperVector : public DerivedValue<std::vector<T> >{
544 private:
545 Value<int>* size;
546 Value<T*>* data;
547
548 void update_value(){
549 int n = size->get_value();
550 T* data_ref = data->get_value();
551 this->value.assign(data_ref, data_ref+n);
552 }
553
554 public:
555 static std::string fmt_name(Value<int>* size, Value<T*>* data){
556 return "wrapper_vector("+size->get_name()+","+data->get_name()+")";
557 }
558
559 WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
560 :DerivedValue<std::vector<T> >(fmt_name(size,data), alias),
561 size(size), data(data){ }
562 };
563
567 template <typename T1, typename T2>
568 class Pair : public DerivedValue<std::pair<T1, T2> >{
569 protected:
570 std::pair<Value<T1>*, Value<T2>* > value_pair;
571 void update_value(){
572 this->value.first = value_pair.first->get_value();
573 this->value.second = value_pair.second->get_value();
574 }
575
576 public:
577 static std::string fmt_name(Value<T1> *value1, Value<T2> *value2){
578 return "pair("+value1->get_name()+","+value2->get_name()+")";
579 }
580
581 Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
582 :DerivedValue<std::pair<T1, T2> >(fmt_name(value1, value2), alias),
583 value_pair(value1, value2){ }
584 };
585
586 template<typename... T> class _Zip;
587 template<>
588 class _Zip<> {
589 protected:
590
591 int _get_size(){
592 return std::numeric_limits<int>::max();
593 }
594
595 std::tuple<> _get_at(int){
596 return std::make_tuple();
597 }
598
599 std::string _get_name(){
600 return "";
601 }
602
603 public:
604 _Zip() { }
605 };
606
607 template<typename Head, typename... Tail>
608 class _Zip<Head, Tail...> : private _Zip<Tail...> {
609 protected:
610 Value<std::vector<Head>>* head;
611
612 int _get_size(){
613 int this_size = head->get_value().size();
614 int rest_size = _Zip<Tail...>::_get_size();
615 return std::min(this_size, rest_size);
616 }
617
618 typename std::tuple<Head,Tail...> _get_at(int idx){
619 auto tail_tuple = _Zip<Tail...>::_get_at(idx);
620 return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
621 }
622
623 std::string _get_name(){
624 return head->get_name()+","+_Zip<Tail...>::_get_name();
625 }
626
627 public:
628 _Zip() { }
629
630 _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
631 : _Zip<Tail...>(tail...),
632 head(head) { }
633 };
634
635 namespace impl {
636 std::string zip_fmt_name(){
637 return "";
638 }
639
640 template<typename Head>
641 std::string zip_fmt_name(Value<std::vector<Head>>* head){
642 return head->get_name();
643 }
644
645 template<typename Head1, typename Head2, typename... Tail>
646 std::string zip_fmt_name(Value<std::vector<Head1>>* head1, Value<std::vector<Head2>>* head2, Value<std::vector<Tail>>*... tail){
647 return head1->get_name() + "," + zip_fmt_name<Head2, Tail...>(head2, tail...);
648 }
649 }
665 template <typename... ArgTypes>
666 class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
667 private _Zip<ArgTypes...>{
668 protected:
669 void update_value(){
670 this->value.clear();
671 int size = _Zip<ArgTypes...>::_get_size();
672 for(int i=0; i<size; i++){
673 this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
674 }
675 }
676
677 public:
678 static std::string fmt_name(Value<std::vector<ArgTypes>>*... args){
679 return "zip("+zip_fmt_name(args...)+")";
680 }
681
682 Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
683 :DerivedValue<std::vector<std::tuple<ArgTypes...>>>(fmt_name(args...), alias),
684 _Zip<ArgTypes...>(args...) { }
685 };
686
687 template<typename> class Map; // undefined
695 template <typename Ret, typename... ArgTypes>
696 class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
697 private:
698 typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
699 Function<Ret(ArgTypes...)>& fn;
700 arg_type* arg;
701
702 void update_value(){
703 this->value.clear();
704 for(auto tup : arg->get_value()){
705 this->value.push_back(call(fn,tup));
706 }
707 }
708
709 public:
710 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, arg_type* arg){
711 return "map("+fn.get_name()+":"+arg->get_name()+")";
712 }
713
714 Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
715 :DerivedValue<std::vector<Ret>>(fmt_name(fn, arg), alias),
716 fn(fn), arg(arg){ }
717
718 };
719
720 template<typename... T> class _Tuple;
721 template<>
722 class _Tuple<> {
723 protected:
724
725 std::tuple<> _get_value(){
726 return std::make_tuple();
727 }
728
729 public:
730 _Tuple() { }
731 };
732
733 template<typename Head, typename... Tail>
734 class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
735 protected:
736 Value<Head>* head;
737
738 typename std::tuple<Head,Tail...> _get_value(){
739 auto tail_tuple = _Tuple<Tail...>::_get_value();
740 return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
741 }
742
743 public:
744 _Tuple() { }
745
746 _Tuple(Value<Head>* head, Value<Tail>*... tail)
747 : _Tuple<Tail...>(tail...),
748 head(head) { }
749 };
750
751 namespace impl {
752 std::string tuple_fmt_name(){
753 return "";
754 }
755
756 template<typename Head>
757 std::string tuple_fmt_name(Value<Head>* head){
758 return head->get_name();
759 }
760
761 template<typename Head1, typename Head2, typename... Tail>
762 std::string tuple_fmt_name(Value<Head1>* head1, Value<Head2>* head2, Value<Tail>*... tail){
763 return head1->get_name() + "," + tuple_fmt_name<Head2, Tail...>(head2, tail...);
764 }
765 }
766
773 template <typename... ArgTypes>
774 class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
775 private _Tuple<ArgTypes...>{
776 protected:
777 void update_value(){
778 this->value = _Tuple<ArgTypes...>::_get_value();
779 }
780
781 public:
782 static std::string fmt_name(Value<ArgTypes>*... args){
783 return "tuple("+impl::tuple_fmt_name(args...)+")";
784 }
785
786 Tuple(Value<ArgTypes>*... args, const std::string& alias)
787 :DerivedValue<std::tuple<ArgTypes...>>(fmt_name(args...), alias),
788 _Tuple<ArgTypes...>(args...) { }
789 };
790
794 template <size_t N, typename... ArgTypes>
795 class DeTup : public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
796 Value<std::tuple<ArgTypes...>> tup;
797 protected:
798 void update_value(){
799 this->value = std::get<N>(tup->get_value());
800 }
801
802 public:
803 static std::string fmt_name(Value<std::tuple<ArgTypes...>>* tup){
804 return "detup("+tup->get_name()+")";
805 }
806
807 DeTup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias)
808 :DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(fmt_name(tup), alias),
809 tup(tup) { }
810 };
811
816 template <size_t N, typename... ArgTypes>
817 class DeTupVector : public DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>{
818 Value<std::vector<std::tuple<ArgTypes...>>>* tup;
819 protected:
820 void update_value(){
821 this->value.clear();
822 for( auto& t : tup->get_value()){
823 this->value.push_back(std::get<N>(t));
824 }
825 }
826
827 public:
828 static std::string fmt_name(Value<std::vector<std::tuple<ArgTypes...>>>* tup){
829 return "detup_vec("+tup->get_name()+")";
830 }
831
832 DeTupVector(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias)
833 :DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(fmt_name(tup), alias),
834 tup(tup) { }
835 };
836
837 template<typename> class Apply; // undefined
842 template <typename Ret, typename... ArgTypes>
843 class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
844 private:
845 Function<Ret(ArgTypes...)>& fn;
846 Value<std::tuple<ArgTypes...>>* arg;
847
848 void update_value(){
849 auto &tup = arg->get_value();
850 this->value = call(fn, tup);
851 }
852
853 public:
854 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg){
855 return "apply("+fn.get_name()+":"+arg->get_name()+")";
856 }
857
858 Apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias)
859 :DerivedValue<Ret>(fmt_name(fn,arg), alias),
860 fn(fn), arg(arg){ }
861
862 };
863
867 template<typename T>
868 class Count : public DerivedValue<int>{
869 private:
870 Function<bool(T)>& selector;
871 Value<std::vector<T> >* v;
872
873 void update_value(){
874 value = 0;
875 for(auto val : v->get_value()){
876 if(selector(val))
877 value++;
878 }
879 }
880
881 public:
882 static std::string fmt_name(Function<bool(T)>& selector, Value<std::vector<T>>* v){
883 return "count("+selector.get_name()+":"+v->get_name()+")";
884 }
885
886 Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
887 :DerivedValue<int>(fmt_name(selector,v), alias),
888 selector(selector), v(v) { }
889 };
890
894 template<typename T>
895 class Filter : public DerivedValue<std::vector<T>>{
896 private:
897 Function<bool(T)>& filter;
898 Value<std::vector<T> >* v;
899
900 void update_value(){
901 this->value.clear();
902 for(auto val : v->get_value()){
903 if(this->filter(val))
904 this->value.push_back(val);
905 }
906 }
907
908 public:
909 static std::string fmt_name(Function<bool(T)>& filter, Value<std::vector<T>>* v){
910 return "filter("+filter.get_name()+":"+v->get_name()+")";
911 }
912
913 Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
914 :DerivedValue<std::vector<T>>(fmt_name(filter,v), alias),
915 filter(filter), v(v) { }
916 };
917
923 template<typename... ArgTypes>
924 class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
925 private:
926 typedef std::vector<std::tuple<ArgTypes...>> value_type;
927 Function<bool(ArgTypes...)>& filter;
928 Value<value_type>* arg;
929
930 void update_value(){
931 this->value.clear();
932 for(auto val : arg->get_value()){
933 if(call(filter,val))
934 this->value.push_back(val);
935 }
936 }
937
938 public:
939 static std::string fmt_name(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg){
940 return "tup_filter("+filter.get_name()+":"+arg->get_name()+")";
941 }
942
943 TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
944 :DerivedValue<value_type>(fmt_name(filter, arg), alias),
945 filter(filter), arg(arg) { }
946 };
947
954 template <typename T>
955 class Reduce : public DerivedValue<T>{
956 private:
957 Function<T(std::vector<T>)>& reduce;
958
959 void update_value(){
960 this->value = reduce(v->get_value());
961 }
962
963 protected:
964 Value<std::vector<T> >* v;
965
966 public:
967 Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
968 :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
969 reduce(reduce), v(v) { }
970 };
971
975 template <typename T>
976 class Max : public Reduce<T>{
977 public:
978 static std::string fmt_name(Value<std::vector<T>>* v){
979 return "max("+v->get_name()+")";
980 }
981
982 Max(Value<std::vector<T>>* v, const std::string alias)
983 :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
984 FUNC(([](std::vector<T> vec){
985 return *std::max_element(vec.begin(), vec.end());}))),
986 v, alias) { }
987 };
988
992 template <typename T>
993 class Min : public Reduce<T>{
994 public:
995 static std::string fmt_name(Value<std::vector<T>>* v){
996 return "min("+v->get_name()+")";
997 }
998
999 Min(Value<std::vector<T>>* v, const std::string alias)
1000 :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
1001 FUNC(([](std::vector<T> vec){
1002 return *std::min_element(vec.begin(), vec.end());}))),
1003 v, alias) { }
1004 };
1005
1009 template <typename T>
1010 class Mean : public Reduce<T>{
1011 public:
1012 static std::string fmt_name(Value<std::vector<T>>* v){
1013 return "mean("+v->get_name()+")";
1014 }
1015
1016 Mean(Value<std::vector<T>>* v, const std::string alias)
1017 :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
1018 FUNC(([](std::vector<T> vec){
1019 int n = 0; T sum = 0;
1020 for (T e : vec){ n++; sum += e; }
1021 return n>0 ? sum / n : 0; }))),
1022 v, alias) { }
1023 };
1024
1028 template <typename T>
1029 class Range : public Reduce<T>{
1030 public:
1031 static std::string fmt_name(Value<std::vector<T>>* v){
1032 return "range("+v->get_name()+")";
1033 }
1034
1035 Range(Value<std::vector<T>>* v, const std::string alias)
1036 :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
1037 FUNC(([](std::vector<T> vec){
1038 auto minmax = std::minmax_element(vec.begin(), vec.end());
1039 return (*minmax.second) - (*minmax.first); }))),
1040 v, alias) { }
1041 };
1042
1046 template <typename T>
1047 class ElementOf : public Reduce<T>{
1048 public:
1049 ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
1050 :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
1051 FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
1052 v, alias) { }
1053 };
1054
1060 template <typename T>
1061 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
1062 private:
1063 Function<std::pair<T,int>(std::vector<T>)>& reduce;
1064 Value<std::vector<T> >* v;
1065
1066 void update_value(){
1067 this->value = reduce(v->get_value());
1068 }
1069
1070 public:
1071 ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
1072 :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
1073 reduce(reduce), v(v) { }
1074 };
1075
1079 template <typename T>
1080 class MaxIndex : public ReduceIndex<T>{
1081 public:
1082 MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
1083 :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
1084 FUNC(([](std::vector<T> vec){
1085 auto elptr = std::max_element(vec.begin(), vec.end());
1086 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1087 v, alias) { }
1088 };
1089
1093 template <typename T>
1094 class MinIndex : public ReduceIndex<T>{
1095 public:
1096 MinIndex(Value<std::vector<T>>* v, const std::string alias="")
1097 :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
1098 FUNC(([](std::vector<T> vec){
1099 auto elptr = std::min_element(vec.begin(), vec.end());
1100 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1101 v, alias) { }
1102 };
1103
1107 template <typename T, int Size>
1108 class Combinations : public DerivedValue<std::vector<typename HomoTuple<T,Size>::type>>{
1109 private:
1110 Value<std::vector<T>>* val;
1111 typedef typename HomoTuple<T,Size>::type tuple_type;
1112
1113 void update_value(){
1114 auto& v = val->get_value();
1115 int data_size = v.size();
1116 this->value.clear();
1117
1118 std::vector<bool> selector(data_size);
1119 std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}), true);
1120 do {
1121 std::array<T, Size> perm;
1122 int idx = 0;
1123 for (int i=0; i<data_size; i++){
1124 if (selector[i]){
1125 perm[idx] = v[i];
1126 idx++;
1127 if (idx == Size) break;
1128 }
1129 }
1130 this->value.push_back(a2t(perm));
1131 } while(std::prev_permutation(selector.begin(), selector.end()));
1132 }
1133
1134 public:
1135 static std::string fmt_name(Value<std::vector<T>>* val){
1136 std::stringstream ss;
1137 ss << "combinations(" << Size << "," << val->get_name() << ")";
1138 return ss.str();
1139 }
1140
1141 Combinations(Value<std::vector<T>>* val, const std::string alias="")
1142 :DerivedValue<std::vector<tuple_type>>(fmt_name(val), alias),
1143 val(val) { }
1144
1145 };
1146
1150 template <typename FST, typename SND>
1151 class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
1152 private:
1153 Value<std::vector<FST>>* val1;
1154 Value<std::vector<SND>>* val2;
1155
1156 void update_value(){
1157 this->value.clear();
1158 auto& v1 = val1->get_value();
1159 auto& v2 = val2->get_value();
1160 for(int i=0; i<v1.size(); i++){
1161 for(int j=0; j<v2.size(); j++){
1162 this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1163 }
1164 }
1165 }
1166
1167 static std::string calc_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1168 std::stringstream ss;
1169 ss << "cartProduct("
1170 << val1->get_name() << ", " << val2->get_name()
1171 << ")";
1172 return ss.str();
1173 }
1174
1175 public:
1176 static std::string fmt_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
1177 return "cartProduct("+val1->get_name()+", "+val2->get_name()+")";
1178 }
1179
1180 CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
1181 :DerivedValue<std::vector<std::tuple<FST,SND>>>(calc_name(val1, val2), alias),
1182 val1(val1), val2(val2) { }
1183 };
1184
1190 template <typename T>
1191 class BoundValue : public DerivedValue<T>{
1192 protected:
1193 Function<T()>& f;
1194 void update_value(){
1195 this->value = f();
1196 }
1197 public:
1198 BoundValue(Function<T()>& f, const std::string alias="")
1199 :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
1200 f(f) { }
1201 };
1202
1207 template <typename T>
1208 class PointerValue : public DerivedValue<T*>{
1209 protected:
1210 void update_value(){ }
1211
1212 public:
1213 PointerValue(const std::string& name, T* ptr, const std::string alias="")
1214 :DerivedValue<T*>(name, alias){
1215 this->value = ptr;
1216 }
1217 };
1218
1222 template <typename T>
1223 class ConstantValue : public DerivedValue<T>{
1224 protected:
1225 void update_value(){ }
1226
1227 public:
1228 ConstantValue(const std::string& name, T const_value, const std::string alias="")
1229 :DerivedValue<T>("const::"+name, alias),
1230 Value<T>::value(const_value) { }
1231 };
1232 }
1233 #endif // value_hpp
fv::Combinations::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:1113
fv::BoundValue::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:1194
fv::Max
Find and return the maximum value of a vector.
Definition: value.hpp:976
fv::Zip
Zips a series of vectors together.
Definition: value.hpp:666
fv::Reduce
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:955
fv::Count::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:873
fv::Pair::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:571
fv::MinIndex
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1094
fv::Combinations
Find combinations of items from an input vector.
Definition: value.hpp:1108
fv::BoundValue
A generic value owning only a function object.
Definition: value.hpp:1191
fv::DerivedValue::get_value
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:516
fv::Range
Calculate the range of the values in a vector.
Definition: value.hpp:1029
fv::DeTupVector::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:820
fv::Tuple
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:774
fv::WrapperVector
A std::vector wrapper around a C-style array.
Definition: value.hpp:543
std
fv::ReduceIndex
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:1061
fv::Count
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:868
fv::MaxIndex
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1080
fv::Reduce::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:959
fv::GenFunction
Parent class to all Function classes.
Definition: value.hpp:143
fv::Tuple::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:777
fv::TupFilter::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:930
fv::ObservedValue
A value supplied by the dataset, not derived.
Definition: value.hpp:448
fv::Filter
Returns the elements in a vector that pass a test function.
Definition: value.hpp:895
fv::DeTup
Gets the Nth element from a tuple value.
Definition: value.hpp:795
fv::Min
Find and return the minimum value of a vector.
Definition: value.hpp:993
fv::DeTupVector
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:817
fv::Pair
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:568
fv::a2t
decltype(auto) a2t(const std::array< T, N > &a)
Converts a std::vector to a std::tuple.
Definition: value.hpp:94
fv::Apply< Ret(ArgTypes...)>::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:848
fv::ObservedValue::get_value
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:467
fv::ReduceIndex::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:1066
fv::Map< Ret(ArgTypes...)>::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:702
fv::ConstantValue::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:1225
fv
The namespace containing all filval classes and functions.
Definition: api.hpp:38
fv::ElementOf
Extract the element at a specific index from a vector.
Definition: value.hpp:1047
fv::TupFilter
Returns the elements in a vector that pass a test function.
Definition: value.hpp:924
fv::Mean
Calculate the mean value of a vector.
Definition: value.hpp:1010
fv::WrapperVector::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:548
fv::Value
A templated value.
Definition: value.hpp:415
fv::CartProduct
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1151
fv::CartProduct::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:1156
fv::Zip::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:669
fv::GenFunction::format_code
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
log.hpp
fv::DerivedValue
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:493
fv::Filter::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:900
fv::PointerValue::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:1210
fv::Value::get_value
virtual T & get_value()=0
Calculate, if necessary, and return the value held by this object.
fv::ConstantValue
A Value which always returns the same value, supplied in the constructor.
Definition: value.hpp:1223
fv::GenFunction::function_registry
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
fv::PointerValue
A Value of a pointer.
Definition: value.hpp:1208
fv::DeTup::update_value
void update_value()
Updates the internal value.
Definition: value.hpp:798