Nugget
fixed_function.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
5 #ifndef EASTL_FIXED_FUNCTION_H
6 #define EASTL_FIXED_FUNCTION_H
7 
8 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
9  #pragma once
10 #endif
11 
12 #include <EASTL/internal/function_detail.h>
13 
14 namespace eastl
15 {
16  template <int, typename>
18 
19  namespace internal
20  {
21  template <typename>
23  : public eastl::false_type {};
24 
25  template <int SIZE_IN_BYTES, typename R, typename... Args>
26  struct is_fixed_function<eastl::fixed_function<SIZE_IN_BYTES, R(Args...)>>
27  : public eastl::true_type {};
28 
29  template<typename T>
30  EA_CONSTEXPR bool is_fixed_function_v = is_fixed_function<T>::value;
31  }
32 
33  #define EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(TYPE) \
34  static_assert(sizeof(TYPE) <= sizeof(typename Base::FunctorStorageType), \
35  "fixed_function local buffer is not large enough to hold the callable object.")
36 
37  #define EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES) \
38  static_assert(SIZE_IN_BYTES >= NEW_SIZE_IN_BYTES, \
39  "fixed_function local buffer is not large enough to hold the new fixed_function type.")
40 
41  template <typename Functor>
42  using EASTL_DISABLE_OVERLOAD_IF_FIXED_FUNCTION =
43  eastl::disable_if_t<internal::is_fixed_function_v<eastl::decay_t<Functor>>>;
44 
45 
46  // fixed_function
47  //
48  template <int SIZE_IN_BYTES, typename R, typename... Args>
49  class fixed_function<SIZE_IN_BYTES, R(Args...)> : public internal::function_detail<SIZE_IN_BYTES, R(Args...)>
50  {
51  using Base = internal::function_detail<SIZE_IN_BYTES, R(Args...)>;
52 
53  public:
54  using typename Base::result_type;
55 
56  fixed_function() EA_NOEXCEPT = default;
57  fixed_function(std::nullptr_t p) EA_NOEXCEPT
58  : Base(p)
59  {
60  }
61 
62  fixed_function(const fixed_function& other)
63  : Base(other)
64  {
65  }
66 
68  : Base(eastl::move(other))
69  {
70  }
71 
72  template <typename Functor,
73  typename = EASTL_INTERNAL_FUNCTION_VALID_FUNCTION_ARGS(Functor, R, Args..., Base, fixed_function),
74  typename = EASTL_DISABLE_OVERLOAD_IF_FIXED_FUNCTION<Functor>>
75  fixed_function(Functor functor)
76  : Base(eastl::move(functor))
77  {
78  EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(Functor);
79  }
80 
81  template<int NEW_SIZE_IN_BYTES>
82  fixed_function(const fixed_function<NEW_SIZE_IN_BYTES, R(Args...)>& other)
83  : Base(other)
84  {
85  EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES);
86  }
87 
88  template<int NEW_SIZE_IN_BYTES>
89  fixed_function(fixed_function<NEW_SIZE_IN_BYTES, R(Args...)>&& other)
90  : Base(eastl::move(other))
91  {
92  EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES);
93  }
94 
95  ~fixed_function() EA_NOEXCEPT = default;
96 
97  fixed_function& operator=(const fixed_function& other)
98  {
99  Base::operator=(other);
100  return *this;
101  }
102 
103  fixed_function& operator=(fixed_function&& other)
104  {
105  Base::operator=(eastl::move(other));
106  return *this;
107  }
108 
109  fixed_function& operator=(std::nullptr_t p) EA_NOEXCEPT
110  {
111  Base::operator=(p);
112  return *this;
113  }
114 
115  template<int NEW_SIZE_IN_BYTES>
116  fixed_function& operator=(const fixed_function<NEW_SIZE_IN_BYTES, R(Args...)>& other)
117  {
118  EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES);
119 
120  Base::operator=(other);
121  return *this;
122  }
123 
124  template<int NEW_SIZE_IN_BYTES>
125  fixed_function& operator=(fixed_function<NEW_SIZE_IN_BYTES, R(Args...)>&& other)
126  {
127  EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES);
128 
129  Base::operator=(eastl::move(other));
130  return *this;
131  }
132 
133  template <typename Functor,
134  typename = EASTL_INTERNAL_FUNCTION_VALID_FUNCTION_ARGS(Functor, R, Args..., Base, fixed_function),
135  typename = EASTL_DISABLE_OVERLOAD_IF_FIXED_FUNCTION<Functor>>
136  fixed_function& operator=(Functor&& functor)
137  {
138  EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(eastl::decay_t<Functor>);
139  Base::operator=(eastl::forward<Functor>(functor));
140  return *this;
141  }
142 
143  template <typename Functor>
144  fixed_function& operator=(eastl::reference_wrapper<Functor> f) EA_NOEXCEPT
145  {
146  EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(eastl::reference_wrapper<Functor>);
147  Base::operator=(f);
148  return *this;
149  }
150 
151  void swap(fixed_function& other) EA_NOEXCEPT
152  {
153  Base::swap(other);
154  }
155 
156  explicit operator bool() const EA_NOEXCEPT
157  {
158  return Base::operator bool();
159  }
160 
161  R operator ()(Args... args) const
162  {
163  return Base::operator ()(eastl::forward<Args>(args)...);
164  }
165 
166  #if EASTL_RTTI_ENABLED
167  const std::type_info& target_type() const EA_NOEXCEPT
168  {
169  return Base::target_type();
170  }
171 
172  template <typename Functor>
173  Functor* target() EA_NOEXCEPT
174  {
175  return Base::target();
176  }
177 
178  template <typename Functor>
179  const Functor* target() const EA_NOEXCEPT
180  {
181  return Base::target();
182  }
183  #endif
184  };
185 
186  template <int S, typename R, typename... Args>
187  bool operator==(const fixed_function<S, R(Args...)>& f, std::nullptr_t) EA_NOEXCEPT
188  {
189  return !f;
190  }
191 
192  template <int S, typename R, typename... Args>
193  bool operator==(std::nullptr_t, const fixed_function<S, R(Args...)>& f) EA_NOEXCEPT
194  {
195  return !f;
196  }
197 
198  template <int S, typename R, typename... Args>
199  bool operator!=(const fixed_function<S, R(Args...)>& f, std::nullptr_t) EA_NOEXCEPT
200  {
201  return !!f;
202  }
203 
204  template <int S, typename R, typename... Args>
205  bool operator!=(std::nullptr_t, const fixed_function<S, R(Args...)>& f) EA_NOEXCEPT
206  {
207  return !!f;
208  }
209 
210  template <int S, typename R, typename... Args>
211  void swap(fixed_function<S, R(Args...)>& lhs, fixed_function<S, R(Args...)>& rhs)
212  {
213  lhs.swap(rhs);
214  }
215 
216 } // namespace eastl
217 
218 #endif // EASTL_FIXED_FUNCTION_H
Definition: fixed_function.h:17
Definition: function_detail.h:416
reference_wrapper
Definition: functional_base.h:221
EA Standard Template Library.
Definition: algorithm.h:288
OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
Definition: copy_help.h:170
Definition: type_traits.h:263
Definition: fixed_function.h:23