21 #ifndef STATIC_ASSERT_H
28 #include <type_traits>
34 template<
typename RT,
typename P1,
typename P2,
typename P3>
37 typedef RT (*
Type)(P1,P2,P3);
40 template<
typename RT,
typename P1,
typename P2>
45 template<
typename RT,
typename P1>
85 template<>
class ConstParamT<void> {
class Unused {};
public:
typedef Unused
Type; };
92 #define INVALID_CB_PARAM_TYPE(TYPE) template<> class AW_CL_castableType<TYPE> { }
99 #undef INVALID_CB_PARAM_TYPE
104 template<
typename RT,
typename P1 =
void,
typename P2 =
void,
typename P3 =
void>
120 RT
operator()(FP1 p1, FP2 p2, FP3 p3)
const {
return cb(p1, p2, p3); }
139 template<
typename P1,
typename P2>
151 return p1<other.
p1 || (p1 == other.
p1 && (p2< other.
p2 || (p2 == other.
p2 && dealloc<other.
dealloc)));
154 return p1 == other.
p1 && p2 == other.
p2 && dealloc == other.
dealloc;
163 template<
typename RT>
187 template<
typename RT,
typename FIXED>
211 template<
typename RT,
typename F1,
typename F2>
224 cd(new FFV_CallbackData(P, 0))
235 template<
typename RT,
typename F1,
typename F2>
242 enum funtype { ST_P0F12, ST_P0F2, ST_P1 };
248 funtype get_funtype()
const {
return cd->
p2; }
251 Callback_FVF(SigP0F12 CB) : cb(CB.get_cb()), cd(new FVF_CallbackData(0, ST_P0F12)) {}
252 Callback_FVF(SigP0F2 CB) : cb(CB.get_cb()), cd(new FVF_CallbackData(0, ST_P0F2)) {}
256 cd(new FVF_CallbackData(P1, ST_P1,
CASTSIG(typename FVF_CallbackData::CallbackDataDeallocator, dealloc)))
260 funtype ft = get_funtype();
281 #define CASTABLE_TO_AW_CL(TYPE) (sizeof(TYPE) <= sizeof(AW_CL))
282 #define CAST_TO_AW_CL(TYPE,PARAM) AW_CL_castableType<TYPE>::cast_to_AW_CL(PARAM)
284 #define CONST_PARAM_T(T) typename ConstParamT<T>::Type
286 #define CAST_DEALLOCATOR(dealloc) CASTSIG(UntypedCallbackData::CallbackDataDeallocator,dealloc)
294 template<
typename P>
struct ParamIsMutable<
P*
const> {
static constexpr
bool value = !std::is_const<P>::value; };
295 template<
typename ReturnType,
typename... Args>
struct ParamIsMutable<ReturnType(*)(Args...)> {
static constexpr
bool value =
false; };
297 #define CONST_VARIANT_REQUIRED(T) ParamIsMutable<T>::value
298 #define CONST_VARIANTS_REQUIRED(T1,T2) (CONST_VARIANT_REQUIRED(T1) && CONST_VARIANT_REQUIRED(T2))
301 #define RETURN_TYPE_IF(COND,CB) typename std::enable_if<COND,CB>::type
321 #define CBTYPE_VV_BUILDER_P1(BUILDER,CB,RESULT,SIG,P1,P1fun,MAYBE_CB) \
322 template<typename P1> \
324 BUILDER(RESULT (*cb)(P1fun), P1 p1) { \
325 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
326 return CB(CASTSIG(SIG,cb), CAST_TO_AW_CL(P1,p1), 0); \
328 template<typename P1> \
330 BUILDER(RESULT (*cb)(P1fun), void (*dealloc)(P1), P1 p1) { \
331 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
332 return CB(CASTSIG(SIG,cb), CAST_DEALLOCATOR(dealloc), CAST_TO_AW_CL(P1,p1), 0); \
335 #define CBTYPE_VV_BUILDER_P1P2(BUILDER,CB,RESULT,SIG,P1,P2,P1fun,P2fun,MAYBE_CB) \
336 template<typename P1, typename P2> \
338 BUILDER(RESULT (*cb)(P1fun, P2fun), P1 p1, P2 p2) { \
339 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1) && CASTABLE_TO_AW_CL(P2)); \
340 return CB(CASTSIG(SIG,cb), CAST_TO_AW_CL(P1,p1), CAST_TO_AW_CL(P2,p2)); \
342 template<typename P1, typename P2> \
344 BUILDER(RESULT (*cb)(P1fun, P2fun), void (*dealloc)(P1,P2), P1 p1, P2 p2) { \
345 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1) && CASTABLE_TO_AW_CL(P2)); \
346 return CB(CASTSIG(SIG,cb), CAST_DEALLOCATOR(dealloc), CAST_TO_AW_CL(P1,p1), CAST_TO_AW_CL(P2,p2)); \
349 #define CBTYPE_VV_BUILDER_NP12(BUILDER,CB,RESULT,SIG,P1,P2) \
350 CBTYPE_VV_BUILDER_P1(BUILDER,CB,RESULT,SIG,P1,P1,RETURN_TYPE_IF(true,CB)); \
351 CBTYPE_VV_BUILDER_P1(BUILDER,CB,RESULT,SIG,P1,CONST_PARAM_T(P1),RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P1),CB)); \
352 CBTYPE_VV_BUILDER_P1P2(BUILDER,CB,RESULT,SIG,P1,P2,P1,P2,RETURN_TYPE_IF(true,CB)); \
353 CBTYPE_VV_BUILDER_P1P2(BUILDER,CB,RESULT,SIG,P1,P2,P1,CONST_PARAM_T(P2),RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P2),CB)); \
354 CBTYPE_VV_BUILDER_P1P2(BUILDER,CB,RESULT,SIG,P1,P2,CONST_PARAM_T(P1),P2,RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P1),CB)); \
355 CBTYPE_VV_BUILDER_P1P2(BUILDER,CB,RESULT,SIG,P1,P2,CONST_PARAM_T(P1),CONST_PARAM_T(P2),RETURN_TYPE_IF(CONST_VARIANTS_REQUIRED(P1,P2),CB))
357 #define CBTYPE_VV_BUILDER_TEMPLATES(BUILDER,CB,RESULT,SIG) \
358 inline CB BUILDER(RESULT (*cb)()) { \
359 return CB(CASTSIG(SIG,cb), 0, 0); \
361 CBTYPE_VV_BUILDER_NP12(BUILDER,CB,RESULT,SIG,P1,P2)
366 #define CBTYPE_FVV_BUILDER_NP(BUILDER,CB,RESULT,FIXED,SIG) \
367 inline CB BUILDER(RESULT (*cb)(FIXED)) { \
368 return CB((SIG)(void*)cb, 0, 0); \
372 #define CBTYPE_FVV_BUILDER_P1(BUILDER,CB,RESULT,FIXED,SIG,P1,P1fun,MAYBE_CB) \
373 template<typename P1> \
375 BUILDER(RESULT (*cb)(FIXED, P1fun), P1 p1) { \
376 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
377 return CB(CASTSIG(SIG,cb), CAST_TO_AW_CL(P1,p1), 0); \
379 template<typename P1> \
381 BUILDER(RESULT (*cb)(FIXED, P1fun), void (*dealloc)(P1), P1 p1) { \
382 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
383 return CB(CASTSIG(SIG,cb), CAST_DEALLOCATOR(dealloc), CAST_TO_AW_CL(P1,p1), 0); \
386 #define CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,P1fun,P2fun,MAYBE_CB) \
387 template<typename P1, typename P2> \
389 BUILDER(RESULT (*cb)(FIXED, P1fun, P2fun), P1 p1, P2 p2) { \
390 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1) && CASTABLE_TO_AW_CL(P2)); \
391 return CB(CASTSIG(SIG,cb), CAST_TO_AW_CL(P1,p1), CAST_TO_AW_CL(P2,p2)); \
393 template<typename P1, typename P2> \
395 BUILDER(RESULT (*cb)(FIXED, P1fun, P2fun), void (*dealloc)(P1,P2), P1 p1, P2 p2) { \
396 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1) && CASTABLE_TO_AW_CL(P2)); \
397 return CB(CASTSIG(SIG,cb), CAST_DEALLOCATOR(dealloc), CAST_TO_AW_CL(P1,p1), CAST_TO_AW_CL(P2,p2)); \
400 #define CBTYPE_FVV_BUILDER_NP12(BUILDER,CB,RESULT,FIXED,SIG,P1,P2) \
401 CBTYPE_FVV_BUILDER_NP(BUILDER,CB,RESULT,FIXED,SIG); \
402 CBTYPE_FVV_BUILDER_P1(BUILDER,CB,RESULT,FIXED,SIG,P1,P1,RETURN_TYPE_IF(true,CB)); \
403 CBTYPE_FVV_BUILDER_P1(BUILDER,CB,RESULT,FIXED,SIG,P1,CONST_PARAM_T(P1),RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P1),CB)); \
404 CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,P1,P2,RETURN_TYPE_IF(true,CB)); \
405 CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,P1,CONST_PARAM_T(P2),RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P2),CB)); \
406 CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,CONST_PARAM_T(P1),P2,RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P1),CB)); \
407 CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,CONST_PARAM_T(P1),CONST_PARAM_T(P2),RETURN_TYPE_IF(CONST_VARIANTS_REQUIRED(P1,P2),CB))
409 #define CBTYPE_FVV_BUILDER_TEMPLATES(BUILDER,CB,RESULT,FIXED,SIG) \
410 inline CB BUILDER(RESULT (*cb)()) { \
411 return CB(CASTSIG(SIG,cb), 0, 0); \
413 CBTYPE_FVV_BUILDER_NP12(BUILDER,CB,RESULT,FIXED,SIG,P1,P2); \
414 CBTYPE_FVV_BUILDER_NP12(BUILDER,CB,RESULT,UNFIXED,SIG,P1,P2)
419 #define CBTYPE_FFV_BUILDER_P(BUILDER,CB,RESULT,F1,F2,SIG,P,Pfun,MAYBE_CB) \
420 template<typename P> \
422 BUILDER(RESULT (*cb)(F1,F2,Pfun), P p) { \
423 STATIC_ASSERT(CASTABLE_TO_AW_CL(P)); \
424 return CB(CASTSIG(SIG,cb), CAST_TO_AW_CL(P,p)); \
426 template<typename P> \
428 BUILDER(RESULT (*cb)(F1,F2,Pfun), void (*dealloc)(P), P p) { \
429 STATIC_ASSERT(CASTABLE_TO_AW_CL(P)); \
430 return CB(CASTSIG(SIG,cb), CAST_DEALLOCATOR(dealloc), CAST_TO_AW_CL(P,p)); \
433 #define CBTYPE_FFV_BUILDER_TEMPLATES(BUILDER,CB,RESULT,F1,F2,SIG) \
434 inline CB BUILDER(RESULT (*cb)()) { return CB(CASTSIG(SIG,cb), 0); } \
435 inline CB BUILDER(RESULT (*cb)(F1)) { return CB(CASTSIG(SIG,cb), 0); } \
436 inline CB BUILDER(RESULT (*cb)(F1,F2)) { return CB(CASTSIG(SIG,cb), 0); } \
437 CBTYPE_FFV_BUILDER_P(BUILDER,CB,RESULT,F1,F2,SIG,P,P,RETURN_TYPE_IF(true,CB)); \
438 CBTYPE_FFV_BUILDER_P(BUILDER,CB,RESULT,F1,F2,SIG,P,CONST_PARAM_T(P),RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P),CB))
443 #define CBTYPE_FVF_BUILDER_P1_F1F2(BUILDER,CB,RESULT,F1,F2,SIG,P1,P1fun,MAYBE_CB) \
444 template<typename P1> \
446 BUILDER(RESULT (*cb)(F1, P1fun, F2), P1 p1) { \
447 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
448 return CB(CASTSIG(SIG,cb), CAST_TO_AW_CL(P1,p1)); \
450 template<typename P1> \
452 BUILDER(RESULT (*cb)(F1, P1fun, F2), void (*dealloc)(P1), P1 p1) { \
453 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
454 return CB(CASTSIG(SIG,cb), CAST_DEALLOCATOR(dealloc), CAST_TO_AW_CL(P1,p1)); \
457 #define CBTYPE_FVF_BUILDER_P1_F1(BUILDER,CB,RESULT,F1,SIG,P1,P1fun,MAYBE_CB) \
458 template<typename P1> \
460 BUILDER(RESULT (*cb)(F1, P1fun), P1 p1) { \
461 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
462 return CB(CASTSIG(SIG,cb), CAST_TO_AW_CL(P1,p1)); \
464 template<typename P1> \
466 BUILDER(RESULT (*cb)(F1, P1fun), void (*dealloc)(P1), P1 p1) { \
467 STATIC_ASSERT(CASTABLE_TO_AW_CL(P1)); \
468 return CB(CASTSIG(SIG,cb), CAST_DEALLOCATOR(dealloc), CAST_TO_AW_CL(P1,p1)); \
471 #define CBTYPE_FVF_BUILDER_NP1(BUILDER,CB,RESULT,F1,F2,SIG,SIG01,P1) \
472 inline CB BUILDER(RESULT (*cb)(F1)) { return CB(CASTSIG(SIG01,cb)); } \
473 inline CB BUILDER(RESULT (*cb)(F1,F2)) { return CB(CASTSIG(SIG01,cb)); } \
474 CBTYPE_FVF_BUILDER_P1_F1F2(BUILDER,CB,RESULT,F1,F2,SIG,P1,P1,RETURN_TYPE_IF(true,CB)); \
475 CBTYPE_FVF_BUILDER_P1_F1F2(BUILDER,CB,RESULT,F1,F2,SIG,P1,CONST_PARAM_T(P1),RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P1),CB)); \
476 CBTYPE_FVF_BUILDER_P1_F1(BUILDER,CB,RESULT,F1,SIG,P1,P1,RETURN_TYPE_IF(true,CB)); \
477 CBTYPE_FVF_BUILDER_P1_F1(BUILDER,CB,RESULT,F1,SIG,P1,CONST_PARAM_T(P1),RETURN_TYPE_IF(CONST_VARIANT_REQUIRED(P1),CB))
479 #define CBTYPE_FVF_BUILDER_TEMPLATES(BUILDER,CB,RESULT,F1,F2,SIG,SIG01,SIG02) \
480 inline CB BUILDER(RESULT (*cb)()) { return CB((SIG01)cb); } \
481 inline CB BUILDER(RESULT (*cb)(F2)) { return CB((SIG02)cb); } \
482 CBTYPE_FVF_BUILDER_NP1(BUILDER,CB,RESULT,F1,F2,SIG,SIG01,P1); \
483 CBTYPE_FVF_BUILDER_NP1(BUILDER,CB,RESULT,UNFIXED,F2,SIG,SIG01,P1)
488 #define DECLARE_CBTYPE_VV_AND_BUILDERS(CBTYPE,RESULT) \
489 typedef Callback_VV<RESULT> CBTYPE; \
490 CBTYPE_VV_BUILDER_TEMPLATES(make##CBTYPE,CBTYPE,RESULT, \
491 CBTYPE::Signature::FuncType)
493 #define DECLARE_CBTYPE_FVV_AND_BUILDERS(CBTYPE,RESULT,FIXED) \
494 typedef Callback_FVV<RESULT, FIXED> CBTYPE; \
495 CBTYPE_FVV_BUILDER_TEMPLATES(make##CBTYPE,CBTYPE,RESULT,FIXED, \
496 CBTYPE::Signature::FuncType)
498 #define DECLARE_CBTYPE_FFV_AND_BUILDERS(CBTYPE,RESULT,F1,F2) \
499 typedef Callback_FFV<RESULT,F1,F2> CBTYPE; \
500 CBTYPE_FFV_BUILDER_TEMPLATES(make##CBTYPE,CBTYPE,RESULT,F1,F2, \
501 CBTYPE::Signature::FuncType)
503 #define DECLARE_CBTYPE_FVF_AND_BUILDERS(CBTYPE,RESULT,F1,F2) \
504 typedef Callback_FVF<RESULT,F1,F2> CBTYPE; \
505 CBTYPE_FVF_BUILDER_TEMPLATES(make##CBTYPE,CBTYPE,RESULT,F1,F2, \
506 CBTYPE::SigP1::FuncType, \
507 CBTYPE::SigP0F12::FuncType, \
508 CBTYPE::SigP0F2::FuncType)
511 #error cbtypes.h included twice
bool operator==(const Callback_FVV &other) const
bool operator<(const Callback_FFV &other) const
StrictlyTypedCallback< RT, FIXED, AW_CL, AW_CL > Signature
RT operator()(FIXED fixed) const
RT operator()(FP1 p1, FP2 p2, FP3 p3) const
static constexpr bool value
Callback_FVF(SigP0F12 CB)
RT operator()(F1 f1, F2 f2) const
StrictlyTypedCallback(FuncType CB)
StrictlyTypedCallback< RT, F1, F2, AW_CL > Signature
CallbackDataDeallocator dealloc
Callback_FVF(SigP1 CB, UntypedCallbackData::CallbackDataDeallocator dealloc, AW_CL P1)
AW_CL inspect_CD1() const
StrictlyTypedCallback< RT, F2, void, void > SigP0F2
bool operator<(const Callback_FVV &other) const
bool operator<(const Callback_FVF &other) const
AW_CL inspect_CD1() const
bool same_function_as(const Callback_FVF &other) const
CallbackData(P1 p1_, P2 p2_)
StrictlyTypedCallback< RT, AW_CL, AW_CL, AW_CL > Signature
Callback_FVV(Signature CB, UntypedCallbackData::CallbackDataDeallocator dealloc, AW_CL P1, AW_CL P2)
AW_CL inspect_CD2() const
StrictlyTypedCallback< RT, F1, AW_CL, F2 > SigP1
bool operator<(const StrictlyTypedCallback &other) const
RT operator()(F1 f1, F2 f2) const
Function< RT, P1, P2, P3 >::Type FuncType
static AW_CL cast_to_AW_CL(const T &t)
RT operator()(FP1 p1, FP2 p2) const
CallbackData(P1 p1_, P2 p2_, CallbackDataDeallocator dealloc_)
bool operator==(const Callback_FFV &other) const
bool operator<(const CallbackData &other) const
bool same_function_as(const Callback_FVV &other) const
RT operator()(FP1 p1) const
#define INVALID_CB_PARAM_TYPE(TYPE)
CallbackData< AW_CL, AW_CL > UntypedCallbackData
bool operator==(const Callback_VV &other) const
bool operator<(const Callback_VV &other) const
bool equals(const StrictlyTypedCallback &other) const
IfThenElseType< TypeT< T >::IsClassT, typename TypeOp< T >::RefConstT, typename TypeOp< T >::ConstT >::ResultType Type
void(* CallbackDataDeallocator)(P1 p1, P2 p2)
bool operator==(const Callback_FVF &other) const
IfThenElseType< TypeT< T >::IsClassT, typename TypeOp< T >::RefConstT, typename TypeOp< T >::ArgT >::ResultType Type
bool same_function_as(const Callback_VV &other) const
StrictlyTypedCallback< RT, F1, F2, void > SigP0F12
Callback_FVF(SigP1 CB, AW_CL P1)
Callback_FVV(Signature CB, AW_CL P1, AW_CL P2)
Callback_VV(Signature CB, AW_CL P1, AW_CL P2)
bool same_function_as(const Callback_FFV &other) const
Callback_VV(Signature CB, UntypedCallbackData::CallbackDataDeallocator dealloc, AW_CL P1, AW_CL P2)
AW_CL inspect_CD1() const
Callback_FFV(Signature CB, AW_CL P)
AW_CL inspect_CD2() const
static StrictlyTypedCallback make_cb(AW_CL cb_)
TypeOp< T >::ConstT * Type
bool operator==(const StrictlyTypedCallback &other) const
AW_CL inspect_CD2() const
bool operator==(const CallbackData &other) const