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;
298 this->value_valid =
false;
307 inline static std::map<const std::string, GenValue*> values;
315 inline static std::map<const std::string, GenValue*> aliases;
317 bool logging_enabled;
320 GenValue(
const std::string& name,
const std::string& alias)
323 logging_enabled(
false){
324 INFO(
"Registered value: \"" << name <<
"\" with alias: \"" << alias <<
"\"");
327 GenValue::alias(alias,
this);
330 const std::string& get_name(){
334 void set_name(
const std::string& new_name){
335 values[name] =
nullptr;
340 virtual void log() = 0;
343 for (
auto val : values){
344 if (val.second !=
nullptr){
345 val.second->_reset();
350 static GenValue* get_value(
const std::string& name){
351 if (aliases[name] !=
nullptr)
352 return aliases[name];
353 else if (values[name] !=
nullptr)
356 ERROR(
"Could not find alias or value \"" << name <<
"\". I'll tell you the ones I know about." << std::endl
358 CRITICAL(
"Aborting... :(",-1);
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));
464 if (!this->value_valid){
465 this->value_valid =
true;
488 template <
typename T>
501 virtual void update_value() = 0;
503 DerivedValue(
const std::string& name,
const std::string& alias=
"")
507 if(this->logging_enabled){
508 INFO(this->get_name() <<
": " << this->value_to_string(value));
516 if (!this->value_valid){
521 this->value_valid =
true;
538 template <
typename T>
547 this->value.assign(data_ref, data_ref+n);
553 size(size), data(data){ }
559 template <
typename T1,
typename T2>
562 std::pair<Value<T1>*,
Value<T2>* > value_pair;
564 this->value.first = value_pair.first->get_value();
565 this->value.second = value_pair.second->get_value();
571 value_pair(value1, value2){ }
574 template<
typename... T>
class _Zip;
580 return std::numeric_limits<int>::max();
583 std::tuple<> _get_at(
int){
584 return std::make_tuple();
587 std::string _get_name(){
595 template<
typename Head,
typename... Tail>
596 class _Zip<Head, Tail...> :
private _Zip<Tail...> {
601 int this_size = head->
get_value().size();
602 int rest_size = _Zip<Tail...>::_get_size();
603 return std::min(this_size, rest_size);
606 typename std::tuple<Head,Tail...> _get_at(
int idx){
607 auto tail_tuple = _Zip<Tail...>::_get_at(idx);
608 return std::tuple_cat(std::make_tuple(head->
get_value()[idx]),tail_tuple);
611 std::string _get_name(){
612 return head->get_name()+
","+_Zip<Tail...>::_get_name();
618 _Zip(
Value<std::vector<Head>>* head,
Value<std::vector<Tail>>*... tail)
619 : _Zip<Tail...>(tail...),
638 template <
typename... ArgTypes>
640 private _Zip<ArgTypes...>{
644 int size = _Zip<ArgTypes...>::_get_size();
645 for(
int i=0; i<size; i++){
646 this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
650 std::string _get_name(){
651 return "zip("+_Zip<ArgTypes...>::_get_name()+
")";
655 Zip(
Value<std::vector<ArgTypes>>*... args,
const std::string& alias)
656 :
DerivedValue<std::vector<std::tuple<ArgTypes...>>>(
"", alias),
657 _Zip<ArgTypes...>(args...) {
658 this->set_name(_get_name());
662 template<
typename>
class Map;
670 template <
typename Ret,
typename... ArgTypes>
673 typedef Value<std::vector<std::tuple<ArgTypes...>>>
arg_type;
674 Function<Ret(ArgTypes...)>& fn;
680 this->value.push_back(call(fn,tup));
685 Map(Function<Ret(ArgTypes...)>& fn,
arg_type* arg,
const std::string& alias)
691 template<
typename... T>
class _Tuple;
696 std::tuple<> _get_value(){
697 return std::make_tuple();
700 std::string _get_name(){
708 template<
typename Head,
typename... Tail>
709 class _Tuple<Head, Tail...> :
private _Tuple<Tail...> {
713 typename std::tuple<Head,Tail...> _get_value(){
714 auto tail_tuple = _Tuple<Tail...>::_get_value();
715 return std::tuple_cat(std::make_tuple(head->
get_value()),tail_tuple);
719 std::string _get_name(){
720 return head->get_name()+
","+_Tuple<Tail...>::_get_name();
727 : _Tuple<Tail...>(tail...),
737 template <
typename... ArgTypes>
739 private _Tuple<ArgTypes...>{
742 this->value = _Tuple<ArgTypes...>::_get_value();
745 std::string _get_name(){
746 return "tuple("+_Tuple<ArgTypes...>::_get_name()+
")";
752 _Tuple<ArgTypes...>(args...) {
753 this->set_name(_get_name());
760 template <
size_t N,
typename... ArgTypes>
761 class DeTup :
public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
762 Value<std::tuple<ArgTypes...>> tup;
765 this->value = std::get<N>(tup->get_value());
769 DeTup(
Value<std::tuple<ArgTypes...>>* tup,
const std::string& alias)
770 :
DerivedValue<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>(
"detup("+tup->get_name()+
")", alias),
778 template <
size_t N,
typename... ArgTypes>
780 Value<std::vector<std::tuple<ArgTypes...>>>* tup;
784 for(
auto& t : tup->get_value()){
785 this->value.push_back(std::get<N>(t));
790 DeTupVector(
Value<std::vector<std::tuple<ArgTypes...>>>* tup,
const std::string& alias)
791 :
DerivedValue<std::vector<
typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>(
"detup("+tup->get_name()+
")", alias),
795 template<
typename>
class Apply;
800 template <
typename Ret,
typename... ArgTypes>
803 Function<Ret(ArgTypes...)>& fn;
804 Value<std::tuple<ArgTypes...>>* arg;
807 auto &tup = arg->get_value();
808 this->value = call(fn, tup);
812 Apply(Function<Ret(ArgTypes...)>& fn,
Value<std::tuple<ArgTypes...>>* arg,
const std::string& alias)
824 Function<bool(T)>& selector;
836 Count(Function<
bool(T)>& selector,
Value<std::vector<T>>* v,
const std::string alias)
838 selector(selector), v(v) { }
847 Function<bool(T)>& filter;
853 if(this->filter(val))
854 this->value.push_back(val);
859 Filter(Function<
bool(T)>& filter,
Value<std::vector<T>>* v,
const std::string alias)
861 filter(filter), v(v) { }
869 template<
typename... ArgTypes>
872 typedef std::vector<std::tuple<ArgTypes...>> value_type;
873 Function<bool(ArgTypes...)>& filter;
880 this->value.push_back(val);
887 filter(filter), arg(arg) { }
896 template <
typename T>
899 Function<T(std::vector<T>)>& reduce;
902 this->value = reduce(v->get_value());
909 Reduce(Function<T(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias)
910 :
DerivedValue<T>(
"reduceWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
911 reduce(reduce), v(v) { }
917 template <
typename T>
920 Max(
Value<std::vector<T>>* v,
const std::string alias)
921 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"max",
922 FUNC(([](std::vector<T> vec){
923 return *std::max_element(vec.begin(), vec.end());}))),
930 template <
typename T>
933 Min(
Value<std::vector<T>>* v,
const std::string alias)
934 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"min",
935 FUNC(([](std::vector<T> vec){
936 return *std::min_element(vec.begin(), vec.end());}))),
943 template <
typename T>
946 Mean(
Value<std::vector<T>>* v,
const std::string alias)
947 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"mean",
948 FUNC(([](std::vector<T> vec){
949 int n = 0; T sum = 0;
950 for (T e : vec){ n++; sum += e; }
951 return n>0 ? sum / n : 0; }))),
958 template <
typename T>
961 Range(
Value<std::vector<T>>* v,
const std::string alias)
962 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"range",
963 FUNC(([](std::vector<T> vec){
964 auto minmax = std::minmax_element(vec.begin(), vec.end());
965 return (*minmax.second) - (*minmax.first); }))),
972 template <
typename T>
976 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"elementOf",
977 FUNC(([index](std::vector<T> vec){
return vec[index->
get_value()];}))),
986 template <
typename T>
989 Function<std::pair<T,int>(std::vector<T>)>& reduce;
993 this->value = reduce(v->get_value());
997 ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias=
"")
998 :
DerivedValue<T>(
"reduceIndexWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
999 reduce(reduce), v(v) { }
1005 template <
typename T>
1008 MaxIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1009 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"maxIndex",
1010 FUNC(([](std::vector<T> vec){
1011 auto elptr = std::max_element(vec.begin(), vec.end());
1012 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1019 template <
typename T>
1022 MinIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
1023 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"minIndex",
1024 FUNC(([](std::vector<T> vec){
1025 auto elptr = std::min_element(vec.begin(), vec.end());
1026 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
1033 template <
typename T,
int Size>
1037 typedef typename HomoTuple<T,Size>::type tuple_type;
1041 int data_size = v.size();
1042 this->value.clear();
1044 std::vector<bool> selector(data_size);
1045 std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}),
true);
1047 std::array<T, Size> perm;
1049 for (
int i=0; i<data_size; i++){
1053 if (idx == Size)
break;
1056 this->value.push_back(
a2t(perm));
1057 }
while(std::prev_permutation(selector.begin(), selector.end()));
1060 static std::string calc_name(
Value<std::vector<T>>* val){
1061 std::stringstream ss;
1062 ss <<
"combinations(" << Size <<
"," << val->get_name() <<
")";
1076 template <
typename FST,
typename SND>
1083 this->value.clear();
1086 for(
int i=0; i<v1.size(); i++){
1087 for(
int j=0; j<v2.size(); j++){
1088 this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
1093 static std::string calc_name(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2){
1094 std::stringstream ss;
1095 ss <<
"cartProduct(" 1096 << val1->get_name() <<
", " << val2->get_name()
1102 CartProduct(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2,
const std::string alias=
"")
1113 template <
typename T>
1121 BoundValue(Function<T()>& f,
const std::string alias=
"")
1130 template <
typename T>
1136 PointerValue(
const std::string& name, T* ptr,
const std::string alias=
"")
1145 template <
typename T>
1151 ConstantValue(
const std::string& name, T const_value,
const std::string alias=
"")
void update_value()
Updates the internal value.
Definition: value.hpp:1039
void update_value()
Updates the internal value.
Definition: value.hpp:1117
Find and return the maximum value of a vector.
Definition: value.hpp:918
Zips a series of vectors together.
Definition: value.hpp:639
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:897
void update_value()
Updates the internal value.
Definition: value.hpp:827
void update_value()
Updates the internal value.
Definition: value.hpp:563
Find and return the minimum value of a vector and its index.
Definition: value.hpp:1020
Find combinations of items from an input vector.
Definition: value.hpp:1034
A generic value owning only a function object.
Definition: value.hpp:1114
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:512
Calculate the range of the values in a vector.
Definition: value.hpp:959
void update_value()
Updates the internal value.
Definition: value.hpp:782
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:738
A std::vector wrapper around a C-style array.
Definition: value.hpp:539
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:987
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:822
Find and return the maximum value of a vector and its index.
Definition: value.hpp:1006
void update_value()
Updates the internal value.
Definition: value.hpp:901
Parent class to all Function classes.
Definition: value.hpp:143
void update_value()
Updates the internal value.
Definition: value.hpp:741
void update_value()
Updates the internal value.
Definition: value.hpp:876
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:845
Gets the Nth element from a tuple value.
Definition: value.hpp:761
Find and return the minimum value of a vector.
Definition: value.hpp:931
Creates a vector of extracting the Nth value from each entry in a vector of tuples.
Definition: value.hpp:779
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:560
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:806
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:463
void update_value()
Updates the internal value.
Definition: value.hpp:992
void update_value()
Updates the internal value.
Definition: value.hpp:677
void update_value()
Updates the internal value.
Definition: value.hpp:1148
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:973
Returns the elements in a vector that pass a test function.
Definition: value.hpp:870
Calculate the mean value of a vector.
Definition: value.hpp:944
void update_value()
Updates the internal value.
Definition: value.hpp:544
A generic value.
Definition: value.hpp:415
Calculate the cartesian product of two input vectors.
Definition: value.hpp:1077
void update_value()
Updates the internal value.
Definition: value.hpp:1082
void update_value()
Updates the internal value.
Definition: value.hpp:642
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:489
void update_value()
Updates the internal value.
Definition: value.hpp:850
void update_value()
Updates the internal value.
Definition: value.hpp:1133
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:1146
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:1131
void update_value()
Updates the internal value.
Definition: value.hpp:764