pfr icon indicating copy to clipboard operation
pfr copied to clipboard

Member pointers functionality

Open denzor200 opened this issue 4 years ago • 10 comments

Hello Anton. I have some idea and i want to suggest it for you. This patch will add pretty useful functionality for extracting member pointer of some structure. For example:

struct Foo
{
	char ch;
	short id;
	short opt;
	int value;
};

auto ch_memptr = boost::pfr::get_memptr<0>(Foo{});
auto id_memptr = boost::pfr::get_memptr<1>(Foo{});
auto opt_memptr = boost::pfr::get_memptr<2>(Foo{});
auto value_memptr = boost::pfr::get_memptr<3>(Foo{});

auto obj = Foo{};

obj.*ch_memptr = 'c';
obj.*id_memptr = 100;
obj.*opt_memptr = 200;
obj.*value_memptr = 3000;

std::cout << obj.ch << " " << obj.id << " " << obj.opt << " " << obj.value << std::endl; ///< will print "c 100 200 3000"

Its just a draft - not a final code. If you are interested - i will continue for it.

denzor200 avatar Apr 25 '21 20:04 denzor200

This may help to resolve this issue: https://github.com/boostorg/pfr/issues/62 BUT i unfortunately do not know how to make get_memptr constexpr((

denzor200 avatar Apr 25 '21 20:04 denzor200

Good idea!

I''ve simplified it a little bit https://godbolt.org/z/e8rKWrrEs

In my implementation problems are the same:

  • pointer arithmetic is not a constant expression (bit_cast refuses to convert pointers to integers)
  • Something must be done with the default constructor

apolukhin avatar May 06 '21 16:05 apolukhin

Something must be done with the default constructor

  1. template<typename T> struct declval_helper { static T value; }; But it not for clang and msvc https://godbolt.org/z/nYz6M61YT
  2. What if we pass a NULL reference into boost::pfr::get? This is works good, but i cant anticipate the consequences

denzor200 avatar Jun 17 '21 18:06 denzor200

Something must be done with the default constructor

  1. Why don't we use the already checked offset_based_getter? In my opinion it solves this problem good. https://godbolt.org/z/hfxbnvqrE This works on MSVC too

denzor200 avatar Jun 19 '21 12:06 denzor200

I tried to construct constexpr member pointer getter:

GCC and msvc are promising: https://godbolt.org/z/hPa9718aY https://godbolt.org/z/Th8KTKxns

Caveats:

  • msvc static assert: same member pointer at runtime, but not recognized as equal at compile time.
  • only for not final classes
  • clang not works with this technique

schaumb avatar Feb 23 '22 21:02 schaumb

@schaumb interesting. Unfortunatelly, refl cannot be passed as template parameter, only orig can.

denzor200 avatar Feb 23 '22 22:02 denzor200

@denzor200

I created a gcc ticket, because it is a compiler bug (probably?).

msvc constexpr member pointers can be used as template parameter. But:

template<auto> struct X {};
static_assert(std::is_same_v<X<refl>, X<orig>>);  // ERROR


template <auto V> decltype(V) wash() { return V; };
static_assert(&wash<refl> == &wash<orig>);  // OK
static_assert(wash<refl>() == wash<orig>()); // OK
// compiler save first call function instance template argument (currently the refl), so:
static_assert(wash<refl>() == refl); // OK
static_assert(wash<orig>() == orig); // ERROR

Not equality problem occures only if the original member pointer is used. But wash can be used as equality checker.

schaumb avatar Feb 24 '22 17:02 schaumb

@schaumb I created clang ticket here: https://github.com/llvm/llvm-project/issues/56541

Let's see where the answer will be faster :)

denzor200 avatar Jul 15 '22 17:07 denzor200