repr
0.1
Reconstructable string representations and more
Toggle main menu visibility
Main Page
Installation
Usage
Customization
Extending
FAQ
CI Results
Test
Benchmark
API Documentation
Namespace List
Namespace List
Namespace Members
All
_
a
c
d
e
f
g
i
l
m
n
o
p
r
s
t
u
v
w
Functions
_
a
c
d
e
f
g
i
l
m
n
o
r
s
t
u
v
w
Variables
Typedefs
Enumerations
Concept List
Class List
Class List
Class Index
Class Hierarchy
Class Members
All
_
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
~
Functions
_
a
c
e
f
g
i
l
m
n
o
p
r
s
t
v
w
~
Variables
a
b
c
d
e
f
g
i
k
l
m
n
o
p
q
r
s
t
u
v
Typedefs
a
c
d
e
f
g
h
l
m
p
r
s
t
u
v
w
Enumerations
Enumerator
Related Symbols
File List
File List
File Members
All
_
l
n
o
r
u
Variables
Macros
_
l
o
r
u
Examples
Source Code
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
Concepts
Loading...
Searching...
No Matches
member.h
Go to the documentation of this file.
#pragma once
#include <
memory
>
#include <
string_view
>
#include <
utility
>
#include <
array
>
#include <
librepr/macro/warning.h
>
#include <
librepr/customization/reflection.h
>
#include <
librepr/ctvi/ctvi.h
>
#include <
librepr/customization/members.h
>
#include <
librepr/util/util.h
>
#include <
librepr/util/string/const_string.h
>
#include <
librepr/reflection/detail/arity.h
>
#include <
librepr/reflection/detail/to_tuple.h
>
#include <
librepr/macro/platform.h
>
namespace
librepr
{
namespace
detail {
#if USING(LIBREPR_COMPILER_CLANG)
// clang-format off
#define LIBREPR_SUBOBJECT_PTR(...) ::librepr::Wrap{__VA_ARGS__}
// clang-format on
#else
#define LIBREPR_SUBOBJECT_PTR(...) __VA_ARGS__
#endif
template
<auto>
struct
MemberName
;
template
<
typename
C,
typename
T, T C::*ptr>
struct
MemberName
<ptr> {
using
type
=
C
;
constexpr
static
auto
value =
#if USING(LIBREPR_COMPILER_MSVC)
// MSVC unfortunately returns pointer to member template arguments into offsets
// like `pointer-to-member(0x0)`. Using the aggregate member name reflection trick yields
// `&fake_obj<struct Test>->value->member` instead, which is usable here.
librepr::ctvi::detail::name_from_subobject
<
C
,
std::addressof
(
fake_obj<C>
.value.*ptr)>();
#else
librepr::ctvi::detail::name_from_member_ptr<ptr>();
#endif
};
struct
MemberName
<ptr> {
…
};
template
<Member info>
struct
MemberName
<
info
> {
using
type
=
typename
decltype
(
info
)::class_type;
constexpr
static
auto
member_name
() {
if
constexpr
(!
info
.name.empty()) {
return
info
.name;
}
else
if
constexpr
(!
std::is_member_function_pointer_v
<
decltype
(
info
.value.value)> &&
!
std::is_function_v
<
std::remove_pointer_t
<
decltype
(
info
.value.value)>>) {
// don't extract names of accessor functions - those will probably be incorrect
return
MemberName
<
info
.value.value>{}.value;
}
else
{
return
const_string<0>
{};
}
}
constexpr
static
auto
member_name
() {
…
}
constexpr
static
auto
value =
member_name
();
};
struct
MemberName
<
info
> {
…
};
LIBREPR_WARNING_PUSH
LIBREPR_WARNING_DISABLE
(
CLANG
,
"-Wundefined-var-template"
)
// This technique has been described by @schaumb
// For explanations see
// https://github.com/boostorg/pfr/issues/150#issuecomment-1831500004
// https://github.com/boostorg/pfr/issues/90#issuecomment-1589530490
template
<
typename
T,
std
::
size_t
Idx
>
requires
(
std
::is_aggregate_v<T> && !
std
::is_array_v<T>)
inline
constexpr
auto
raw_member_name
=
librepr
::ctvi::detail::name_from_subobject<T,
LIBREPR_SUBOBJECT_PTR
(
get
<
Idx
>(
to_addr_tuple
(
fake_obj
<T>.value)))>();
LIBREPR_WARNING_POP
template
<
typename
T>
requires
(
std
::is_aggregate_v<T> && !
std
::is_array_v<T>)
inline
constexpr
auto
raw_member_names
= []<
std
::
size_t
...
Idx
>(
std
::index_sequence<
Idx
...>) {
return
std::array
{
std::string_view
{
raw_member_name<T, Idx>
}...};
}(
std::make_index_sequence<arity<T>
>{});
inline
constexpr
auto
raw_member_names
= []<
std
::
size_t
...
Idx
>(
std
::index_sequence<
Idx
...>) {
…
};
template
<auto Accessor>
constexpr
inline
auto
custom_member_name
=
MemberName<Accessor>::value
;
template
<
typename
T>
constexpr
auto
get_member_names
() {
// TODO
using
error
=
std::array<std::string_view, 0>
;
if
constexpr
(
has_custom_members<T>
) {
if
constexpr
(
Settings<T>::members
!= 0) {
return
Settings<T>::members::invoke
(
[]<
Member
... members>() { return std::array{std::string_view{custom_member_name<members>}...}; });
}
else
{
return
error
{};
}
}
else
if
constexpr
(std::is_aggregate_v<T> && !std::is_array_v<T>) {
constexpr
auto
member_count =
arity<T>
;
if
constexpr
(member_count != 0 &&
requires
{
raw_member_name<T, 0>
; }) {
return
[]<
std::size_t
...
Idx
>(
std::index_sequence
<
Idx
...>) {
return
std::array
{
std::string_view
{
raw_member_name<T, Idx>
}...};
}(
std::make_index_sequence<member_count>
{});
}
else
{
return
error
{};
}
}
else
{
return
error
{};
}
}
constexpr
auto
get_member_names
() {
…
}
}
// namespace detail
template
<
typename
T>
constexpr
inline
auto
member_names
= detail::get_member_names<T>();
template
<
typename
T, std::
size_t
Idx>
requires
(Idx <= member_names<T>.size())
constexpr
inline
auto
member_name = member_names<T>[Idx];
}
// namespace librepr
include
librepr
name
member.h
Generated by
1.9.8, using the excellent
Doxygen Awesome
Theme