Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use 'ref' at compile time?

Tags:

d

struct Matrix(int row, int col){ /* ... */ }

// finds the inverse using Gauss–Jordan elimination
pure M inverse(M)(const ref M m){ /* ... */ }

The reason m is a ref is because of performance. Obviously, I don't want large matrices being copied around every time the inverse is needed, and this has worked fine so far.

But, it has become a problem in situations where the inverse is needed at compile time:

mixin template A(){

  alias Matrix!(3, 3) Matrix3x3;

  static Matrix3x3 computeSomeMatrix(){ }

  immutable Matrix3x3 _m = computeSomeMatrix();
  immutable Matrix3x3 _m_1 = inverse(computeSomeMatrix());  // error
}

To fix the error, I need to change m to a non-ref, but that means that matrices will be copied every time inverse() is called. What do I do?

like image 933
Arlen Avatar asked Oct 08 '22 20:10

Arlen


1 Answers

I see one of two options. One, create a version which takes an rvalue. It's frequently annoying when a function doesn't work with rvalues anyway. A simple wrapper is all you need:

pure M inverse(M)(const ref M m){ /* ... */ }
pure M inverse(M)(const M m){ inverse(m); }

Be careful that the const-ness of the parameters matches though, or you're going to get infinite recursion.

However, a better solution would be to use auto ref. This is what it was created for.

pure M inverse(M)(const auto ref M m){ /* ... */ }

The compiler will then use ref when appropriate and non-ref when appropriate without you having to worry about it.

like image 163
Jonathan M Davis Avatar answered Oct 16 '22 11:10

Jonathan M Davis