Empirical
flex_function.h
Go to the documentation of this file.
1 
12 #ifndef EMP_FLEX_FUNCTION_H
13 #define EMP_FLEX_FUNCTION_H
14 
15 #include <functional>
16 #include <tuple>
17 
18 #include "../base/assert.h"
19 #include "../meta/meta.h"
20 
21 namespace emp {
22 
23  template <class T> class flex_function; // Not defined.
24 
27  template <class R, class... ARGS>
28  class flex_function<R(ARGS...)> {
29  public:
30  using size_t = std::size_t;
31  using return_t = R;
32  using fun_t = std::function<R(ARGS...)>;
33  using this_t = flex_function<R(ARGS...)>;
34  using tuple_t = std::tuple<ARGS...>;
35 
36  static constexpr int num_args = sizeof...(ARGS);
37 
38  private:
39  fun_t fun;
40  tuple_t default_args;
41 
42  public:
43  template <typename T>
44  flex_function(T && fun_info) : fun(std::forward<T>(fun_info)), default_args() { ; }
45  flex_function(const this_t &) = default;
46  flex_function(this_t &&) = default;
47  flex_function() { ; }
48 
49  this_t & operator=(const this_t &) = default;
50  this_t & operator=(this_t &&) = default;
51  this_t & operator=(const fun_t & _f) { fun=_f; return *this; }
52  this_t & operator=(fun_t && _f) { fun=std::move(_f); return *this; }
53  template <typename T>
54  this_t & operator=(T && arg) { fun = std::forward<T>(arg); return *this; }
55 
57  template <int ID> void SetDefault(pack_id<ID,ARGS...> & in_default) {
58  std::get<ID>(default_args) = in_default;
59  }
60 
62  void SetDefaults(ARGS... args) {
63  default_args = std::make_tuple(args...);
64  }
65 
67  return_t operator()(ARGS... k) const {
68  emp_assert(fun);
69  return fun(k...);
70  }
71 
73  template <class... IN_ARGS>
74  return_t operator()(IN_ARGS &&... k) const {
75  emp_assert(fun);
76  constexpr int in_args = sizeof...(IN_ARGS);
77  static_assert(in_args < num_args, "This operator() should only be called if too few args provided.");
78  return operator()(std::forward<IN_ARGS>(k)..., std::get<in_args>(default_args));
79  }
80 
82  operator bool() const { return (bool) fun; }
83 
84  };
85 
86 }
87 
88 #endif
Definition: flex_function.h:28
Definition: BitVector.h:785
return_t operator()(IN_ARGS &&...k) const
All the function to be called with a subset of arguments (and the rest set to defaults) ...
Definition: flex_function.h:74
R return_t
Definition: flex_function.h:31
this_t & operator=(T &&arg)
Definition: flex_function.h:54
this_t & operator=(fun_t &&_f)
Definition: flex_function.h:52
typename internal::pack_id_impl< ID, Ts... >::type pack_id
Definition: meta.h:40
this_t & operator=(const fun_t &_f)
Definition: flex_function.h:51
flex_function(T &&fun_info)
Definition: flex_function.h:44
If we are in emscripten, make sure to include the header.
Definition: array.h:37
void SetDefaults(ARGS...args)
Set the default values for all parameters.
Definition: flex_function.h:62
return_t operator()(ARGS...k) const
Allow the function to be called with all args.
Definition: flex_function.h:67
#define emp_assert(...)
Definition: assert.h:199
void SetDefault(pack_id< ID, ARGS... > &in_default)
Set the default value for a specific parameter.
Definition: flex_function.h:57
std::function< R(ARGS...)> fun_t
Definition: flex_function.h:32
std::tuple< ARGS... > tuple_t
Definition: flex_function.h:34
Definition: flex_function.h:23
flex_function()
Definition: flex_function.h:47