mn_function.hpp
Go to the documentation of this file.
1 
20 #ifndef _MINLIB_MN_FUNCTION_LIGHT_H_
21 #define _MINLIB_MN_FUNCTION_LIGHT_H_
22 
23 #include "mn_config.hpp"
24 
25 #include "mn_functional.hpp"
26 #include "utils/mn_alignment.hpp"
27 
28 #include <type_traits>
29 
30 
31 namespace mn {
32 
33  template <class Sig, size_t sz, size_t algn>
34  class small_task;
35 
36  template <class R, class... Args, size_t sz, size_t algn>
37  class small_task<R(Args...), sz, algn> {
38  struct vtable_t {
39  void (*mover)(void *src, void *dest);
40 
41  void (*destroyer)(void *);
42 
43  R (*invoke)(void const *t, Args &&...args);
44 
45  template <class T> static vtable_t const *get() {
46  static const vtable_t table = {
47  [](void *src, void *dest) { new (dest) T(move(*static_cast<T *>(src))); },
48  [](void *t) { static_cast<T *>(t)->~T(); },
49  [](void const *t, Args &&...args) -> R {
50  return (*static_cast<T const *>(t))(forward<Args>(args)...);
51  }
52  };
53  return &table;
54  }
55  };
56  public:
57  using return_type = R;
58 
59  small_task() { }
61  : table(o.table), data(o.data) { }
62 
64  : table(o.table) {
65  if (table) table->mover(&o.data, &data);
66  }
67 
68  template <class F, class dF = decay_t<F>, enable_if_t<!is_same<dF, small_task>{}> * = nullptr,
69  enable_if_t<is_convertible<res_of_t<dF &(Args...)>, R>{}> * = nullptr>
70  small_task(F &&f) : table(vtable_t::template get<dF>()) {
71  static_assert(sizeof(dF) <= sz, "object too large");
72  static_assert(alignof(dF) <= algn, "object too aligned");
73  new (&data) dF(forward<F>(f));
74  }
76  if (table) table->destroyer(&data);
77  }
78 
79 
81  this->~small_task();
82  new (this) small_task(move(o));
83  return *this;
84  }
85 
87  this->~small_task();
88  new (this) small_task(move(o));
89  return *this;
90  }
91 
92  explicit operator bool() const {
93  return table;
94  }
95 
96  return_type operator()(Args... args) const {
97  return table->invoke(&data, mn::forward<Args>(args)...);
98  }
99  private:
100  vtable_t const *table = nullptr;
101  aligned_storage_t<sz, algn> data;
102  };
103 
104  template <class R, class... Args, size_t sz, size_t algn>
105  inline bool operator==(const small_task<R(Args...), sz, algn> &__f, nullptr_t) {
106  return !static_cast<bool>(__f);
107  }
108 
109 
110  template <class R, class... Args, size_t sz, size_t algn>
111  inline bool operator==(nullptr_t, const small_task<R(Args...), sz, algn> &__f) {
112  return !static_cast<bool>(__f);
113  }
114 
115  template <class R, class... Args, size_t sz, size_t algn>
116  inline bool operator!=(const small_task<R(Args...), sz, algn> &__f, nullptr_t) {
117  return static_cast<bool>(__f);
118  }
119 
120  template <class R, class... Args, size_t sz, size_t algn>
121  inline bool operator!=(nullptr_t, const small_task<R(Args...), sz, algn> &__f) {
122  return static_cast<bool>(__f);
123  }
124 
125  template <class Sig>
126  using function = small_task<Sig, sizeof(void *) * 4, alignof(void *)>;
127 
128 }
129 
130 #include <functional>
131 
132 #endif
small_task(const small_task &o)
Definition: mn_function.hpp:60
small_task()
Definition: mn_function.hpp:59
small_task(small_task &&o)
Definition: mn_function.hpp:63
return_type operator()(Args... args) const
Definition: mn_function.hpp:96
R return_type
Definition: mn_function.hpp:57
small_task(F &&f)
Definition: mn_function.hpp:70
small_task & operator=(small_task &&o)
Definition: mn_function.hpp:86
aligned_storage_t< sz, algn > data
Definition: mn_function.hpp:101
~small_task()
Definition: mn_function.hpp:75
small_task & operator=(const small_task &o)
Definition: mn_function.hpp:80
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
T * get(const basic_linked_ptr< T > &_pPtr)
Get the pointer object.
Definition: mn_linked_ptr.hpp:223
Definition: mn_allocator_typetraits.hpp:25
constexpr bool operator==(const byte l, const byte r) noexcept
Definition: mn_def.hpp:112
constexpr bool operator!=(const byte l, const byte r) noexcept
Definition: mn_def.hpp:116
decltype(nullptr) nullptr_t
Definition: mn_def.hpp:45
void move(const T *src, const T *last, T *dest)
Definition: mn_algorithm.hpp:100
Definition: mn_function.hpp:34
static vtable_t const * get()
Definition: mn_function.hpp:45