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));
519 if (!this->value_valid){
521 this->value_valid =
true;
538 template <
typename T>
547 this->value.assign(data_ref, data_ref+n);
552 return "wrapper_vector("+size->get_name()+
","+data->get_name()+
")";
557 size(size), data(data){ }
563 template <
typename T1,
typename T2>
566 std::pair<Value<T1>*,
Value<T2>* > value_pair;
568 this->value.first = value_pair.first->
get_value();
569 this->value.second = value_pair.second->
get_value();
574 return "pair("+value1->get_name()+
","+value2->get_name()+
")";
579 value_pair(value1, value2){ }
582 template<
typename... T>
class _Zip;
588 return std::numeric_limits<int>::max();
591 std::tuple<> _get_at(
int){
592 return std::make_tuple();
595 std::string _get_name(){
603 template<
typename Head,
typename... Tail>
604 class _Zip<Head, Tail...> :
private _Zip<Tail...> {
609 int this_size = head->
get_value().size();
610 int rest_size = _Zip<Tail...>::_get_size();
611 return std::min(this_size, rest_size);
614 typename std::tuple<Head,Tail...> _get_at(
int idx){
615 auto tail_tuple = _Zip<Tail...>::_get_at(idx);
616 return std::tuple_cat(std::make_tuple(head->
get_value()[idx]),tail_tuple);
619 std::string _get_name(){
620 return head->get_name()+
","+_Zip<Tail...>::_get_name();
626 _Zip(
Value<std::vector<Head>>* head,
Value<std::vector<Tail>>*... tail)
627 : _Zip<Tail...>(tail...),
632 std::string zip_fmt_name(){
636 template<
typename Head>
637 std::string zip_fmt_name(
Value<std::vector<Head>>* head){
638 return head->get_name();
641 template<
typename Head1,
typename Head2,
typename... Tail>
642 std::string zip_fmt_name(
Value<std::vector<Head1>>* head1,
Value<std::vector<Head2>>* head2,
Value<std::vector<Tail>>*... tail){
643 return head1->get_name() +
"," + zip_fmt_name<Head2, Tail...>(head2, tail...);
661 template <
typename... ArgTypes>
663 private _Zip<ArgTypes...>{
667 int size = _Zip<ArgTypes...>::_get_size();
668 for(
int i=0; i<size; i++){
669 this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
674 static std::string fmt_name(
Value<std::vector<ArgTypes>>*... args){
675 return "zip("+zip_fmt_name(args...)+
")";
678 Zip(
Value<std::vector<ArgTypes>>*... args,
const std::string& alias)
679 :
DerivedValue<std::vector<std::tuple<ArgTypes...>>>(fmt_name(args...), alias),
680 _Zip<ArgTypes...>(args...) { }
683 template<
typename>
class Map;
691 template <
typename Ret,
typename... ArgTypes>
694 typedef Value<std::vector<std::tuple<ArgTypes...>>>
arg_type;
695 Function<Ret(ArgTypes...)>& fn;
701 this->value.push_back(
call(fn,tup));
706 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn,
arg_type* arg){
707 return "map("+fn.get_name()+
":"+arg->get_name()+
")";
710 Map(Function<Ret(ArgTypes...)>& fn,
arg_type* arg,
const std::string& alias)
716 template<
typename... T>
class _Tuple;
721 std::tuple<> _get_value(){
722 return std::make_tuple();
729 template<
typename Head,
typename... Tail>
730 class _Tuple<Head, Tail...> :
private _Tuple<Tail...> {
734 typename std::tuple<Head,Tail...> _get_value(){
735 auto tail_tuple = _Tuple<Tail...>::_get_value();
736 return std::tuple_cat(std::make_tuple(head->
get_value()),tail_tuple);
743 : _Tuple<Tail...>(tail...),
748 std::string tuple_fmt_name(){
752 template<
typename Head>
754 return head->get_name();
757 template<
typename Head1,
typename Head2,
typename... Tail>
759 return head1->get_name() +
"," + tuple_fmt_name<Head2, Tail...>(head2, tail...);
769 template <
typename... ArgTypes>
771 private _Tuple<ArgTypes...>{
774 this->value = _Tuple<ArgTypes...>::_get_value();
779 return "tuple("+impl::tuple_fmt_name(args...)+
")";
783 :
DerivedValue<std::tuple<ArgTypes...>>(fmt_name(args...), alias),
784 _Tuple<ArgTypes...>(args...) { }
790 template <
size_t N,
typename... ArgTypes>
791 class DeTup :
public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
792 Value<std::tuple<ArgTypes...>> tup;
795 this->value = std::get<N>(tup->get_value());
799 static std::string fmt_name(
Value<std::tuple<ArgTypes...>>* tup){
800 return "detup("+tup->get_name()+
")";
803 DeTup(
Value<std::tuple<ArgTypes...>>* tup,
const std::string& alias)
804 :
DerivedValue<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(fmt_name(tup), alias),
812 template <
size_t N,
typename... ArgTypes>
814 Value<std::vector<std::tuple<ArgTypes...>>>* tup;
818 for(
auto& t : tup->get_value()){
819 this->value.push_back(std::get<N>(t));
824 static std::string fmt_name(
Value<std::vector<std::tuple<ArgTypes...>>>* tup){
825 return "detup_vec("+tup->get_name()+
")";
828 DeTupVector(
Value<std::vector<std::tuple<ArgTypes...>>>* tup,
const std::string& alias)
829 :
DerivedValue<std::vector<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(fmt_name(tup), alias),
833 template<
typename>
class Apply;
838 template <
typename Ret,
typename... ArgTypes>
841 Function<Ret(ArgTypes...)>& fn;
842 Value<std::tuple<ArgTypes...>>* arg;
845 auto &tup = arg->get_value();
846 this->value =
call(fn, tup);
850 static std::string fmt_name(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg){
851 return "apply("+fn.get_name()+
":"+arg->get_name()+
")";
854 Apply(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg,
const std::string& alias)
866 Function<bool(T)>& selector;
878 static std::string fmt_name(Function<
bool(T)>& selector,
Value<std::vector<T>>* v){
879 return "count("+selector.get_name()+
":"+v->get_name()+
")";
882 Count(Function<
bool(T)>& selector,
Value<std::vector<T>>* v,
const std::string alias)
884 selector(selector), v(v) { }
893 Function<bool(T)>& filter;
899 if(this->filter(val))
900 this->value.push_back(val);
905 static std::string fmt_name(Function<
bool(T)>& filter,
Value<std::vector<T>>* v){
906 return "filter("+filter.get_name()+
":"+v->get_name()+
")";
909 Filter(Function<
bool(T)>& filter,
Value<std::vector<T>>* v,
const std::string alias)
911 filter(filter), v(v) { }
919 template<
typename... ArgTypes>
922 typedef std::vector<std::tuple<ArgTypes...>> value_type;
923 Function<bool(ArgTypes...)>& filter;
930 this->value.push_back(val);
935 static std::string fmt_name(Function<
bool(ArgTypes...)>& filter,
Value<value_type>* arg){
936 return "tup_filter("+filter.get_name()+
":"+arg->get_name()+
")";
941 filter(filter), arg(arg) { }
950 template <
typename T>
953 Function<T(std::vector<T>)>& reduce;
956 this->value = reduce(v->get_value());
963 Reduce(Function<T(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias)
964 :
DerivedValue<T>(
"reduceWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
965 reduce(reduce), v(v) { }
971 template <
typename T>
974 static std::string fmt_name(
Value<std::vector<T>>* v){
975 return "max("+v->get_name()+
")";
978 Max(
Value<std::vector<T>>* v,
const std::string alias)
979 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"max",
980 FUNC(([](std::vector<T> vec){
981 return *std::max_element(vec.begin(), vec.end());}))),
988 template <
typename T>
991 static std::string fmt_name(
Value<std::vector<T>>* v){
992 return "min("+v->get_name()+
")";
995 Min(
Value<std::vector<T>>* v,
const std::string alias)
996 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"min",
997 FUNC(([](std::vector<T> vec){
998 return *std::min_element(vec.begin(), vec.end());}))),
1005 template <
typename T>
1008 static std::string fmt_name(
Value<std::vector<T>>* v){
1009 return "mean("+v->get_name()+
")";
1012 Mean(
Value<std::vector<T>>* v,
const std::string alias)
1013 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"mean",
1014 FUNC(([](std::vector<T> vec){
1015 int n = 0; T sum = 0;
1016 for (T e : vec){ n++; sum += e; }
1017 return n>0 ? sum / n : 0; }))),
1024 template <
typename T>
1027 static std::string fmt_name(
Value<std::vector<T>>* v){
1028 return "range("+v->get_name()+
")";
1031 Range(
Value<std::vector<T>>* v,
const std::string alias)
1032 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"range",
1033 FUNC(([](std::vector<T> vec){
1034 auto minmax = std::minmax_element(vec.begin(), vec.end());
1035 return (*minmax.second) - (*minmax.first); }))),
1042 template <
typename T>
1046 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"elementOf",
1047 FUNC(([index](std::vector<T> vec){
return vec[index->
get_value()];}))),
1056 template <
typename T>
1059 Function<std::pair<T,int>(std::vector<T>)>& reduce;
1063 this->value = reduce(v->get_value());
1067 ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias=
"")
1068 :
DerivedValue<T>(
"reduceIndexWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
1069 reduce(reduce), v(v) { }
1075 template <
typename T>
1078 MaxIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1079 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"maxIndex",
1080 FUNC(([](std::vector<T> vec){
1081 auto elptr = std::max_element(vec.begin(), vec.end());
1082 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1089 template <
typename T>
1092 MinIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1093 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"minIndex",
1094 FUNC(([](std::vector<T> vec){
1095 auto elptr = std::min_element(vec.begin(), vec.end());
1096 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1103 template <
typename T,
int Size>
1107 typedef typename HomoTuple<T,Size>::type tuple_type;
1111 int data_size = v.size();
1112 this->value.clear();
1114 std::vector<bool> selector(data_size);
1115 std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}),
true);
1117 std::array<T, Size> perm;
1119 for (
int i=0; i<data_size; i++){
1123 if (idx == Size)
break;
1126 this->value.push_back(
a2t(perm));
1127 }
while(std::prev_permutation(selector.begin(), selector.end()));
1131 static std::string fmt_name(
Value<std::vector<T>>* val){
1132 std::stringstream ss;
1133 ss <<
"combinations(" << Size <<
"," << val->get_name() <<
")";
1146 template <
typename FST,
typename SND>
1153 this->value.clear();
1156 for(
int i=0; i<v1.size(); i++){
1157 for(
int j=0; j<v2.size(); j++){
1158 this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1163 static std::string calc_name(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2){
1164 std::stringstream ss;
1165 ss <<
"cartProduct(" 1166 << val1->get_name() <<
", " << val2->get_name()
1172 static std::string fmt_name(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2){
1173 return "cartProduct("+val1->get_name()+
", "+val2->get_name()+
")";
1176 CartProduct(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2,
const std::string alias=
"")
1178 val1(val1), val2(val2) { }
1186 template <
typename T>
1195 static std::string fmt_name(Function<T()> f){
1196 return f.get_name()+
"(<bound>)";
1199 BoundValue(Function<T()>& f,
const std::string alias=
"")
1208 template <
typename T>
1214 PointerValue(
const std::string& name, T* ptr,
const std::string alias=
"")
1223 template <
typename T>
1229 static std::string fmt_name(
const std::string& name){
1230 return "const::"+name;
1232 ConstantValue(
const std::string& name, T const_value,
const std::string alias=
"")
1234 this->value = const_value;
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.