Macros which declare templates for testing named members of types. More...
Go to the source code of this file.
Classes | |
| struct | ugmisc::call_foo_method< T > |
Macros | |
| #define | UGMISC_NAMED_MEMBER_TYPE_TEST(TEMPLATENAME, ALIASNAME, HASMEMBERNAME, NAME) |
| #define | UGMISC_MEMBER_TYPE_TEST(NAME) |
| #define | UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL(TEMPLATENAME, NAME) |
| #define | UGMISC_MEMBER_STATIC_METHOD_CALL(NAME) |
Macros which declare templates for testing named members of types.
The macros allow templates to be created which can check for the existence of a named member type of any of a list of types, and templates which can check for the existence of a named static method of any of a list of types, and forward arguments to it.
Default types or callables may be provided when using the declared templates.
| #define UGMISC_MEMBER_STATIC_METHOD_CALL | ( | NAME | ) |
Equivalent to UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL(member_call_NAME, NAME).
See the description of UGMISC_MEMBER_TYPE_TEST(NAME) for the pitfalls of using this.
| #define UGMISC_MEMBER_TYPE_TEST | ( | NAME | ) |
This is equivalent to calling UGMISC_NAMED_MEMBER_TYPE_TEST(member_type_test_NAME, member_type_NAME, has_member_type_NAME, NAME).
The downside to this compared to directly using UGMISC_NAMED_MEMBER_TYPE_TEST, is that it is not obvious, without looking up the macro's definition or documentation, what declarations it makes. I personally would use this where a few macro calls were wanted in one place, and include a comment explaining the effect.
For example:
This way the following use of one of those declarations won't require a hunt through the entire project to find where they came from by your successor after you're dead. Or by you next week.
| #define UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL | ( | TEMPLATENAME, | |
| NAME ) |
Declares a template.
The template can be instantiated with a list of types. Then its static 'call' method, or the non-static operator() overload, can be called with any arguments, and will be forwarded to Type::NAME for the first type which accepts such a call.
For example:
Continuing the above example:
If none of X, Y, and Z has a static method called "foo", the provided callable will be used instead. If forwarding args... to the callable is valid, that will be done. Otherwise the callable will be called without arguments.
| #define UGMISC_NAMED_MEMBER_TYPE_TEST | ( | TEMPLATENAME, | |
| ALIASNAME, | |||
| HASMEMBERNAME, | |||
| NAME ) |
Creates a type like this:
Which has members:
Also creates the alias:
and the template variable:
T can be a ugmisc::type_list, which will check each type in order until if finds one with the named type member.
To pass a type which is actually be a ugmisc::type_list without giving it special treatment, wrap it in a ugmisc::wrapped_list. e.g.