A traits class that is used to check if a class implements a method with a given signature was already used by the eventhandler signature check. It has now been moved to its own traits header (macro name is DEFINE_HAS_METHOD_TRAITS). Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>pull/617/head
parent
8fe381a0a2
commit
af1c2ba659
@ -0,0 +1,73 @@
|
||||
/* Kaleidoscope - Firmware for computer input devices
|
||||
* Copyright (C) 2013-2018 Keyboard.io, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kaleidoscope/macro_helpers.h"
|
||||
|
||||
#define DEFINE_HAS_METHOD_TRAITS(PREFIX, METHOD_NAME, \
|
||||
RETURN_TYPE, ARGUMENTS) \
|
||||
__NL__ \
|
||||
/* This traits checks if a class of type Class__ __NL__ \
|
||||
* implements a method with given signature. __NL__ \
|
||||
*/ __NL__ \
|
||||
template<typename Class__> __NL__ \
|
||||
struct PREFIX##_HasMethod_##METHOD_NAME __NL__ \
|
||||
{ __NL__ \
|
||||
/* Define a pointer to member function with the correct __NL__ \
|
||||
* argument signature. The newly defined type is named __NL__ \
|
||||
* MethodType__. __NL__ \
|
||||
*/ __NL__ \
|
||||
typedef RETURN_TYPE (Class__::*MethodType__)ARGUMENTS; __NL__ \
|
||||
__NL__ \
|
||||
/* This is an application of the SFINAE concept. __NL__ \
|
||||
* We check if Class__ defines a method with given name and __NL__ \
|
||||
* signature. This is done by forcing the compiler __NL__ \
|
||||
* through a static cast to select the respective method __NL__ \
|
||||
* if possible. If the method signature cannot be found, __NL__ \
|
||||
* the substitution fails and the first version of method "test" __NL__ \
|
||||
* will not be defined. __NL__ \
|
||||
*/ __NL__ \
|
||||
template <typename ClassAux__> __NL__ \
|
||||
static constexpr __NL__ \
|
||||
/* The following decltype-clause defines the function return type __NL__ \
|
||||
*/ __NL__ \
|
||||
decltype( __NL__ \
|
||||
/* If &ClassAux__::METHOD_NAME exists and is of type __NL__ \
|
||||
* MethodType__, the list below evaluates to bool{} whose __NL__ \
|
||||
* type can be determined. Otherwise the comma expression __NL__ \
|
||||
* cannot be evaluated and the content __NL__ \
|
||||
* of decltype is undefined and this function overload __NL__ \
|
||||
* is ignored by the compiler __NL__ \
|
||||
* (SFINAE = substitution failure is not an error) __NL__ \
|
||||
* and the test(...) overload is used instead. __NL__ \
|
||||
*/ __NL__ \
|
||||
static_cast<MethodType__>(&ClassAux__::METHOD_NAME), bool{} __NL__ \
|
||||
) __NL__ \
|
||||
test(int /* unused */) __NL__ \
|
||||
{ __NL__ \
|
||||
return true; __NL__ \
|
||||
} __NL__ \
|
||||
__NL__ \
|
||||
template <typename ClassAux__> __NL__ \
|
||||
static constexpr bool test(...) __NL__ \
|
||||
{ __NL__ \
|
||||
return false; __NL__ \
|
||||
} __NL__ \
|
||||
__NL__ \
|
||||
static constexpr bool value = test<Class__>(int{}); __NL__ \
|
||||
};
|
||||
|
Loading…
Reference in new issue