On Saturday, 28 May 2016 at 08:10:50 UTC, Era Scarecrow wrote:
On Friday, 27 May 2016 at 09:22:49 UTC, Guillaume Piolat wrote:
You have to write your code three times, one for

version(D_InlineAsm_X86)
version (D_InlineAsm_X86_64)
and a version without assembly.

Rather than make a new thread I wonder if struct inheritance wouldn't solve this, as trying to manage specific versions, lack of versions, checks for CTFE all became a headache. and bloated a 4 line function (2 of which were the opening/declaration) to something like 20 lines and looks like a huge mess.

 So...

 Let's assume structs as they are don't (otherwise) change.
 Let's assume structs can be inherited.
Let's assume inherited structs change _behavior_ only (overridden functions as final), but don't add/expand any new data (non-polymorphic, no vtables).

 Then I could do something like this!

  //contains plain portable version
  struct base {}

  version(X86) {
    struct inherited : base {
      //only adds or replaces functions, no data changes
      //all asm injection is known to be 32bit x86
    }
  }
  version(X86_64) {
    ...
  }

Truthfully going with my example, only a couple functions would be considered, namely multiply and divide as they would be the slowest ones, while everything else has very little to improve on, at least based on how wideint.d was implemented.

The great thing about D's UFCS is that it allows exactly that:

void main()
{
    WideInt myInt;
    myInt.inc(); // looks like a member function
    myInt++; // can be hidden behind operator overloading
}

struct WideInt
{
    ulong[2] data;

    int opUnary(string s)()
    {
        static if (s == "++")
            this.inc();
    }
}

version(D_InlineAsm_X86_64)
{
void inc(ref WideInt w) { /* 32-bit increment implementation */ }
}
else version(D_InlineAsm_X86)
{
void inc(ref WideInt w) { /* 64-bit increment implementation */ }
}
else
{
void inc(ref WideInt w) { /* generic increment implementation */ }
}

Also, you can implement inc() in terms of ulong[2] - void inc(ref ulong[2] w), which makes it applicable for other types, with the same memory representation. E.g. cent - (cast(ulong[2]*)&cent).inc(), arrays - ulong[] arr; arr[0..2].inc(), and so on.


Reply via email to