ugmisc 0.2-76
Miscellaneous C++ header library
Loading...
Searching...
No Matches
member.hpp File Reference

Testing for and using named static and non static members of types. More...

#include "ugmisc/typelist.hpp"
#include <utility>

Go to the source code of this file.

Classes

struct  ugmisc::default_type< T >
struct  static_member_caller< Access, T >
struct  member_caller< Access >
struct  member_value< Access, CopyValue >
struct  member_type_access< Access, T >
struct  static_member_value< Access, T >

Macros

#define UGMISC_DECL_MEMBER_ACCESS(TNAME, NAME)
#define UGMISC_DECL_STATIC_MEMBER_CALLER(TNAME, NAME)
#define UGMISC_DECL_MEMBER_TYPE_ALIAS(TNAME, NAME)
#define UGMISC_DECL_STATIC_MEMBER_ACCESSOR(TNAME, NAME)
#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)

Enumerations

enum  member_value_copy { MEMBER_COPY_AUTO , MEMBER_COPY_NEVER , MEMBER_COPY_ALWAYS }

Detailed Description

Testing for and using named static and non static members of types.

Why

The utilities provided by this header will be obsoleted by C++26's reflection support. But if that support is not available or can't be assumed, this is a clumsy, horrible substitute.

What it Does

There are 4 things you can do:

  • Find a named static member function of a type among a list of types, which accepts certain parameters, and optionally call it with those parameters.
  • Find a named member type of a type among a list of types.
  • Find a named static member value of a type among a list of types.
  • Find a named member function of an object among a list of objects, which accepts certain parameters, and call it with those parameters.
  • Find a named non static member reference among a sequence of objects.

Usage

Everything you might want to do with member.hpp has two parts. First there is the macro UGMISC_DECL_MEMBER_ACCESS, which defines a type. This type can be declared at namespace or class scope. The type declared using the UGMISC_DECL_MEMBER_ACCESS macro is responsible for knowing the name of the class member you want to use.

Then there is a template in the ugmisc namespace, which takes that class as its first parameter.

Call a named static method

Use the template static_member_caller.

For example:

UGMISC_DECL_MEMBER_ACCESS(FooCall, foo); // Defines FooCall class.
using Caller = ugmisc::static_member_caller<FooCall, X, Y>;
#define UGMISC_DECL_MEMBER_ACCESS(TNAME, NAME)
Definition member.hpp:165

See static_member_caller for a full explanation, including how to fallback to a default value, or find out if the call would be valid without actually making it.

Find a named member type

Note
Finding a member type is broken in versions 0.1 and 0.2. See commit f2246e89efa45f0f7a24f903e434cac9d086ab1a.

Use the template member_type_access.

For example, to find the first of X::foo and Y::foo which is a valid type expression:

UGMISC_DECL_MEMBER_ACCESS(FooType, foo); // Declare FooType.
using TypeFinder = ugmisc::member_type_access<FooType, X, Y>;
using Type = typename TypeFinder::type;

See member_type_access for full instructions, including how to include a default type, and how to test if the type exists at all.

Obtain a static member reference

Use the template static_member_value.

For example, to find a reference to the first of X::foo and Y::foo which is an accessible static member:

UGMISC_DECL_MEMBER_ACCESS(FooGet, foo); // Declares FooGet.
using Getter = ugmisc::static_member_value<FooGet, X, Y>;
auto& foo = Getter::get();

See static_member_value for full instructions, including how to provide a default fallback value.

Call a non static method

Use the template member_caller.

For example, to find the first of x.foo(1) and y.foo(1) which is valid and obtain the return value:

UGMISC_DECL_MEMBER_ACCESS(fooGet, foo); // Declares fooGet.
auto foo_retval = ugmisc::member_caller<fooGet>{}(x, y)(1);

See member_caller for full instructions, including how to provide a default fallback value.

Obtain a non static member reference

Use the template member_value.

For example, to find the first of x.foo and y.foo which is valid and obtain a reference:

UGMISC_DECL_MEMBER_ACCESS(fooGet, foo); // Declares fooGet.
auto foo_value = ugmisc::member_value<fooGet>{}(x, y).get();

See member_value for full instructions, including how to provide a default fallback, and notes about how to keep everything constexpr.

Macro Definition Documentation

◆ UGMISC_DECL_MEMBER_ACCESS

#define UGMISC_DECL_MEMBER_ACCESS ( TNAME,
NAME )

Declares a type which can be used for named member access of types and objects. Can be passed to the template classes and functions which find member types and references static and non-member objects, and forward arguments to static and non static methods.

TNAME is the name the declared type will have.

NAME is the member name it will access.

◆ UGMISC_DECL_MEMBER_TYPE_ALIAS

#define UGMISC_DECL_MEMBER_TYPE_ALIAS ( TNAME,
NAME )

◆ UGMISC_DECL_STATIC_MEMBER_ACCESSOR

#define UGMISC_DECL_STATIC_MEMBER_ACCESSOR ( TNAME,
NAME )

◆ UGMISC_DECL_STATIC_MEMBER_CALLER

#define UGMISC_DECL_STATIC_MEMBER_CALLER ( TNAME,
NAME )

◆ UGMISC_MEMBER_STATIC_METHOD_CALL

#define UGMISC_MEMBER_STATIC_METHOD_CALL ( NAME)
Value:
UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL(member_call_##NAME, NAME)
#define UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL(TEMPLATENAME, NAME)
Definition member.hpp:1622
Deprecated
See also
static_member_caller

◆ UGMISC_MEMBER_TYPE_TEST

#define UGMISC_MEMBER_TYPE_TEST ( NAME)
Value:
UGMISC_NAMED_MEMBER_TYPE_TEST(member_type_test_##NAME, member_type_##NAME, has_member_type_##NAME, NAME)
#define UGMISC_NAMED_MEMBER_TYPE_TEST(TEMPLATENAME, ALIASNAME, HASMEMBERNAME, NAME)
Definition member.hpp:462
Deprecated
See also
member_type_access

◆ UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL

#define UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL ( TEMPLATENAME,
NAME )
Value:
UGMISC__DECL_MEMBER_CALLER_TYPE(TEMPLATENAME, NAME); \
template<class...T> class TEMPLATENAME \
: public ::ugmisc::static_member_caller< \
UGMISC__MEMBER_CALLER_TYPE_NAME(TEMPLATENAME), \
T... \
> \
{ \
static constexpr const char *template_name = #TEMPLATENAME; \
static constexpr const char *function_name = #NAME; \
}

Non static member access. ::ugmisc

Deprecated
See also
static_member_caller

◆ UGMISC_NAMED_MEMBER_TYPE_TEST

#define UGMISC_NAMED_MEMBER_TYPE_TEST ( TEMPLATENAME,
ALIASNAME,
HASMEMBERNAME,
NAME )
Value:
UGMISC__DECL_MEMBER_TYPEDEF_TYPE(TEMPLATENAME, NAME); \
\
template<class T, class D = void> struct TEMPLATENAME : \
public ::ugmisc::member_type_access<UGMISC__MEMBER_TYPEDEF_TYPE_NAME(TEMPLATENAME), T, ::ugmisc::default_type<D>> \
{ \
}; \
\
template<class T, class D = void> using ALIASNAME = \
typename TEMPLATENAME<T, D>::type; \
template<class...T> static constexpr bool HASMEMBERNAME = \
TEMPLATENAME<::ugmisc::type_list<T...>>::has_member
Encapsulates a list of types.
Definition typelist.hpp:810
Deprecated
See also
member_type_access

Enumeration Type Documentation

◆ member_value_copy

See also
member_value
Enumerator
MEMBER_COPY_AUTO 

Default. Copy value if safe and trivial to do so.

MEMBER_COPY_NEVER 

Always take a reference to the original object.

MEMBER_COPY_ALWAYS 

Always copy the value.