Who Wants to Take a Crack at Some Metaprogramming Bullshit?
Who Wants to Take a Crack at Some Metaprogramming Bullshit?
So I've been tinkering with a simple idea of a metafunction that can take a normal binary function like std::less that works with references, and adapt it to work with pointers. A simple implementation here that works for std::unique_ptr (the most common use case for me personally), but the return value is fixed to bool: https://wandbox.org/permlink/JwNdoVcMom26HeGE. I suppose it's not too hard to make that work by adapting the return value to whatever the return value of the base functor is. A little more work might be required to support other pointer types (shared_ptr<T>, T*), probably some template specialization elbow grease I guess. But what really piqued my interest was the ability to make an adaptor that didn't just resolve T* to T&, but one that could resolve T* to T::SomeInstanceFunction() or T::SomeMemberVariable. An implementation of that for pointer-to-data-member is here: https://wandbox.org/permlink/mKxXWkr6R2R1nL1C.
Works pretty well, but the syntax annoys me. What I would like, is I would like Crapdaptor<std::less,&Finkle::y>{}. I feel like this could be possible, perhaps with some usage of auto template parameters (cybo also expressed a similar opinion). So if any brave souls want to venture an attempt into the harsh lands of template BS, I'd be interested in seeing what an implementation of that would look like . Alternatively (or in addition), making the return value of the adaptor operator() reactive or supporting other pointer types might be cool beans.
Works pretty well, but the syntax annoys me. What I would like, is I would like Crapdaptor<std::less,&Finkle::y>{}. I feel like this could be possible, perhaps with some usage of auto template parameters (cybo also expressed a similar opinion). So if any brave souls want to venture an attempt into the harsh lands of template BS, I'd be interested in seeing what an implementation of that would look like . Alternatively (or in addition), making the return value of the adaptor operator() reactive or supporting other pointer types might be cool beans.
Chili
- krautersuppe
- Posts: 91
- Joined: September 14th, 2015, 10:58 pm
- Location: Istanbul
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
*cough* cyber *cough*
DSU
Discord: dsu1, GitHub: https://github.com/DSpUz
Discord: dsu1, GitHub: https://github.com/DSpUz
-
- Posts: 4373
- Joined: February 28th, 2013, 3:23 am
- Location: Oklahoma, United States
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
So let me get some clarification:
Crapdaptor<std::less,&Finkle::y>{}
This is going to be a functor that takes as params a binary function and a pointer to member/member function, and Crapdaptor::operator() is suppose to take any pointer or pointer-like type and forward as reference to the binary functor?
Crapdaptor<std::less,&Finkle::y>{}
This is going to be a functor that takes as params a binary function and a pointer to member/member function, and Crapdaptor::operator() is suppose to take any pointer or pointer-like type and forward as reference to the binary functor?
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
Yeah, that is the idea. Although I suppose you could use SFINAE to make the adaptor support both binary and unary. You can just do normal overloading to support operator() for shared_ptr, unique_ptr, T*.
If the second template param is a data member ptr, forward reference to that member of the object pointed to, if template param is a unary member function ptr, forward reference to the result value of the member function called on the object pointed to, and if the template param is a type, dereference the object pointed to and forward reference to that object.
If the second template param is a data member ptr, forward reference to that member of the object pointed to, if template param is a unary member function ptr, forward reference to the result value of the member function called on the object pointed to, and if the template param is a type, dereference the object pointed to and forward reference to that object.
Chili
-
- Posts: 4373
- Joined: February 28th, 2013, 3:23 am
- Location: Oklahoma, United States
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
The adapter operator() could probably just be a variadic template, though that brings up other complexities.Although I suppose you could use SFINAE to make the adaptor support both binary and unary
As for the choosing what to do with the type the second parameter ( S ) is and what to forward to the comparator in this case, I believe std::invoke is what you want to use.
As to what you want to use for syntax, I'm not sure there is a way around specifying more than a function like object and a pointer to member/member function.
Code: Select all
template<template<typename> class F, class T, class R, R T::*ptr>
struct TestAdapter
{
template<typename...Args>
bool operator()( const std::unique_ptr<T>& pl, Args&&...args ) const
{
return F<R>{}( std::invoke( ptr, pl ), std::invoke( ptr, std::forward<Args>( args )... ) );
}
};
If you are passing pointer or pointer like types, then you wouldn't necessarily need overloads for each type as they each dereference the same way and with invoke it seems to handle pointer types just fine.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com
- cyboryxmen
- Posts: 190
- Joined: November 14th, 2014, 2:03 am
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
For a moment there, I thought you were actually going to give me a challenge.
Code: Select all
template<typename Function>
constexpr auto Crapdaptor = [](auto&& pl, auto&& pr)
{
return Function{}(*pl,*pr);
};
Code: Select all
std::sort(v.begin(),v.end(),Crapdaptor<std::greater<Foo>>);
Zekilk
- cyboryxmen
- Posts: 190
- Joined: November 14th, 2014, 2:03 am
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
Additionally, you can do
Code: Select all
constexpr auto Crapdaptor = [](auto&& function)
{
return [function](auto&& left_ptr, auto&& right_ptr)
{
return function(*left_ptr, *right_ptr);
};
};
Code: Select all
std::sort(v.begin(),v.end(),Crapdaptor(std::mem_fn(&Foo::operator>)));
Zekilk
-
- Posts: 4373
- Joined: February 28th, 2013, 3:23 am
- Location: Oklahoma, United States
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
Can you post some working code in online compiler? I can't seem to get your version to work with his examples.
I think he's trying to avoid declaring/defining operator> and operator< overloads for user defined types.
I think he's trying to avoid declaring/defining operator> and operator< overloads for user defined types.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com
Re: Who Wants to Take a Crack at Some Metaprogramming Bullshit?
Pls don't :peppers:cyboryxmen wrote: ↑December 1st, 2019, 7:16 amAdditionally, you can do
Code: Select all
constexpr auto Crapdaptor = [](auto&& function) { return [function](auto&& left_ptr, auto&& right_ptr) { return function(*left_ptr, *right_ptr); }; };
Code: Select all
std::sort(v.begin(),v.end(),Crapdaptor(std::mem_fn(&Foo::operator>)));
The point wasn't really to avoid defining operators. It's just that we have these nice functions like std::less/std::greater that work with containers of objects, but not containers of pointer types (which is often what you're dealing with). Then as an extension of that concept, I got the idea of using member pointers make the idea even more flexible (e.g. accumulating by std::multiplies across the return value of some member function on a container of pointer types).albinopapa wrote: ↑December 1st, 2019, 7:35 amI think he's trying to avoid declaring/defining operator> and operator< overloads for user defined types.
Chili