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(){
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 271 typedef std::map<std::string, GenValue*> ValueSet;
294 this->value_valid =
false;
303 inline static std::map<const std::string, GenValue*> values;
311 inline static std::map<const std::string, GenValue*> aliases;
313 bool logging_enabled;
316 GenValue(
const std::string& name,
const std::string& alias)
319 logging_enabled(
false){
320 INFO(
"Registered value: \"" << name <<
"\" with alias: \"" << alias <<
"\"");
323 GenValue::alias(alias,
this);
326 const std::string& get_name(){
330 void set_name(
const std::string& new_name){
331 values[name] =
nullptr;
336 virtual void log() = 0;
339 for (
auto val : values){
340 if (val.second !=
nullptr){
341 val.second->_reset();
346 static GenValue* get_value(
const std::string& name){
347 if (aliases[name] !=
nullptr)
348 return aliases[name];
349 else if (values[name] !=
nullptr)
352 ERROR(
"Could not find alias or value \"" << name <<
"\". I'll tell you the ones I know about." << std::endl
354 CRITICAL(
"Aborting... :(",-1);
358 static void alias(
const std::string& name, GenValue* value){
359 if (aliases[name] !=
nullptr){
360 WARNING(
"WARNING: alias \"" << name <<
"\" overrides previous entry.");
362 aliases[name] = value;
365 static GenValue* alias(
const std::string& name){
366 if (values[name] !=
nullptr){
367 WARNING(
"Alias \"" << name <<
"\" does not exist.");
369 return aliases[name];
372 static std::string summary(){
373 std::stringstream ss;
374 ss <<
"The following values have been created:" << std::endl;
375 for (
auto value : values){
376 if (value.second ==
nullptr)
continue;
377 ss <<
"\tVALUE::\"" << value.first <<
"\" at address " << value.second << std::endl;
379 ss <<
"And these aliases:" << std::endl;
380 for (
auto alias : aliases){
381 std::string orig(
"VOID");
382 if (alias.second ==
nullptr)
continue;
383 for (
auto value : values){
384 if (alias.second == value.second){
385 orig = value.second->get_name();
389 ss <<
"\tALIAS::\"" << alias.first <<
"\" referring to \"" << orig <<
"\"" << std::endl;
393 friend std::ostream& operator<<(std::ostream& os,
const GenValue& gv);
395 std::ostream& operator<<(std::ostream& os, GenValue& gv){
410 template <
typename T>
413 std::function<std::string(T)> value_to_string;
416 Value(
const std::string& name,
const std::string& alias=
"")
417 :value_to_string([](T){
return "";}),
418 GenValue(name, alias){ }
421 virtual T& get_value() = 0;
423 void enable_logging(
const std::function<std::string(T)>& value_to_string = [](T){
return "";}){
424 logging_enabled =
true;
425 this->value_to_string = value_to_string;
428 void disable_logging(){
429 logging_enabled =
false;
443 template <
typename T>
449 ObservedValue(
const std::string& name, T* val_ref,
const std::string& alias=
"")
454 if(this->logging_enabled){
455 INFO(this->get_name() <<
": " << this->value_to_string(*val_ref));
460 if (!this->value_valid){
461 this->value_valid =
true;
484 template <
typename T>
497 virtual void update_value() = 0;
499 DerivedValue(
const std::string& name,
const std::string& alias=
"")
503 if(this->logging_enabled){
504 INFO(this->get_name() <<
": " << this->value_to_string(value));
512 if (!this->value_valid){
517 this->value_valid =
true;
534 template <
typename T>
543 this->value.assign(data_ref, data_ref+n);
549 size(size), data(data){ }
555 template <
typename T1,
typename T2>
558 std::pair<Value<T1>*,
Value<T2>* > value_pair;
560 this->value.first = value_pair.first->get_value();
561 this->value.second = value_pair.second->get_value();
567 value_pair(value1, value2){ }
570 template<
typename... T>
class _Zip;
576 return std::numeric_limits<int>::max();
579 std::tuple<> _get_at(
int){
580 return std::make_tuple();
583 std::string _get_name(){
591 template<
typename Head,
typename... Tail>
592 class _Zip<Head, Tail...> :
private _Zip<Tail...> {
597 int this_size = head->
get_value().size();
598 int rest_size = _Zip<Tail...>::_get_size();
599 return std::min(this_size, rest_size);
602 typename std::tuple<Head,Tail...> _get_at(
int idx){
603 auto tail_tuple = _Zip<Tail...>::_get_at(idx);
604 return std::tuple_cat(std::make_tuple(head->
get_value()[idx]),tail_tuple);
607 std::string _get_name(){
608 return head->get_name()+
","+_Zip<Tail...>::_get_name();
614 _Zip(
Value<std::vector<Head>>* head,
Value<std::vector<Tail>>*... tail)
615 : _Zip<Tail...>(tail...),
634 template <
typename... ArgTypes>
636 private _Zip<ArgTypes...>{
640 int size = _Zip<ArgTypes...>::_get_size();
641 for(
int i=0; i<size; i++){
642 this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
646 std::string _get_name(){
647 return "zip("+_Zip<ArgTypes...>::_get_name()+
")";
651 Zip(
Value<std::vector<ArgTypes>>*... args,
const std::string& alias)
652 :
DerivedValue<std::vector<std::tuple<ArgTypes...>>>(
"", alias),
653 _Zip<ArgTypes...>(args...) {
654 this->set_name(_get_name());
658 template<
typename>
class Map;
666 template <
typename Ret,
typename... ArgTypes>
669 typedef Value<std::vector<std::tuple<ArgTypes...>>>
arg_type;
670 Function<Ret(ArgTypes...)>& fn;
676 this->value.push_back(call(fn,tup));
681 Map(Function<Ret(ArgTypes...)>& fn,
arg_type* arg,
const std::string& alias)
687 template<
typename... T>
class _Tuple;
692 std::tuple<> _get_value(){
693 return std::make_tuple();
696 std::string _get_name(){
704 template<
typename Head,
typename... Tail>
705 class _Tuple<Head, Tail...> :
private _Tuple<Tail...> {
709 typename std::tuple<Head,Tail...> _get_value(){
710 auto tail_tuple = _Tuple<Tail...>::_get_value();
711 return std::tuple_cat(std::make_tuple(head->
get_value()),tail_tuple);
715 std::string _get_name(){
716 return head->get_name()+
","+_Tuple<Tail...>::_get_name();
723 : _Tuple<Tail...>(tail...),
733 template <
typename... ArgTypes>
735 private _Tuple<ArgTypes...>{
738 this->value = _Tuple<ArgTypes...>::_get_value();
741 std::string _get_name(){
742 return "tuple("+_Tuple<ArgTypes...>::_get_name()+
")";
748 _Tuple<ArgTypes...>(args...) {
749 this->set_name(_get_name());
756 template <
size_t N,
typename... ArgTypes>
757 class DeTup :
public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
758 Value<std::tuple<ArgTypes...>> tup;
761 this->value = std::get<N>(tup->get_value());
765 DeTup(
Value<std::tuple<ArgTypes...>>* tup,
const std::string& alias)
766 :
DerivedValue<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(
"detup("+tup->get_name()+
")", alias),
774 template <
size_t N,
typename... ArgTypes>
776 Value<std::vector<std::tuple<ArgTypes...>>>* tup;
780 for(
auto& t : tup->get_value()){
781 this->value.push_back(std::get<N>(t));
786 DeTupVector(
Value<std::vector<std::tuple<ArgTypes...>>>* tup,
const std::string& alias)
787 :
DerivedValue<std::vector<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(
"detup("+tup->get_name()+
")", alias),
791 template<
typename>
class Apply;
796 template <
typename Ret,
typename... ArgTypes>
799 Function<Ret(ArgTypes...)>& fn;
800 Value<std::tuple<ArgTypes...>>* arg;
803 auto &tup = arg->get_value();
804 this->value = call(fn, tup);
808 Apply(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg,
const std::string& alias)
820 Function<bool(T)>& selector;
832 Count(Function<
bool(T)>& selector,
Value<std::vector<T>>* v,
const std::string alias)
834 selector(selector), v(v) { }
843 Function<bool(T)>& filter;
849 if(this->filter(val))
850 this->value.push_back(val);
855 Filter(Function<
bool(T)>& filter,
Value<std::vector<T>>* v,
const std::string alias)
857 filter(filter), v(v) { }
865 template<
typename... ArgTypes>
868 typedef std::vector<std::tuple<ArgTypes...>> value_type;
869 Function<bool(ArgTypes...)>& filter;
876 this->value.push_back(val);
883 filter(filter), arg(arg) { }
892 template <
typename T>
895 Function<T(std::vector<T>)>& reduce;
898 this->value = reduce(v->get_value());
905 Reduce(Function<T(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias)
906 :
DerivedValue<T>(
"reduceWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
907 reduce(reduce), v(v) { }
913 template <
typename T>
916 Max(
Value<std::vector<T>>* v,
const std::string alias)
917 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"max",
918 FUNC(([](std::vector<T> vec){
919 return *std::max_element(vec.begin(), vec.end());}))),
926 template <
typename T>
929 Min(
Value<std::vector<T>>* v,
const std::string alias)
930 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"min",
931 FUNC(([](std::vector<T> vec){
932 return *std::min_element(vec.begin(), vec.end());}))),
939 template <
typename T>
942 Mean(
Value<std::vector<T>>* v,
const std::string alias)
943 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"mean",
944 FUNC(([](std::vector<T> vec){
945 int n = 0; T sum = 0;
946 for (T e : vec){ n++; sum += e; }
947 return n>0 ? sum / n : 0; }))),
954 template <
typename T>
957 Range(
Value<std::vector<T>>* v,
const std::string alias)
958 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"range",
959 FUNC(([](std::vector<T> vec){
960 auto minmax = std::minmax_element(vec.begin(), vec.end());
961 return (*minmax.second) - (*minmax.first); }))),
968 template <
typename T>
972 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"elementOf",
973 FUNC(([index](std::vector<T> vec){
return vec[index->
get_value()];}))),
982 template <
typename T>
985 Function<std::pair<T,int>(std::vector<T>)>& reduce;
989 this->value = reduce(v->get_value());
993 ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias=
"")
994 :
DerivedValue<T>(
"reduceIndexWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
995 reduce(reduce), v(v) { }
1001 template <
typename T>
1004 MaxIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1005 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"maxIndex",
1006 FUNC(([](std::vector<T> vec){
1007 auto elptr = std::max_element(vec.begin(), vec.end());
1008 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1015 template <
typename T>
1018 MinIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1019 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"minIndex",
1020 FUNC(([](std::vector<T> vec){
1021 auto elptr = std::min_element(vec.begin(), vec.end());
1022 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1029 template <
typename T,
int Size>
1033 typedef typename HomoTuple<T,Size>::type tuple_type;
1037 int data_size = v.size();
1038 this->value.clear();
1040 std::vector<bool> selector(data_size);
1041 std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}),
true);
1043 std::array<T, Size> perm;
1045 for (
int i=0; i<data_size; i++){
1049 if (idx == Size)
break;
1052 this->value.push_back(
a2t(perm));
1053 }
while(std::prev_permutation(selector.begin(), selector.end()));
1056 static std::string calc_name(
Value<std::vector<T>>* val){
1057 std::stringstream ss;
1058 ss <<
"combinations(" << Size <<
"," << val->get_name() <<
")";
1072 template <
typename FST,
typename SND>
1079 this->value.clear();
1082 for(
int i=0; i<v1.size(); i++){
1083 for(
int j=0; j<v2.size(); j++){
1084 this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1089 static std::string calc_name(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2){
1090 std::stringstream ss;
1091 ss <<
"cartProduct(" 1092 << val1->get_name() <<
", " << val2->get_name()
1098 CartProduct(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2,
const std::string alias=
"")
1109 template <
typename T>
1117 BoundValue(Function<T()>& f,
const std::string alias=
"")
1126 template <
typename T>
1132 PointerValue(
const std::string& name, T* ptr,
const std::string alias=
"")
1141 template <
typename T>
1147 ConstantValue(
const std::string& name, T const_value,
const std::string alias=
"")
void update_value()
Updates the internal value.
Definition: value.hpp:1035
void update_value()
Updates the internal value.
Definition: value.hpp:1113
Find and return the maximum value of a vector.
Definition: value.hpp:914
Zips a series of vectors together.
Definition: value.hpp:635
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:893
void update_value()
Updates the internal value.
Definition: value.hpp:823
void update_value()
Updates the internal value.
Definition: value.hpp:559
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1016
Find combinations of items from an input vector.
Definition: value.hpp:1030
A generic value owning only a function object.
Definition: value.hpp:1110
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:508
Calculate the range of the values in a vector.
Definition: value.hpp:955
void update_value()
Updates the internal value.
Definition: value.hpp:778
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:734
A std::vector wrapper around a C-style array.
Definition: value.hpp:535
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:983
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:818
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1002
void update_value()
Updates the internal value.
Definition: value.hpp:897
Parent class to all Function classes.
Definition: value.hpp:143
void update_value()
Updates the internal value.
Definition: value.hpp:737
void update_value()
Updates the internal value.
Definition: value.hpp:872
A value supplied by the dataset, not derived.
Definition: value.hpp:444
Returns the elements in a vector that pass a test function.
Definition: value.hpp:841
Gets the Nth element from a tuple value.
Definition: value.hpp:757
Find and return the minimum value of a vector.
Definition: value.hpp:927
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:775
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:556
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:802
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:459
void update_value()
Updates the internal value.
Definition: value.hpp:988
void update_value()
Updates the internal value.
Definition: value.hpp:673
void update_value()
Updates the internal value.
Definition: value.hpp:1144
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:969
Returns the elements in a vector that pass a test function.
Definition: value.hpp:866
Calculate the mean value of a vector.
Definition: value.hpp:940
void update_value()
Updates the internal value.
Definition: value.hpp:540
A generic value.
Definition: value.hpp:411
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1073
void update_value()
Updates the internal value.
Definition: value.hpp:1078
void update_value()
Updates the internal value.
Definition: value.hpp:638
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:172
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:485
void update_value()
Updates the internal value.
Definition: value.hpp:846
void update_value()
Updates the internal value.
Definition: value.hpp:1129
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:1142
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:1127
void update_value()
Updates the internal value.
Definition: value.hpp:760