46 #include <initializer_list> 65 template<
typename T,
int N,
bool Done,
typename... TYPES>
67 typedef _HomoTuple<T, N,
sizeof...(TYPES)+1==N, TYPES..., T> stype;
68 typedef typename stype::type type;
71 template<
typename T,
int N,
typename... TYPES>
72 struct _HomoTuple<T, N, true, TYPES...> {
73 typedef std::tuple<TYPES...> type;
77 template<
typename T,
int N>
79 typedef detail::_HomoTuple<T, N, N==0> stype;
80 typedef typename stype::type type;
85 template<
typename Array, std::size_t... I>
86 decltype(
auto) a2t_impl(const Array& a,
std::index_sequence<I...>){
87 return std::make_tuple(a[I]...);
94 template<
typename T, std::
size_t N,
typename Indices = std::make_index_sequence<N>>
95 decltype(
auto)
a2t(const
std::array<T, N>& a){
96 return detail::a2t_impl(a, Indices());
101 template<
typename R,
typename Tuple, std::size_t... Is>
102 decltype(
auto) t2v_impl(
const Tuple& t, std::index_sequence<Is...>){
104 return std::vector<R>({std::get<Is>(t)...});
111 template<
typename R,
typename... ArgTypes>
112 std::vector<R>
t2v(
const std::tuple<ArgTypes...>& t){
113 return detail::t2v_impl<R, std::tuple<ArgTypes...>>(t, std::index_sequence_for<ArgTypes...>{});
117 template <
class F,
class Tuple, std::size_t... I>
118 constexpr decltype(
auto) call_impl(F &&f, Tuple &&t, std::index_sequence<I...>){
119 return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
126 template <
class F,
class Tuple>
128 return detail::call_impl(
129 std::forward<F>(f), std::forward<Tuple>(t),
130 std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
133 template<
typename>
class Function;
144 inline static bool in_register_function=
false;
153 GenFunction(
const std::string& name,
const std::string& impl)
159 std::string& get_name(){
163 std::string& get_impl(){
173 std::stringstream code_out(
"");
174 std::string command(
"echo \""+code+
"\" | clang-format");
176 FILE *stream = popen(command.c_str(),
"r");
177 while (fgets(buffer, 255, stream) != NULL)
179 if (pclose(stream) == 0)
180 return code_out.str();
185 static std::string summary(){
186 std::stringstream ss;
187 ss <<
"The following functions have been registered" << std::endl;
188 for(
auto p : function_registry){
189 if (p.second ==
nullptr)
continue;
190 ss <<
"FUNCTION::" << p.second->name <<
"@" << p.second << std::endl;
191 ss << format_code(p.second->impl);
196 template <
typename T>
197 static Function<T>& register_function(
const std::string& name, std::function<T> f,
const std::string& impl){
198 in_register_function =
true;
202 if (func ==
nullptr){
203 ERROR(
"Trying to register function which has already been registered with a different type");
206 func =
new Function<T>(name, impl, f);
209 in_register_function =
false;
213 template <
typename T>
214 static Function<T>& lookup_function(
const std::string& name){
216 CRITICAL(
"Function \"" << name <<
"\" not previously registered", -1);
219 if (func ==
nullptr){
220 CRITICAL(
"Function \"" << name <<
"\" request and register have mismatched types", -1);
239 template <
typename R,
typename... ArgTypes>
242 std::function<R(ArgTypes...)> f;
245 Function(
const std::string& name,
const std::string& impl, std::function<R(ArgTypes...)> f)
247 if (!in_register_function) {
248 WARNING(
"Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
251 Function(
const std::string& name, std::function<R(ArgTypes...)> f)
252 :Function(name,
"N/A", f){ }
255 R operator()(ArgTypes ...args){
262 #define FUNC(f) f, #f 264 template <
typename T>
273 typedef std::map<std::string, GenValue*> ValueSet;
293 this->value_valid =
false;
303 inline static std::map<std::pair<const std::type_index, const std::string>, GenValue*> values;
312 inline static std::map<std::pair<const std::type_index, const std::string>, GenValue*> aliases;
314 bool logging_enabled;
317 GenValue(
const std::type_index&& ti,
const std::string& name,
const std::string& alias)
318 :name(name), value_valid(false), logging_enabled(false){
320 INFO(
"Registered value: \"" << name <<
"\" with alias: \"" << alias <<
"\"");
322 INFO(
"Registered value: \"" << name);
323 values[std::make_pair(ti,name)] =
this;
325 GenValue::alias(ti, alias,
this);
328 const std::string& get_name(){
339 virtual void log() = 0;
342 for (
auto val : values){
343 if (val.second !=
nullptr){
344 val.second->_reset();
350 static Value<T>* get_value(
const std::string& name){
351 const std::type_index& ti =
typeid(T);
352 auto lookup_id = std::make_pair(ti,name);
353 if (aliases[lookup_id] !=
nullptr)
354 return (
Value<T>*)aliases[lookup_id];
356 return (
Value<T>*)values[lookup_id];
360 static void alias(
const std::type_index& ti,
const std::string& name, GenValue* value){
361 auto lookup_id = std::make_pair(ti,name);
362 if (aliases[lookup_id] !=
nullptr){
363 WARNING(
"WARNING: alias \"" << name <<
"\" overrides previous entry.");
365 aliases[lookup_id] = value;
369 static void alias(
const std::string& name,
Value<T>* value){
370 alias(
typeid(T), name, value);
373 static std::string summary(){
374 std::stringstream ss;
375 ss <<
"The following values have been created:" << std::endl;
376 for (
auto item : values){
377 auto& key = item.first;
378 auto& value = item.second;
379 if (value ==
nullptr)
continue;
380 ss <<
"\tVALUE::\"" << key.second <<
"\" at address " << value << std::endl;
382 ss <<
"And these aliases:" << std::endl;
383 for (
auto item : aliases){
384 auto& key = item.first;
385 auto& value = item.second;
386 std::string orig(
"VOID");
387 if (value ==
nullptr)
continue;
388 for (
auto v_item : values){
389 auto& v_value = v_item.second;
390 if (v_value == value){
391 orig = v_value->get_name();
395 ss <<
"\tALIAS::\"" << key.second <<
"\" referring to \"" << orig <<
"\"" << std::endl;
399 friend std::ostream& operator<<(std::ostream& os,
const GenValue& gv);
401 std::ostream& operator<<(std::ostream& os, GenValue& gv){
416 template <
typename T>
417 class Value :
public GenValue{
419 std::function<std::string(T)> value_to_string;
422 Value(
const std::string& name,
const std::string& alias=
"")
423 :value_to_string([](T){
return "";}),
424 GenValue(
typeid(T), name, alias){ }
427 virtual T& get_value() = 0;
429 void enable_logging(
const std::function<std::string(T)>& value_to_string = [](T){
return "";}){
430 logging_enabled =
true;
431 this->value_to_string = value_to_string;
434 void disable_logging(){
435 logging_enabled =
false;
449 template <
typename T>
455 ObservedValue(
const std::string& name, T* val_ref,
const std::string& alias=
"")
460 if(this->logging_enabled){
461 INFO(this->get_name() <<
": " << this->value_to_string(*val_ref));
465 static std::string fmt_name(
const std::string& name){
470 if (!this->value_valid){
471 this->value_valid =
true;
494 template <
typename T>
507 virtual void update_value() = 0;
509 DerivedValue(
const std::string& name,
const std::string& alias=
"")
513 if(this->logging_enabled){
514 INFO(this->get_name() <<
": " << this->value_to_string(value));
522 if (!this->value_valid){
527 this->value_valid =
true;
544 template <
typename T>
553 this->value.assign(data_ref, data_ref+n);
558 return "wrapper_vector("+size->get_name()+
","+data->get_name()+
")";
563 size(size), data(data){ }
569 template <
typename T1,
typename T2>
572 std::pair<Value<T1>*,
Value<T2>* > value_pair;
574 this->value.first = value_pair.first->
get_value();
575 this->value.second = value_pair.second->
get_value();
580 return "pair("+value1->get_name()+
","+value2->get_name()+
")";
585 value_pair(value1, value2){ }
588 template<
typename... T>
class _Zip;
594 return std::numeric_limits<int>::max();
597 std::tuple<> _get_at(
int){
598 return std::make_tuple();
601 std::string _get_name(){
609 template<
typename Head,
typename... Tail>
610 class _Zip<Head, Tail...> :
private _Zip<Tail...> {
615 int this_size = head->
get_value().size();
616 int rest_size = _Zip<Tail...>::_get_size();
617 return std::min(this_size, rest_size);
620 typename std::tuple<Head,Tail...> _get_at(
int idx){
621 auto tail_tuple = _Zip<Tail...>::_get_at(idx);
622 return std::tuple_cat(std::make_tuple(head->
get_value()[idx]),tail_tuple);
625 std::string _get_name(){
626 return head->get_name()+
","+_Zip<Tail...>::_get_name();
632 _Zip(
Value<std::vector<Head>>* head,
Value<std::vector<Tail>>*... tail)
633 : _Zip<Tail...>(tail...),
638 std::string zip_fmt_name(){
642 template<
typename Head>
643 std::string zip_fmt_name(
Value<std::vector<Head>>* head){
644 return head->get_name();
647 template<
typename Head1,
typename Head2,
typename... Tail>
648 std::string zip_fmt_name(
Value<std::vector<Head1>>* head1,
Value<std::vector<Head2>>* head2,
Value<std::vector<Tail>>*... tail){
649 return head1->get_name() +
"," + zip_fmt_name<Head2, Tail...>(head2, tail...);
667 template <
typename... ArgTypes>
669 private _Zip<ArgTypes...>{
673 int size = _Zip<ArgTypes...>::_get_size();
674 for(
int i=0; i<size; i++){
675 this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
680 static std::string fmt_name(
Value<std::vector<ArgTypes>>*... args){
681 return "zip("+zip_fmt_name(args...)+
")";
684 Zip(
Value<std::vector<ArgTypes>>*... args,
const std::string& alias)
685 :
DerivedValue<std::vector<std::tuple<ArgTypes...>>>(fmt_name(args...), alias),
686 _Zip<ArgTypes...>(args...) { }
689 template<
typename>
class Map;
697 template <
typename Ret,
typename... ArgTypes>
700 typedef Value<std::vector<std::tuple<ArgTypes...>>>
arg_type;
701 Function<Ret(ArgTypes...)>& fn;
707 this->value.push_back(
call(fn,tup));
712 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn,
arg_type* arg){
713 return "map("+fn.get_name()+
":"+arg->get_name()+
")";
716 Map(Function<Ret(ArgTypes...)>& fn,
arg_type* arg,
const std::string& alias)
722 template<
typename... T>
class _Tuple;
727 std::tuple<> _get_value(){
728 return std::make_tuple();
735 template<
typename Head,
typename... Tail>
736 class _Tuple<Head, Tail...> :
private _Tuple<Tail...> {
740 typename std::tuple<Head,Tail...> _get_value(){
741 auto tail_tuple = _Tuple<Tail...>::_get_value();
742 return std::tuple_cat(std::make_tuple(head->
get_value()),tail_tuple);
749 : _Tuple<Tail...>(tail...),
754 std::string tuple_fmt_name(){
758 template<
typename Head>
760 return head->get_name();
763 template<
typename Head1,
typename Head2,
typename... Tail>
765 return head1->get_name() +
"," + tuple_fmt_name<Head2, Tail...>(head2, tail...);
775 template <
typename... ArgTypes>
777 private _Tuple<ArgTypes...>{
780 this->value = _Tuple<ArgTypes...>::_get_value();
785 return "tuple("+impl::tuple_fmt_name(args...)+
")";
789 :
DerivedValue<std::tuple<ArgTypes...>>(fmt_name(args...), alias),
790 _Tuple<ArgTypes...>(args...) { }
796 template <
size_t N,
typename... ArgTypes>
797 class DeTup :
public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
798 Value<std::tuple<ArgTypes...>> tup;
801 this->value = std::get<N>(tup->get_value());
805 static std::string fmt_name(
Value<std::tuple<ArgTypes...>>* tup){
806 return "detup("+tup->get_name()+
")";
809 DeTup(
Value<std::tuple<ArgTypes...>>* tup,
const std::string& alias)
810 :
DerivedValue<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(fmt_name(tup), alias),
818 template <
size_t N,
typename... ArgTypes>
820 Value<std::vector<std::tuple<ArgTypes...>>>* tup;
824 for(
auto& t : tup->get_value()){
825 this->value.push_back(std::get<N>(t));
830 static std::string fmt_name(
Value<std::vector<std::tuple<ArgTypes...>>>* tup){
831 return "detup_vec("+tup->get_name()+
")";
834 DeTupVector(
Value<std::vector<std::tuple<ArgTypes...>>>* tup,
const std::string& alias)
835 :
DerivedValue<std::vector<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(fmt_name(tup), alias),
839 template<
typename>
class Apply;
844 template <
typename Ret,
typename... ArgTypes>
847 Function<Ret(ArgTypes...)>& fn;
848 Value<std::tuple<ArgTypes...>>* arg;
851 auto &tup = arg->get_value();
852 this->value =
call(fn, tup);
856 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg){
857 return "apply("+fn.get_name()+
":"+arg->get_name()+
")";
860 Apply(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg,
const std::string& alias)
872 Function<bool(T)>& selector;
884 static std::string fmt_name(Function<
bool(T)>& selector,
Value<std::vector<T>>* v){
885 return "count("+selector.get_name()+
":"+v->get_name()+
")";
888 Count(Function<
bool(T)>& selector,
Value<std::vector<T>>* v,
const std::string alias)
890 selector(selector), v(v) { }
899 Function<bool(T)>& filter;
905 if(this->filter(val))
906 this->value.push_back(val);
911 static std::string fmt_name(Function<
bool(T)>& filter,
Value<std::vector<T>>* v){
912 return "filter("+filter.get_name()+
":"+v->get_name()+
")";
915 Filter(Function<
bool(T)>& filter,
Value<std::vector<T>>* v,
const std::string alias)
917 filter(filter), v(v) { }
925 template<
typename... ArgTypes>
928 typedef std::vector<std::tuple<ArgTypes...>> value_type;
929 Function<bool(ArgTypes...)>& filter;
936 this->value.push_back(val);
941 static std::string fmt_name(Function<
bool(ArgTypes...)>& filter,
Value<value_type>* arg){
942 return "tup_filter("+filter.get_name()+
":"+arg->get_name()+
")";
947 filter(filter), arg(arg) { }
956 template <
typename T>
959 Function<T(std::vector<T>)>& reduce;
962 this->value = reduce(v->get_value());
969 Reduce(Function<T(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias)
970 :
DerivedValue<T>(
"reduceWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
971 reduce(reduce), v(v) { }
977 template <
typename T>
980 static std::string fmt_name(
Value<std::vector<T>>* v){
981 return "max("+v->get_name()+
")";
984 Max(
Value<std::vector<T>>* v,
const std::string alias)
985 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"max",
986 FUNC(([](std::vector<T> vec){
987 return *std::max_element(vec.begin(), vec.end());}))),
994 template <
typename T>
997 static std::string fmt_name(
Value<std::vector<T>>* v){
998 return "min("+v->get_name()+
")";
1001 Min(
Value<std::vector<T>>* v,
const std::string alias)
1002 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"min",
1003 FUNC(([](std::vector<T> vec){
1004 return *std::min_element(vec.begin(), vec.end());}))),
1011 template <
typename T>
1014 static std::string fmt_name(
Value<std::vector<T>>* v){
1015 return "mean("+v->get_name()+
")";
1018 Mean(
Value<std::vector<T>>* v,
const std::string alias)
1019 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"mean",
1020 FUNC(([](std::vector<T> vec){
1021 int n = 0; T sum = 0;
1022 for (T e : vec){ n++; sum += e; }
1023 return n>0 ? sum / n : 0; }))),
1030 template <
typename T>
1033 static std::string fmt_name(
Value<std::vector<T>>* v){
1034 return "range("+v->get_name()+
")";
1037 Range(
Value<std::vector<T>>* v,
const std::string alias)
1038 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"range",
1039 FUNC(([](std::vector<T> vec){
1040 auto minmax = std::minmax_element(vec.begin(), vec.end());
1041 return (*minmax.second) - (*minmax.first); }))),
1048 template <
typename T>
1052 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"elementOf",
1053 FUNC(([index](std::vector<T> vec){
return vec[index->
get_value()];}))),
1062 template <
typename T>
1065 Function<std::pair<T,int>(std::vector<T>)>& reduce;
1069 this->value = reduce(v->get_value());
1073 ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias=
"")
1074 :
DerivedValue<T>(
"reduceIndexWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
1075 reduce(reduce), v(v) { }
1081 template <
typename T>
1084 MaxIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1085 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"maxIndex",
1086 FUNC(([](std::vector<T> vec){
1087 auto elptr = std::max_element(vec.begin(), vec.end());
1088 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1095 template <
typename T>
1098 MinIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1099 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"minIndex",
1100 FUNC(([](std::vector<T> vec){
1101 auto elptr = std::min_element(vec.begin(), vec.end());
1102 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1109 template <
typename T,
int Size>
1113 typedef typename HomoTuple<T,Size>::type tuple_type;
1117 int data_size = v.size();
1118 this->value.clear();
1120 std::vector<bool> selector(data_size);
1121 std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}),
true);
1123 std::array<T, Size> perm;
1125 for (
int i=0; i<data_size; i++){
1129 if (idx == Size)
break;
1132 this->value.push_back(
a2t(perm));
1133 }
while(std::prev_permutation(selector.begin(), selector.end()));
1137 static std::string fmt_name(
Value<std::vector<T>>* val){
1138 std::stringstream ss;
1139 ss <<
"combinations(" << Size <<
"," << val->get_name() <<
")";
1152 template <
typename FST,
typename SND>
1159 this->value.clear();
1162 for(
int i=0; i<v1.size(); i++){
1163 for(
int j=0; j<v2.size(); j++){
1164 this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1169 static std::string calc_name(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2){
1170 std::stringstream ss;
1171 ss <<
"cartProduct(" 1172 << val1->get_name() <<
", " << val2->get_name()
1178 static std::string fmt_name(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2){
1179 return "cartProduct("+val1->get_name()+
", "+val2->get_name()+
")";
1182 CartProduct(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2,
const std::string alias=
"")
1184 val1(val1), val2(val2) { }
1192 template <
typename T>
1200 BoundValue(Function<T()>& f,
const std::string alias=
"")
1209 template <
typename T>
1215 PointerValue(
const std::string& name, T* ptr,
const std::string alias=
"")
1224 template <
typename T>
1230 ConstantValue(
const std::string& name, T const_value,
const std::string alias=
"")
void update_value()
Updates the internal value.
void update_value()
Updates the internal value.
Find and return the maximum value of a vector.
Zips a series of vectors together.
Reduce a Value of type vector<T> to just a T.
void update_value()
Updates the internal value.
void update_value()
Updates the internal value.
Find and return the minimum value of a vector and its index.
Find combinations of items from an input vector.
A generic value owning only a function object.
T & get_value()
Calculate, if necessary, and return the value held by this object.
Calculate the range of the values in a vector.
void update_value()
Updates the internal value.
Takes a series of Value objects and bundles them together into a std::tuple object.
A std::vector wrapper around a C-style array.
Similar to Reduce, but returns a pair of a T and an int.
Returns the count of elements in the input vector passing a test function.
Find and return the maximum value of a vector and its index.
void update_value()
Updates the internal value.
Parent class to all Function classes.
void update_value()
Updates the internal value.
void update_value()
Updates the internal value.
A value supplied by the dataset, not derived.
Returns the elements in a vector that pass a test function.
Gets the Nth element from a tuple value.
Find and return the minimum value of a vector.
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Creates a std::pair type from a two other Value objects.
decltype(auto) a2t(const std::array< T, N > &a)
Converts a std::array to a std::tuple.
void update_value()
Updates the internal value.
T & get_value()
Calculate, if necessary, and return the value held by this object.
void update_value()
Updates the internal value.
void update_value()
Updates the internal value.
void update_value()
Updates the internal value.
The namespace containing all filval classes and functions.
Extract the element at a specific index from a vector.
decltype(auto) constexpr call(F &&f, Tuple &&t)
Call a function f with the elements of the tuple t as arguments.
Returns the elements in a vector that pass a test function.
Calculate the mean value of a vector.
void update_value()
Updates the internal value.
Calculate the cartesian product of two input vectors.
void update_value()
Updates the internal value.
void update_value()
Updates the internal value.
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 ...
A Value derived from some other Values, not directly from the dataset.
void update_value()
Updates the internal value.
void update_value()
Updates the internal value.
std::vector< R > t2v(const std::tuple< ArgTypes... > &t)
Converts a std::tuple to a std::vector.
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.
static std::map< const std::string, GenFunction * > function_registry
Static mapping of functions from their name to the object wrapper of the function.
void update_value()
Updates the internal value.