LMMS
Loading...
Searching...
No Matches
juce_FixedSizeFunction.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28namespace dsp
29{
30
31#ifndef DOXYGEN
32
33namespace detail
34{
35 template <typename Ret, typename... Args>
36 struct Vtable
37 {
38 using Storage = void*;
39
40 using Move = void (*) (Storage, Storage);
41 using Call = Ret (*) (Storage, Args...);
42 using Clear = void (*) (Storage);
43
44 constexpr Vtable (Move moveIn, Call callIn, Clear clearIn) noexcept
45 : move (moveIn), call (callIn), clear (clearIn) {}
46
47 Move move = nullptr;
48 Call call = nullptr;
49 Clear clear = nullptr;
50 };
51
52 template <typename Fn>
53 void move (void* from, void* to)
54 {
55 new (to) Fn (std::move (*reinterpret_cast<Fn*> (from)));
56 }
57
58 template <typename Fn, typename Ret, typename... Args>
59 typename std::enable_if<std::is_same<Ret, void>::value, Ret>::type call (void* s, Args... args)
60 {
61 (*reinterpret_cast<Fn*> (s)) (args...);
62 }
63
64 template <typename Fn, typename Ret, typename... Args>
65 typename std::enable_if<! std::is_same<Ret, void>::value, Ret>::type call (void* s, Args... args)
66 {
67 return (*reinterpret_cast<Fn*> (s)) (std::forward<Args> (args)...);
68 }
69
70 template <typename Fn>
71 void clear (void* s)
72 {
73 auto& fn = *reinterpret_cast<Fn*> (s);
74 fn.~Fn();
75 // I know this looks insane, for some reason MSVC 14 sometimes thinks fn is unreferenced
77 }
78
79 template <typename Fn, typename Ret, typename... Args>
80 constexpr Vtable<Ret, Args...> makeVtable()
81 {
82 return { move <Fn>, call <Fn, Ret, Args...>, clear<Fn> };
83 }
84} // namespace detail
85
86template <size_t len, typename T>
88
89#endif
90
101template <size_t len, typename Ret, typename... Args>
102class FixedSizeFunction<len, Ret (Args...)>
103{
104private:
105 using Storage = typename std::aligned_storage<len>::type;
106
107 template <typename Item>
108 using Decay = typename std::decay<Item>::type;
109
110 template <typename Item, typename Fn = Decay<Item>>
111 using IntIfValidConversion = typename std::enable_if<sizeof (Fn) <= len
112 && alignof (Fn) <= alignof (Storage)
113 && ! std::is_same<FixedSizeFunction, Fn>::value,
114 int>::type;
115
116public:
119
123
125
127 template <typename Callable,
128 typename Fn = Decay<Callable>,
130 FixedSizeFunction (Callable&& callable)
131 {
132 static_assert (sizeof (Fn) <= len,
133 "The requested function cannot fit in this FixedSizeFunction");
134 static_assert (alignof (Fn) <= alignof (Storage),
135 "FixedSizeFunction cannot accommodate the requested alignment requirements");
136
137 static constexpr auto vtableForCallable = detail::makeVtable<Fn, Ret, Args...>();
138 vtable = &vtableForCallable;
139
140 auto* ptr = new (&storage) Fn (std::forward<Callable> (callable));
141 jassertquiet ((void*) ptr == (void*) &storage);
142 }
143
146 : vtable (other.vtable)
147 {
148 move (std::move (other));
149 }
150
152 template <size_t otherLen, typename std::enable_if<(otherLen < len), int>::type = 0>
153 FixedSizeFunction (FixedSizeFunction<otherLen, Ret (Args...)>&& other) noexcept
154 : vtable (other.vtable)
155 {
156 move (std::move (other));
157 }
158
160 FixedSizeFunction& operator= (std::nullptr_t) noexcept
161 {
162 return *this = FixedSizeFunction();
163 }
164
165 FixedSizeFunction& operator= (const FixedSizeFunction&) = delete;
166
168 template <typename Callable, IntIfValidConversion<Callable> = 0>
169 FixedSizeFunction& operator= (Callable&& callable)
170 {
171 return *this = FixedSizeFunction (std::forward<Callable> (callable));
172 }
173
175 template <size_t otherLen, typename std::enable_if<(otherLen < len), int>::type = 0>
176 FixedSizeFunction& operator= (FixedSizeFunction<otherLen, Ret (Args...)>&& other) noexcept
177 {
178 return *this = FixedSizeFunction (std::move (other));
179 }
180
182 FixedSizeFunction& operator= (FixedSizeFunction&& other) noexcept
183 {
184 clear();
185 vtable = other.vtable;
186 move (std::move (other));
187 return *this;
188 }
189
191 ~FixedSizeFunction() noexcept { clear(); }
192
196 Ret operator() (Args... args) const
197 {
198 if (vtable != nullptr)
199 return vtable->call (&storage, std::forward<Args> (args)...);
200
201 throw std::bad_function_call();
202 }
203
205 explicit operator bool() const noexcept { return vtable != nullptr; }
206
207private:
208 template <size_t, typename>
209 friend class FixedSizeFunction;
210
212 {
213 if (vtable != nullptr)
214 vtable->clear (&storage);
215 }
216
217 template <size_t otherLen, typename T>
218 void move (FixedSizeFunction<otherLen, T>&& other) noexcept
219 {
220 if (vtable != nullptr)
221 vtable->move (&other.storage, &storage);
222 }
223
224 const detail::Vtable<Ret, Args...>* vtable = nullptr;
226};
227
228template <size_t len, typename T>
229bool operator!= (const FixedSizeFunction<len, T>& fn, std::nullptr_t) { return bool (fn); }
230
231template <size_t len, typename T>
232bool operator!= (std::nullptr_t, const FixedSizeFunction<len, T>& fn) { return bool (fn); }
233
234template <size_t len, typename T>
235bool operator== (const FixedSizeFunction<len, T>& fn, std::nullptr_t) { return ! (fn != nullptr); }
236
237template <size_t len, typename T>
238bool operator== (std::nullptr_t, const FixedSizeFunction<len, T>& fn) { return ! (fn != nullptr); }
239
240
241}
242}
#define noexcept
Definition DistrhoDefines.h:72
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
void clear() noexcept
Definition juce_FixedSizeFunction.h:211
FixedSizeFunction(FixedSizeFunction &&other) noexcept
Definition juce_FixedSizeFunction.h:145
FixedSizeFunction(const FixedSizeFunction &)=delete
typename std::decay< Item >::type Decay
Definition juce_FixedSizeFunction.h:108
FixedSizeFunction(Callable &&callable)
Definition juce_FixedSizeFunction.h:130
void move(FixedSizeFunction< otherLen, T > &&other) noexcept
Definition juce_FixedSizeFunction.h:218
typename std::enable_if< sizeof(Fn)<=len &&alignof(Fn)<=alignof(Storage) &&! std::is_same< FixedSizeFunction, Fn >::value, int >::type IntIfValidConversion
Definition juce_FixedSizeFunction.h:111
friend class FixedSizeFunction
Definition juce_FixedSizeFunction.h:209
typename std::aligned_storage< len >::type Storage
Definition juce_FixedSizeFunction.h:105
const detail::Vtable< Ret, Args... > * vtable
Definition juce_FixedSizeFunction.h:224
Storage storage
Definition juce_FixedSizeFunction.h:225
Definition juce_FixedSizeFunction.h:87
unsigned s
Definition inflate.c:1555
#define jassertquiet(expression)
Definition juce_FixedSizeFunction.h:34
void clear(void *s)
Definition juce_FixedSizeFunction.h:71
std::enable_if< std::is_same< Ret, void >::value, Ret >::type call(void *s, Args... args)
Definition juce_FixedSizeFunction.h:59
constexpr Vtable< Ret, Args... > makeVtable()
Definition juce_FixedSizeFunction.h:80
void move(void *from, void *to)
Definition juce_FixedSizeFunction.h:53
Definition juce_AudioBlock.h:29
Definition carla_juce.cpp:31
jack_client_t client jack_client_t client jack_client_t client jack_client_t JackInfoShutdownCallback void arg jack_client_t jack_port_t port void func jack_client_t const char const char unsigned long flags const jack_port_t port jack_client_t jack_port_id_t port_id const jack_port_t const char port_name const jack_port_t port void * ptr
Definition juce_linux_JackAudio.cpp:79
void ignoreUnused(Types &&...) noexcept
Definition juce_MathsFunctions.h:333
Definition juce_Uuid.h:141
Definition juce_FixedSizeFunction.h:37
void * Storage
Definition juce_FixedSizeFunction.h:38
Move move
Definition juce_FixedSizeFunction.h:47
constexpr Vtable(Move moveIn, Call callIn, Clear clearIn) noexcept
Definition juce_FixedSizeFunction.h:44
Call call
Definition juce_FixedSizeFunction.h:48
Clear clear
Definition juce_FixedSizeFunction.h:49
Ret(*)(Storage, Args...) Call
Definition juce_FixedSizeFunction.h:41
void(*)(Storage) Clear
Definition juce_FixedSizeFunction.h:42
void(*)(Storage, Storage) Move
Definition juce_FixedSizeFunction.h:40
const char const char const char const char char * fn
Definition swell-functions.h:168
#define void
Definition unzip.h:396
#define const
Definition zconf.h:137