Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
function.hpp
Go to the documentation of this file.
1/*
2 FUNCTION.hpp - metaprogramming utilities for transforming function types
3
4 Copyright (C)
5 2009-2025, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
83#ifndef LIB_META_FUNCTION_H
84#define LIB_META_FUNCTION_H
85
86#include "lib/meta/typelist.hpp"
87#include "lib/meta/util.hpp"
88
89#include <functional>
90
91
92
93namespace lib {
94namespace meta{
95
96 using std::function;
97
98
99 /**************************************************************************/
141 template<typename FUN, typename SEL =void>
142 struct _Fun
143 : std::false_type
144 {
145 using Functor = FUN;
146 };
147
149 template<typename FUN>
151 : _Fun<decltype(&FUN::operator())>
152 {
153 using Functor = FUN;
154 };
155
157 template<typename RET, typename...ARGS>
158 struct _Fun<RET(ARGS...)>
159 : std::true_type
160 {
161 using Ret = RET;
162 using Args = Types<ARGS...>;
163 using Sig = RET(ARGS...);
164 using Functor = std::function<Sig>;
165 enum { ARITY = sizeof...(ARGS) };
166 };
167
169 template<typename RET, typename...ARGS>
170 struct _Fun<RET(ARGS...) noexcept>
171 : _Fun<RET(ARGS...)>
172 { };
173
175 template<typename SIG>
176 struct _Fun<SIG*>
177 : _Fun<SIG>
178 { };
179
181 template<typename SIG>
182 struct _Fun<SIG const&>
183 : _Fun<SIG>
184 { };
185
187 template<typename SIG>
188 struct _Fun<SIG&>
189 : _Fun<SIG>
190 { };
191
193 template<typename SIG>
194 struct _Fun<SIG&&>
195 : _Fun<SIG>
196 { };
197
199 template<class C, typename RET, typename...ARGS>
200 struct _Fun<RET (C::*) (ARGS...)>
201 : _Fun<RET(ARGS...)>
202 { };
203
205 template<class C, typename RET, typename...ARGS>
206 struct _Fun<RET (C::*) (ARGS...) noexcept>
207 : _Fun<RET(ARGS...)>
208 { };
209
213 template<class C, typename RET, typename...ARGS>
214 struct _Fun<RET (C::*) (ARGS...) const>
215 : _Fun<RET(ARGS...)>
216 { };
217
219 template<class C, typename FUN>
220 struct _Fun<FUN (C::*)>
221 : _Fun<FUN>
222 { };
223
224
225
226
227
235 template<typename RET, typename ARGS>
237
238 template<typename RET, typename...ARGS>
239 struct BuildFunType<RET, Types<ARGS...>>
240 {
241 using Sig = RET(ARGS...);
242 using Fun = _Fun<Sig>;
244 using Functor = Func;
245 };
246
247
248
249
250
252 template<typename FUN>
254
255 namespace {
256 template<typename FUN>
258 {
259 static_assert(_Fun<FUN>() , "something funktion-like required");
260 static_assert(_Fun<FUN>::ARITY == 1 , "function with exactly one argument required");
261
264 };
265 }
266
268 template<typename FUN>
269 using _FunArg = _DetectSingleArgFunction<FUN>::Arg;
270
271
272
273 template<typename FUN, uint a>
274 using has_Arity = std::bool_constant<_Fun<FUN>::ARITY == a>;
275
276 template<typename FUN>
278
279 template<typename FUN>
281
282 template<typename FUN>
284
285 template<typename FUN>
287
288
289
290
291
301 struct has_Sig
302 : std::is_same<SIG, typename _Fun<FUN>::Sig>
303 { };
304
306 template<typename FUN, typename X>
307 struct has_Sig<FUN,X, false>
308 : std::false_type
309 { };
310
316#define ASSERT_VALID_SIGNATURE(_FUN_, _SIG_) \
317 static_assert (lib::meta::has_Sig<_FUN_, _SIG_>::value, \
318 "Function " STRINGIFY(_FUN_) " unsuitable, expected signature: " STRINGIFY(_SIG_));
319
320
321
330 template<typename SIG, typename FUN>
331 constexpr inline auto
333 {
334 return has_Sig<FUN,SIG>{};
335 }
336
342#define ASSERT_MEMBER_FUNCTOR(_EXPR_, _SIG_) \
343 static_assert (lib::meta::isFunMember<_SIG_>(_EXPR_), \
344 "Member " STRINGIFY(_EXPR_) " unsuitable, expect function signature: " STRINGIFY(_SIG_));
345
346
347
348
349
350
352 template<class TAR>
354
355 namespace {// Helper to inject instance-pointer instead of placeholder...
360 template<class W, class TAR>
361 constexpr inline TAR*
363 {
364 return static_cast<TAR*> (&instance);
365 }
366
368 template<class W, typename X>
369 constexpr inline X
370 maybeInject (W&, X&& x)
371 {
372 return std::move(x);
373 }
374 }//(End)Helper for lateBindInstance.
375
385 template<class W, class TUP>
386 constexpr inline auto
387 lateBindInstance (W& instance, TUP&& invocation)
388 {
389 auto splice = [&instance](auto&& ...xs)
390 {
391 return std::tuple{maybeInject (instance, std::move(xs))...};
392 };
393 return std::apply (splice, std::forward<TUP> (invocation));
394 }
395
396
397
398}} // namespace lib::meta
399#endif
Trait template to detect presence of a simple function call operator.
Simple and lightweight helpers for metaprogramming and type detection.
constexpr TAR * maybeInject(W &instance, InstancePlaceholder< TAR >)
Definition function.hpp:362
has_Arity< FUN, 0 > is_NullaryFun
Definition function.hpp:277
_Fun< FUN >::Ret _FunRet
abbreviation for referring to a function's return type
Definition function.hpp:253
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
std::bool_constant< _Fun< FUN >::ARITY==a > has_Arity
Definition function.hpp:274
has_Arity< FUN, 1 > is_UnaryFun
Definition function.hpp:280
has_Arity< FUN, 3 > is_TernaryFun
Definition function.hpp:286
constexpr auto isFunMember(FUN)
Helper to pick up a member field for verification.
Definition function.hpp:332
_DetectSingleArgFunction< FUN >::Arg _FunArg
abbreviation for referring to a function's single Argument type
Definition function.hpp:269
has_Arity< FUN, 2 > is_BinaryFun
Definition function.hpp:283
constexpr auto lateBindInstance(W &instance, TUP &&invocation)
Fix-up the arguments for a member-function invocation, allowing to inject the actual this instance in...
Definition function.hpp:387
Build function types from given Argument types.
Definition function.hpp:236
Placeholder marker for a special argument position to be supplied later.
Definition function.hpp:353
variadic sequence of types
Definition typelist.hpp:102
Implementation namespace for support and library code.
std::function< Sig > Functor
Definition function.hpp:164
Trait template for uniform access to function signature types.
Definition function.hpp:144
Meta-function to check that some function like entity offers the expected signature.
Definition function.hpp:303
A template metaprogramming technique for manipulating collections of types.