53 #include <initializer_list> 63 template <
typename F,
typename TUPLE,
bool Done,
int Total,
int... N>
66 static auto call(F& f, TUPLE && t)
68 return call_impl<F, TUPLE, Total == 1 +
sizeof...(N), Total, N...,
sizeof...(N)>
::call(f, std::forward<TUPLE>(t));
72 template <
typename F,
typename TUPLE,
int Total,
int... N>
73 struct call_impl<F, TUPLE, true, Total, N...>
75 static auto call(F& f, TUPLE && t)
77 return f(std::get<N>(std::forward<TUPLE>(t))...);
85 template <
typename F,
typename TUPLE>
86 auto call(F& f, TUPLE && t)
88 typedef typename std::decay<TUPLE>::type ttype;
89 return call_impl<F, TUPLE, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>
::call(f, std::forward<TUPLE>(t));
92 template<
typename>
class Function;
103 inline static bool in_register_function=
false;
112 GenFunction(
const std::string& name,
const std::string& impl)
118 std::string& get_name(){
128 std::stringstream code_out(
"");
129 std::string command(
"echo \""+code+
"\" | clang-format");
131 FILE *stream = popen(command.c_str(),
"r");
132 while (fgets(buffer, 255, stream) != NULL)
134 if (pclose(stream) == 0)
135 return code_out.str();
140 static std::string summary(){
141 std::stringstream ss;
142 ss <<
"The following functions have been registered" << std::endl;
143 for(
auto p : function_registry){
144 if (p.second ==
nullptr)
continue;
145 ss <<
"-->" << p.second->name <<
"@" << p.second << std::endl;
146 ss << format_code(p.second->impl);
151 template <
typename T>
152 static Function<T>& register_function(
const std::string& name, std::function<T> f,
const std::string& impl){
153 in_register_function =
true;
157 if (func ==
nullptr){
158 ERROR(
"Trying to register function which has already been registered with a different type");
161 func =
new Function<T>(name, impl, f);
164 in_register_function =
false;
168 template <
typename T>
169 static Function<T>& lookup_function(
const std::string& name){
171 CRITICAL(
"Function \"" << name <<
"\" not previously registered", -1);
174 if (func ==
nullptr){
175 CRITICAL(
"Function \"" << name <<
"\" request and register have mismatched types", -1);
194 template <
typename R,
typename... ArgTypes>
197 std::function<R(ArgTypes...)> f;
200 Function(
const std::string& name,
const std::string& impl, std::function<R(ArgTypes...)> f)
202 if (!in_register_function) {
203 WARNING(
"Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
206 Function(
const std::string& name, std::function<R(ArgTypes...)> f)
207 :Function(name,
"N/A", f){ }
210 R operator()(ArgTypes ...args){
217 #define FUNC(f) f, #f 226 typedef std::map<std::string, GenValue*> ValueSet;
243 virtual void _reset() = 0;
251 inline static std::map<const std::string, GenValue*> values;
259 inline static std::map<const std::string, GenValue*> aliases;
262 GenValue(
const std::string& name,
const std::string& alias)
266 GenValue::alias(alias,
this);
269 const std::string& get_name(){
273 void set_name(
const std::string& new_name){
274 values[name] =
nullptr;
280 for (
auto val : values){
281 if (val.second !=
nullptr){
282 val.second->_reset();
287 static GenValue* get_value(
const std::string& name){
288 if (aliases[name] !=
nullptr)
289 return aliases[name];
290 else if (values[name] !=
nullptr)
293 ERROR(
"Could not find alias or value \"" << name <<
"\". I'll tell you the ones I know about." << std::endl
295 CRITICAL(
"Aborting... :(",-1);
299 static void alias(
const std::string& name, GenValue* value){
300 if (aliases[name] !=
nullptr){
301 WARNING(
"WARNING: alias \"" << name <<
"\" overrides previous entry.");
303 aliases[name] = value;
306 static GenValue* alias(
const std::string& name){
307 if (values[name] !=
nullptr){
308 WARNING(
"Alias \"" << name <<
"\" does not exist.");
310 return aliases[name];
313 static std::string summary(){
314 std::stringstream ss;
315 ss <<
"The following values have been created: " << std::endl;
316 for (
auto value : values){
317 if (value.second ==
nullptr)
continue;
318 ss <<
"\t\"" << value.first <<
"\" at address " << value.second << std::endl;
320 ss <<
"And these aliases:" << std::endl;
321 for (
auto alias : aliases){
322 std::string orig(
"VOID");
323 if (alias.second ==
nullptr)
continue;
324 for (
auto value : values){
325 if (alias.second == value.second){
326 orig = value.second->get_name();
330 ss <<
"\t\"" << alias.first <<
"\" referring to \"" << orig <<
"\"" << std::endl;
334 friend std::ostream& operator<<(std::ostream& os,
const GenValue& gv);
336 std::ostream& operator<<(std::ostream& os, GenValue& gv){
351 template <
typename T>
354 Value(
const std::string& name,
const std::string& alias=
"")
355 :GenValue(name, alias){ }
358 virtual T& get_value() = 0;
371 template <
typename T>
378 ObservedValue(
const std::string& name, T* val_ref,
const std::string& alias=
"")
402 template <
typename T>
420 virtual void update_value() = 0;
422 DerivedValue(
const std::string& name,
const std::string& alias=
"")
424 value_valid(
false) { }
445 template <
typename T>
454 this->value.assign(data_ref, data_ref+n);
460 size(size), data(data){ }
466 template <
typename T1,
typename T2>
469 std::pair<Value<T1>*,
Value<T2>* > value_pair;
471 this->value.first = value_pair.first->get_value();
472 this->value.second = value_pair.second->get_value();
478 value_pair(value1, value2){ }
481 template<
typename... T>
class _Zip;
487 return std::numeric_limits<int>::max();
490 std::tuple<> _get_at(
int idx){
491 return std::make_tuple();
494 std::string _get_name(){
502 template<
typename Head,
typename... Tail>
503 class _Zip<Head, Tail...> :
private _Zip<Tail...> {
508 int this_size = head->
get_value().size();
509 int rest_size = _Zip<Tail...>::_get_size();
510 return std::min(this_size, rest_size);
513 typename std::tuple<Head,Tail...> _get_at(
int idx){
514 auto tail_tuple = _Zip<Tail...>::_get_at(idx);
515 return std::tuple_cat(std::make_tuple(head->
get_value()[idx]),tail_tuple);
518 std::string _get_name(){
519 return head->get_name()+
","+_Zip<Tail...>::_get_name();
525 _Zip(
Value<std::vector<Head>>* head,
Value<std::vector<Tail>>*... tail)
526 : _Zip<Tail...>(tail...),
545 template <
typename... ArgTypes>
547 private _Zip<ArgTypes...>{
551 int size = _Zip<ArgTypes...>::_get_size();
552 for(
int i=0; i<size; i++){
553 this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
557 std::string _get_name(){
558 return "zip("+_Zip<ArgTypes...>::_get_name()+
")";
562 Zip(
Value<std::vector<ArgTypes>>*... args,
const std::string& alias)
563 :
DerivedValue<std::vector<std::tuple<ArgTypes...>>>(
"", alias),
564 _Zip<ArgTypes...>(args...) {
565 this->set_name(_get_name());
569 template<
typename>
class Map;
577 template <
typename Ret,
typename... ArgTypes>
580 typedef Value<std::vector<std::tuple<ArgTypes...>>>
arg_type;
581 Function<Ret(ArgTypes...)>& fn;
587 this->value.push_back(
call(fn,tup));
592 Map(Function<Ret(ArgTypes...)>& fn,
arg_type* arg,
const std::string& alias)
602 template<
typename... ArgTypes>
605 typedef std::vector<std::tuple<ArgTypes...>> value_type;
606 Function<bool(ArgTypes...)>& filter;
613 this->value.push_back(val);
620 filter(filter), arg(arg) { }
623 template<
typename... T>
class _Tuple;
628 std::tuple<> _get_value(){
629 return std::make_tuple();
632 std::string _get_name(){
640 template<
typename Head,
typename... Tail>
641 class _Tuple<Head, Tail...> :
private _Tuple<Tail...> {
645 typename std::tuple<Head,Tail...> _get_value(){
646 auto tail_tuple = _Tuple<Tail...>::_get_value();
647 return std::tuple_cat(std::make_tuple(head->
get_value()),tail_tuple);
651 std::string _get_name(){
652 return head->get_name()+
","+_Tuple<Tail...>::_get_name();
659 : _Tuple<Tail...>(tail...),
669 template <
typename... ArgTypes>
671 private _Tuple<ArgTypes...>{
674 this->value = _Tuple<ArgTypes...>::_get_value();
677 std::string _get_name(){
678 return "tuple("+_Tuple<ArgTypes...>::_get_name()+
")";
684 _Tuple<ArgTypes...>(args...) {
685 this->set_name(_get_name());
689 template<
typename>
class Apply;
694 template <
typename Ret,
typename... ArgTypes>
697 Function<Ret(ArgTypes...)>& fn;
698 Tuple<ArgTypes...>* arg;
701 auto &tup = arg->get_value();
702 this->value =
call(fn, tup);
706 Apply(Function<Ret(ArgTypes...)>& fn,
Tuple<ArgTypes...>* arg,
const std::string& alias)
719 Function<bool(T)>& selector;
731 Count(Function<
bool(T)>& selector,
Value<std::vector<T>>* v,
const std::string alias)
733 selector(selector), v(v) { }
742 Function<bool(T)>& filter;
749 this->value.push_back(val);
754 Filter(Function<
bool(T)>& filter,
Value<std::vector<T>>* v,
const std::string alias)
756 filter(filter), v(v) { }
766 template <
typename T>
769 Function<T(std::vector<T>)>& reduce;
772 this->value = reduce(v->get_value());
779 Reduce(Function<T(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias)
780 :
DerivedValue<T>(
"reduceWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
781 reduce(reduce), v(v) { }
787 template <
typename T>
790 Max(
Value<std::vector<T>>* v,
const std::string alias)
791 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"max",
792 FUNC(([](std::vector<T> vec){
793 return *std::max_element(vec.begin(), vec.end());}))),
800 template <
typename T>
803 Min(
Value<std::vector<T>>* v,
const std::string alias)
804 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"min",
805 FUNC(([](std::vector<T> vec){
806 return *std::min_element(vec.begin(), vec.end());}))),
813 template <
typename T>
816 Mean(
Value<std::vector<T>>* v,
const std::string alias)
817 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"mean",
818 FUNC(([](std::vector<T> vec){
819 int n = 0; T sum = 0;
820 for (T e : vec){ n++; sum += e; }
821 return n>0 ? sum / n : 0; }))),
828 template <
typename T>
831 Range(
Value<std::vector<T>>* v,
const std::string alias)
832 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"range",
833 FUNC(([](std::vector<T> vec){
834 auto minmax = std::minmax_element(vec.begin(), vec.end());
835 return (*minmax.second) - (*minmax.first); }))),
842 template <
typename T>
846 :
Reduce<T>(GenFunction::register_function<T(std::vector<T>)>(
"elementOf",
847 FUNC(([index](std::vector<T> vec){
return vec[index->
get_value()];}))),
856 template <
typename T>
859 Function<std::pair<T,int>(std::vector<T>)>& reduce;
863 this->value = reduce(v->get_value());
867 ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce,
Value<std::vector<T> >* v,
const std::string alias=
"")
868 :
DerivedValue<T>(
"reduceIndexWith("+reduce.get_name()+
":"+v->get_name()+
")", alias),
869 reduce(reduce), v(v) { }
875 template <
typename T>
878 MaxIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
879 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"maxIndex",
880 FUNC(([](std::vector<T> vec){
881 auto elptr = std::max_element(vec.begin(), vec.end());
882 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
889 template <
typename T>
892 MinIndex(
Value<std::vector<T>>* v,
const std::string alias=
"")
893 :
ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>(
"minIndex",
894 FUNC(([](std::vector<T> vec){
895 auto elptr = std::min_element(vec.begin(), vec.end());
896 return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
903 template <
typename FST,
typename SND>
914 for(
int i=0; i<v1.size(); i++){
915 int lower_lim = self_product ? i+1 : 0;
916 for(
int j=lower_lim; j<v2.size(); j++){
917 this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
923 CartProduct(
Value<std::vector<FST>>* val1,
Value<std::vector<SND>>* val2,
const std::string alias=
"")
925 val1->get_name()+
","+
926 val2->get_name()+
")", alias),
929 self_product(val1 == val2) { }
937 template <
typename T>
945 BoundValue(Function<T()>& f,
const std::string alias=
"")
954 template <
typename T>
960 PointerValue(
const std::string& name, T* ptr,
const std::string alias=
"")
969 template <
typename T>
975 ConstantValue(
const std::string& name, T const_value,
const std::string alias=
"")
void update_value()
Updates the internal value.
Definition: value.hpp:941
Find and return the maximum value of a vector.
Definition: value.hpp:788
Zips a series of vectors together.
Definition: value.hpp:546
Reduce a Value of type vector<T> to just a T.
Definition: value.hpp:767
void update_value()
Updates the internal value.
Definition: value.hpp:722
void update_value()
Updates the internal value.
Definition: value.hpp:470
Find and return the minimum value of a vector and its index.
Definition: value.hpp:890
A generic value owning only a function object.
Definition: value.hpp:938
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:426
Calculate the range of the values in a vector.
Definition: value.hpp:829
Takes a series of Value objects and bundles them together into a std::tuple object.
Definition: value.hpp:670
A std::vector wrapper around a C-style array.
Definition: value.hpp:446
Similar to Reduce, but returns a pair of a T and an int.
Definition: value.hpp:857
Returns the count of elements in the input vector passing a test function.
Definition: value.hpp:717
Find and return the maximum value of a vector and its index.
Definition: value.hpp:876
void update_value()
Updates the internal value.
Definition: value.hpp:771
Parent class to all Function classes.
Definition: value.hpp:98
void update_value()
Updates the internal value.
Definition: value.hpp:673
void update_value()
Updates the internal value.
Definition: value.hpp:609
A value supplied by the dataset, not derived.
Definition: value.hpp:372
Returns the elements in a vector that pass a test function.
Definition: value.hpp:740
Find and return the minimum value of a vector.
Definition: value.hpp:801
Creates a std::pair type from a two other Value objects.
Definition: value.hpp:467
void update_value()
Updates the internal value.
Definition: value.hpp:700
T & get_value()
Calculate, if necessary, and return the value held by this object.
Definition: value.hpp:381
void update_value()
Updates the internal value.
Definition: value.hpp:862
void update_value()
Updates the internal value.
Definition: value.hpp:584
void update_value()
Updates the internal value.
Definition: value.hpp:972
The namespace containing all filval classes and functions.
Definition: api.hpp:6
Extract the element at a specific index from a vector.
Definition: value.hpp:843
Returns the elements in a vector that pass a test function.
Definition: value.hpp:603
Calculate the mean value of a vector.
Definition: value.hpp:814
void update_value()
Updates the internal value.
Definition: value.hpp:451
A generic value.
Definition: value.hpp:352
Find and return the minimum value of a vector and its index.
Definition: value.hpp:904
void update_value()
Updates the internal value.
Definition: value.hpp:910
void update_value()
Updates the internal value.
Definition: value.hpp:549
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:127
A Value derived from some other Values, not directly from the dataset.
Definition: value.hpp:403
void update_value()
Updates the internal value.
Definition: value.hpp:745
void update_value()
Updates the internal value.
Definition: value.hpp:957
virtual T & get_value()=0
Calculate, if necessary, and return the value held by this object.
auto call(F &f, TUPLE &&t)
This calls a function of type F with the contents of the tuple as separate arguments.
Definition: value.hpp:86
A Value which always returns the same value, supplied in the constructor.
Definition: value.hpp:970
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:110
A Value of a pointer.
Definition: value.hpp:955