53 #include <initializer_list> 64 template<
typename T,
int N,
bool Done,
typename... TYPES>
66 typedef _HomoTuple<T, N,
sizeof...(TYPES)+1==N, TYPES..., T> stype;
67 typedef typename stype::type type;
70 template<
typename T,
int N,
typename... TYPES>
71 struct _HomoTuple<T, N, true, TYPES...> {
72 typedef std::tuple<TYPES...> type;
76 template<
typename T,
int N>
78 typedef detail::_HomoTuple<T, N, N==0> stype;
79 typedef typename stype::type type;
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]...);
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());
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))...);
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>{});
113 template <
typename T,
int N,
int I>
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);
123 template <
typename T,
int N>
124 struct t2s_impl<T, N, 0>{
126 static std::string cvt(
typename HomoTuple<T,N>::type&, std::function<std::string(T)>&){
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);
137 template<
typename>
class Function;
148 inline static bool in_register_function=
false;
157 GenFunction(
const std::string& name,
const std::string& impl)
163 std::string& get_name(){
167 std::string& get_impl(){
177 std::stringstream code_out(
"");
178 std::string command(
"echo \""+code+
"\" | clang-format");
180 FILE *stream = popen(command.c_str(),
"r");
181 while (fgets(buffer, 255, stream) != NULL)
183 if (pclose(stream) == 0)
184 return code_out.str();
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);
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;
206 if (func ==
nullptr){
207 ERROR(
"Trying to register function which has already been registered with a different type");
210 func =
new Function<T>(name, impl, f);
213 in_register_function =
false;
217 template <
typename T>
218 static Function<T>& lookup_function(
const std::string& name){
220 CRITICAL(
"Function \"" << name <<
"\" not previously registered", -1);
223 if (func ==
nullptr){
224 CRITICAL(
"Function \"" << name <<
"\" request and register have mismatched types", -1);
243 template <
typename R,
typename... ArgTypes>
246 std::function<R(ArgTypes...)> f;
249 Function(
const std::string& name,
const std::string& impl, std::function<R(ArgTypes...)> f)
251 if (!in_register_function) {
252 WARNING(
"Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
255 Function(
const std::string& name, std::function<R(ArgTypes...)> f)
256 :Function(name,
"N/A", f){ }
259 R operator()(ArgTypes ...args){
266 #define FUNC(f) f, #f 275 typedef std::map<std::string, GenValue*> ValueSet;
295 this->value_valid =
false;
305 inline static std::map<const std::string, GenValue*> values;
314 inline static std::map<const std::string, GenValue*> aliases;
316 bool logging_enabled;
319 GenValue(
const std::string& name,
const std::string& alias)
322 logging_enabled(
false){
323 INFO(
"Registered value: \"" << name <<
"\" with alias: \"" << alias <<
"\"");
326 GenValue::alias(alias,
this);
329 const std::string& get_name(){
333 void set_name(
const std::string& new_name){
334 values[name] =
nullptr;
345 virtual void log() = 0;
348 for (
auto val : values){
349 if (val.second !=
nullptr){
350 val.second->_reset();
355 static GenValue* get_value(
const std::string& name){
356 if (aliases[name] !=
nullptr)
357 return aliases[name];
362 static void alias(
const std::string& name, GenValue* value){
363 if (aliases[name] !=
nullptr){
364 WARNING(
"WARNING: alias \"" << name <<
"\" overrides previous entry.");
366 aliases[name] = value;
369 static GenValue* alias(
const std::string& name){
370 if (values[name] !=
nullptr){
371 WARNING(
"Alias \"" << name <<
"\" does not exist.");
373 return aliases[name];
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;
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();
393 ss <<
"\tALIAS::\"" << alias.first <<
"\" referring to \"" << orig <<
"\"" << std::endl;
397 friend std::ostream& operator<<(std::ostream& os,
const GenValue& gv);
399 std::ostream& operator<<(std::ostream& os, GenValue& gv){
414 template <
typename T>
417 std::function<std::string(T)> value_to_string;
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;
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;
432 void disable_logging(){
433 logging_enabled =
false;
447 template <
typename T>
453 ObservedValue(
const std::string& name, T* val_ref,
const std::string& alias=
"")
458 if(this->logging_enabled){
459 INFO(this->get_name() <<
": " << this->value_to_string(*val_ref));
463 static std::string fmt_name(
const std::string& name){
468 if (!this->value_valid){
469 this->value_valid =
true;
492 template <
typename T>
505 virtual void update_value() = 0;
507 DerivedValue(
const std::string& name,
const std::string& alias=
"")
511 if(this->logging_enabled){
512 INFO(this->get_name() <<
": " << this->value_to_string(value));
520 if (!this->value_valid){
525 this->value_valid =
true;
542 template <
typename T>
551 this->value.assign(data_ref, data_ref+n);
556 return "wrapper_vector("+size->get_name()+
","+data->get_name()+
")";
561 size(size), data(data){ }
567 template <
typename T1,
typename T2>
570 std::pair<Value<T1>*,
Value<T2>* > value_pair;
572 this->value.first = value_pair.first->get_value();
573 this->value.second = value_pair.second->get_value();
578 return "pair("+value1->get_name()+
","+value2->get_name()+
")";
583 value_pair(value1, value2){ }
586 template<
typename... T>
class _Zip;
592 return std::numeric_limits<int>::max();
595 std::tuple<> _get_at(
int){
596 return std::make_tuple();
599 std::string _get_name(){
607 template<
typename Head,
typename... Tail>
608 class _Zip<Head, Tail...> :
private _Zip<Tail...> {
613 int this_size = head->
get_value().size();
614 int rest_size = _Zip<Tail...>::_get_size();
615 return std::min(this_size, rest_size);
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);
623 std::string _get_name(){
624 return head->get_name()+
","+_Zip<Tail...>::_get_name();
630 _Zip(
Value<std::vector<Head>>* head,
Value<std::vector<Tail>>*... tail)
631 : _Zip<Tail...>(tail...),
636 std::string zip_fmt_name(){
640 template<
typename Head>
641 std::string zip_fmt_name(
Value<std::vector<Head>>* head){
642 return head->get_name();
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...);
665 template <
typename... ArgTypes>
667 private _Zip<ArgTypes...>{
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));
678 static std::string fmt_name(
Value<std::vector<ArgTypes>>*... args){
679 return "zip("+zip_fmt_name(args...)+
")";
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...) { }
687 template<
typename>
class Map;
695 template <
typename Ret,
typename... ArgTypes>
698 typedef Value<std::vector<std::tuple<ArgTypes...>>>
arg_type;
699 Function<Ret(ArgTypes...)>& fn;
705 this->value.push_back(call(fn,tup));
710 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn,
arg_type* arg){
711 return "map("+fn.get_name()+
":"+arg->get_name()+
")";
714 Map(Function<Ret(ArgTypes...)>& fn,
arg_type* arg,
const std::string& alias)
720 template<
typename... T>
class _Tuple;
725 std::tuple<> _get_value(){
726 return std::make_tuple();
733 template<
typename Head,
typename... Tail>
734 class _Tuple<Head, Tail...> :
private _Tuple<Tail...> {
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);
747 : _Tuple<Tail...>(tail...),
752 std::string tuple_fmt_name(){
756 template<
typename Head>
758 return head->get_name();
761 template<
typename Head1,
typename Head2,
typename... Tail>
763 return head1->get_name() +
"," + tuple_fmt_name<Head2, Tail...>(head2, tail...);
773 template <
typename... ArgTypes>
775 private _Tuple<ArgTypes...>{
778 this->value = _Tuple<ArgTypes...>::_get_value();
783 return "tuple("+impl::tuple_fmt_name(args...)+
")";
787 :
DerivedValue<std::tuple<ArgTypes...>>(fmt_name(args...), alias),
788 _Tuple<ArgTypes...>(args...) { }
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;
799 this->value = std::get<N>(tup->get_value());
803 static std::string fmt_name(
Value<std::tuple<ArgTypes...>>* tup){
804 return "detup("+tup->get_name()+
")";
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),
816 template <
size_t N,
typename... ArgTypes>
818 Value<std::vector<std::tuple<ArgTypes...>>>* tup;
822 for(
auto& t : tup->get_value()){
823 this->value.push_back(std::get<N>(t));
828 static std::string fmt_name(
Value<std::vector<std::tuple<ArgTypes...>>>* tup){
829 return "detup_vec("+tup->get_name()+
")";
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),
837 template<
typename>
class Apply;
842 template <
typename Ret,
typename... ArgTypes>
845 Function<Ret(ArgTypes...)>& fn;
846 Value<std::tuple<ArgTypes...>>* arg;
849 auto &tup = arg->get_value();
850 this->value = call(fn, tup);
854 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg){
855 return "apply("+fn.get_name()+
":"+arg->get_name()+
")";
858 Apply(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg,
const std::string& alias)
870 Function<bool(T)>& selector;
882 static std::string fmt_name(Function<
bool(T)>& selector,
Value<std::vector<T>>* v){
883 return "count("+selector.get_name()+
":"+v->get_name()+
")";
886 Count(Function<
bool(T)>& selector,
Value<std::vector<T>>* v,
const std::string alias)
888 selector(selector), v(v) { }
897 Function<bool(T)>& filter;
903 if(this->filter(val))
904 this->value.push_back(val);
909 static std::string fmt_name(Function<
bool(T)>& filter,
Value<std::vector<T>>* v){
910 return "filter("+filter.get_name()+
":"+v->get_name()+
")";
913 Filter(Function<
bool(T)>& filter,
Value<std::vector<T>>* v,
const std::string alias)
915 filter(filter), v(v) { }
923 template<
typename... ArgTypes>
926 typedef std::vector<std::tuple<ArgTypes...>> value_type;
927 Function<bool(ArgTypes...)>& filter;
934 this->value.push_back(val);
939 static std::string fmt_name(Function<
bool(ArgTypes...)>& filter,
Value<value_type>* arg){
940 return "tup_filter("+filter.get_name()+
":"+arg->get_name()+
")";
945 filter(filter), arg(arg) { }
954 template <
typename T>
957 Function<T(std::vector<T>)>& reduce;
960 this->value = reduce(v->get_value());
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) { }
975 template <
typename T>
978 static std::string fmt_name(
Value<std::vector<T>>* v){
979 return "max("+v->get_name()+
")";
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());}))),
992 template <
typename T>
995 static std::string fmt_name(
Value<std::vector<T>>* v){
996 return "min("+v->get_name()+
")";
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());}))),
1009 template <
typename T>
1012 static std::string fmt_name(
Value<std::vector<T>>* v){
1013 return "mean("+v->get_name()+
")";
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; }))),
1028 template <
typename T>
1031 static std::string fmt_name(
Value<std::vector<T>>* v){
1032 return "range("+v->get_name()+
")";
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); }))),
1046 template <
typename T>
1050 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"elementOf",
1051 FUNC(([index](std::vector<T> vec){
return vec[index->
get_value()];}))),
1060 template <
typename T>
1063 Function<std::pair<T,int>(std::vector<T>)>& reduce;
1067 this->value = reduce(v->get_value());
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) { }
1079 template <
typename T>
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())); }))),
1093 template <
typename T>
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())); }))),
1107 template <
typename T,
int Size>
1111 typedef typename HomoTuple<T,Size>::type tuple_type;
1115 int data_size = v.size();
1116 this->value.clear();
1118 std::vector<bool> selector(data_size);
1119 std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}),
true);
1121 std::array<T, Size> perm;
1123 for (
int i=0; i<data_size; i++){
1127 if (idx == Size)
break;
1130 this->value.push_back(
a2t(perm));
1131 }
while(std::prev_permutation(selector.begin(), selector.end()));
1135 static std::string fmt_name(
Value<std::vector<T>>* val){
1136 std::stringstream ss;
1137 ss <<
"combinations(" << Size <<
"," << val->get_name() <<
")";
1150 template <
typename FST,
typename SND>
1157 this->value.clear();
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]));
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()
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()+
")";
1180 CartProduct(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2,
const std::string alias=
"")
1182 val1(val1), val2(val2) { }
1190 template <
typename T>
1198 BoundValue(Function<T()>& f,
const std::string alias=
"")
1207 template <
typename T>
1213 PointerValue(
const std::string& name, T* ptr,
const std::string alias=
"")
1222 template <
typename T>
1228 ConstantValue(
const std::string& name, T const_value,
const std::string alias=
"")
void update_value()
Updates the internal value.
Definition: value.hpp:1113
void update_value()
Updates the internal value.
Definition: value.hpp:1194
Find and return the maximum value of a vector.
Definition: value.hpp:976
Zips a series of vectors together.
Definition: value.hpp:666
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:955
void update_value()
Updates the internal value.
Definition: value.hpp:873
void update_value()
Updates the internal value.
Definition: value.hpp:571
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1094
Find combinations of items from an input vector.
Definition: value.hpp:1108
A generic value owning only a function object.
Definition: value.hpp:1191
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:516
Calculate the range of the values in a vector.
Definition: value.hpp:1029
void update_value()
Updates the internal value.
Definition: value.hpp:820
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:774
A std::vector wrapper around a C-style array.
Definition: value.hpp:543
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:1061
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:868
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1080
void update_value()
Updates the internal value.
Definition: value.hpp:959
Parent class to all Function classes.
Definition: value.hpp:143
void update_value()
Updates the internal value.
Definition: value.hpp:777
void update_value()
Updates the internal value.
Definition: value.hpp:930
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:895
Gets the Nth element from a tuple value.
Definition: value.hpp:795
Find and return the minimum value of a vector.
Definition: value.hpp:993
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:817
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:568
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:848
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:467
void update_value()
Updates the internal value.
Definition: value.hpp:1066
void update_value()
Updates the internal value.
Definition: value.hpp:702
void update_value()
Updates the internal value.
Definition: value.hpp:1225
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:1047
Returns the elements in a vector that pass a test function.
Definition: value.hpp:924
Calculate the mean value of a vector.
Definition: value.hpp:1010
void update_value()
Updates the internal value.
Definition: value.hpp:548
A templated value.
Definition: value.hpp:415
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1151
void update_value()
Updates the internal value.
Definition: value.hpp:1156
void update_value()
Updates the internal value.
Definition: value.hpp:669
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:493
void update_value()
Updates the internal value.
Definition: value.hpp:900
void update_value()
Updates the internal value.
Definition: value.hpp:1210
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:1223
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:1208
void update_value()
Updates the internal value.
Definition: value.hpp:798