CppCommon  1.0.4.1
C++ Common Library
function.inl
Go to the documentation of this file.
1 
9 namespace CppCommon {
10 
11 template <class R, class... Args, size_t Capacity>
12 inline Function<R(Args...), Capacity>::Function() noexcept
13  : _data(),
14  _invoker(nullptr),
15  _manager(nullptr)
16 {
17 }
18 
19 template <class R, class... Args, size_t Capacity>
20 inline Function<R(Args...), Capacity>::Function(std::nullptr_t) noexcept
21  : Function<R(Args...), Capacity>()
22 {
23 }
24 
25 template <class R, class... Args, size_t Capacity>
26 inline Function<R(Args...), Capacity>::Function(const Function& function) noexcept
27  : Function<R(Args...), Capacity>()
28 {
29  if (function)
30  {
31  function._manager(&_data, &function._data, Operation::Clone);
32  _invoker = function._invoker;
33  _manager = function._manager;
34  }
35 }
36 
37 template <class R, class... Args, size_t Capacity>
38 inline Function<R(Args...), Capacity>::Function(Function&& function) noexcept
39  : Function<R(Args...), Capacity>()
40 {
41  function.swap(*this);
42 }
43 
44 template <class R, class... Args, size_t Capacity>
45 template <class TFunction>
46 inline Function<R(Args...), Capacity>::Function(TFunction&& function) noexcept
47  : Function<R(Args...), Capacity>()
48 {
49  using function_type = typename std::decay<TFunction>::type;
50 
51  // Check implementation storage parameters
52  static_assert((StorageSize >= sizeof(function_type)), "Function::StorageSize must be increased!");
53  static_assert(((StorageAlign % alignof(function_type)) == 0), "Function::StorageAlign must be adjusted!");
54 
55  // Create the implementation instance
56  new (&_data) function_type(std::forward<TFunction>(function));
57 
58  _invoker = &Invoke<function_type>;
59  _manager = &Manage<function_type>;
60 }
61 
62 template <class R, class... Args, size_t Capacity>
63 inline Function<R(Args...), Capacity>::~Function() noexcept
64 {
65  if (_manager)
66  _manager(&_data, nullptr, Operation::Destroy);
67 }
68 
69 template <class R, class... Args, size_t Capacity>
70 inline Function<R(Args...), Capacity>& Function<R(Args...), Capacity>::operator=(std::nullptr_t) noexcept
71 {
72  if (_manager)
73  {
74  _manager(&_data, nullptr, Operation::Destroy);
75  _manager = nullptr;
76  _invoker = nullptr;
77  }
78  return *this;
79 }
80 
81 template <class R, class... Args, size_t Capacity>
82 inline Function<R(Args...), Capacity>& Function<R(Args...), Capacity>::operator=(const Function& function) noexcept
83 {
84  Function(function).swap(*this);
85  return *this;
86 }
87 
88 template <class R, class... Args, size_t Capacity>
89 inline Function<R(Args...), Capacity>& Function<R(Args...), Capacity>::operator=(Function&& function) noexcept
90 {
91  Function(std::move(function)).swap(*this);
92  return *this;
93 }
94 
95 template <class R, class... Args, size_t Capacity>
96 template <typename TFunction>
97 inline Function<R(Args...), Capacity>& Function<R(Args...), Capacity>::operator=(TFunction&& function) noexcept
98 {
99  Function(std::forward<TFunction>(function)).swap(*this);
100  return *this;
101 }
102 
103 template <class R, class... Args, size_t Capacity>
104 template <typename TFunction>
105 inline Function<R(Args...), Capacity>& Function<R(Args...), Capacity>::operator=(std::reference_wrapper<TFunction> function) noexcept
106 {
107  Function(function).swap(*this);
108  return *this;
109 }
110 
111 template <class R, class... Args, size_t Capacity>
112 inline R Function<R(Args...), Capacity>::operator()(Args... args)
113 {
114  if (!_invoker)
115  throw std::bad_function_call();
116 
117  return _invoker(&_data, std::forward<Args>(args)...);
118 }
119 
120 template <class R, class... Args, size_t Capacity>
121 template <typename TFunction>
122 inline R Function<R(Args...), Capacity>::Invoke(void* data, Args&&... args) noexcept
123 {
124  TFunction& function = *static_cast<TFunction*>(data);
125  return function(std::forward<Args>(args)...);
126 }
127 
128 template <class R, class... Args, size_t Capacity>
129 template <typename TFunction>
130 inline void Function<R(Args...), Capacity>::Manage(void* dst, void* src, Operation op) noexcept
131 {
132  switch (op)
133  {
134  case Operation::Clone:
135  new (dst) TFunction(*static_cast<TFunction*>(src));
136  break;
137  case Operation::Destroy:
138  static_cast<TFunction*>(dst)->~TFunction();
139  break;
140  }
141 }
142 
143 template <class R, class... Args, size_t Capacity>
144 inline void Function<R(Args...), Capacity>::swap(Function& function) noexcept
145 {
146  using std::swap;
147  swap(_data, function._data);
148  swap(_manager, function._manager);
149  swap(_invoker, function._invoker);
150 }
151 
152 template <class R, class... Args, size_t Capacity>
153 void swap(Function<R(Args...), Capacity>& function1, Function<R(Args...), Capacity>& function2) noexcept
154 {
155  function1.swap(function2);
156 }
157 
158 } // namespace CppCommon
Allocation free function stub.
Definition: function.h:19
C++ Common project definitions.
Definition: token_bucket.h:15
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition: filecache.inl:23
void swap(Function< R(Args...), Capacity > &function1, Function< R(Args...), Capacity > &function2) noexcept
Definition: function.inl:153