C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Expose architecture at compile-time (and more at runtime)

From: Jarrad Waterloo <descender76_at_[hidden]>
Date: Thu, 27 Oct 2022 11:25:53 -0400
We have to do something similar in the function_ref proposal even though
the function is already there but we can't access it. Compilers should just
give us access instead of having to do grotesque and inefficient work
arounds creating binders pseudo-manually. We had this ability in "cfront"
because when there was a C analog for everything in C++ but this
functionality was never standardized.


On Thu, Oct 27, 2022 at 11:00 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> On Thu, Oct 27, 2022 at 1:45 PM Jarrad Waterloo <descender76_at_[hidden]>
> wrote:
> >
> > Your second reason is captured in the following. Please give it a look,
> your comments and your support.
> >
> > https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2603r1.html
>
>
> If I understand your proposal correctly, then I've implemented it as
> follows. The following code works properly with clang++ and g++ if you
> do "-std=c++20".
>
> #include <cstring> // memcpy
> #include <type_traits> // is_same_v - just for debugging
> #include <typeinfo> // type_info
> #include <iostream> // iostream
> #include <ios> // dec, hex
>
> /* =================== First let's have some sample classes */
> using std::cout;
> using std::endl;
>
> struct NumberPrinter {
> long unsigned i = 0u;
> virtual void Print(void) { cout << "Base class!" << endl; }
> };
>
> struct DecimalNumberPrinter : NumberPrinter {
> void Print(void) { cout << std::dec << i++ << endl; }
> };
>
> struct HexadecimalNumberPrinter : NumberPrinter {
> void Print(void) { cout << "0x" << std::hex << i++ << endl; }
> };
>
> /* =================== Now let's have the code for MemFuncPtr */
>
> template<class Retval, class... Args>
> class MemFuncPtrBase {
> public:
> std::type_info const &ti;
>
> protected:
> Retval (*const p)(void*,Args...);
> MemFuncPtrBase( std::type_info const &arg_ti, Retval
> (*arg_p)(void*,Args...) ) : ti(arg_ti), p(arg_p) {}
>
> public:
>
> /* =================================================
> Beginning of class within a class */
> class Invoker final {
> void *const p_obj;
> Retval (*const p)(void*, Args...);
> public:
> Invoker(void *const arg_p_obj, Retval (*const arg_p)(void*,
> Args...))
> : p_obj(arg_p_obj), p(arg_p) {}
>
> Retval operator()(Args... args)
> {
> return p(p_obj,args...);
> }
> };
> /* End of class within a class
> ================================================= */
>
> Invoker operator()(void *const arg_p)
> {
> return Invoker(arg_p, this->p);
> }
> };
>
> template<class Retval, class T, class... Args>
> class MemFuncPtrT final : public MemFuncPtrBase< Retval, Args... > {
> protected:
>
> static Retval (*Address_Of_Member_Function( Retval (T:: *const
> mp)(Args...) ))(void*, Args...)
> {
> static T obj; // Let's hope it has a default constructor
>
> std::uintptr_t n;
> std::memcpy(&n, &mp, sizeof n);
>
> Retval (*const *const v_table)(void*,Args...) =
>
> *static_cast<Retval(*const**)(void*,Args...)>(static_cast<void*>(&obj));
>
> return v_table[n >> 3u]; // This works on 'g++' and 'clang++'
> }
>
> public:
>
> typedef MemFuncPtrBase< Retval, Args... > Base;
>
> MemFuncPtrT( Retval (T:: *const arg)(Args...) )
> : Base( typeid(T), Address_Of_Member_Function(arg) ) {}
>
> Base &base(void) { return *this; }
> };
>
> int main(int const argc, char **const argv)
> {
> MemFuncPtrT mfp1( &NumberPrinter::Print );
> MemFuncPtrT mfp2( &HexadecimalNumberPrinter::Print );
>
> static_assert( std::is_same_v< decltype(mfp1)::Base,
> decltype(mfp2)::Base >,
> "These two types should be the same");
>
> using MemFuncPtr = decltype(mfp1)::Base;
>
> // On the next line, we decide at runtime which method to call
> MemFuncPtr mfp( (argc % 2) ? mfp1.base() : mfp2.base() );
>
> HexadecimalNumberPrinter obj;
>
> mfp(&obj)();
>
> cout << mfp.ti.name() << endl;
> }
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2022-10-27 15:26:06