views:

176

answers:

2

I have the following record definition

  E3Vector3T = packed record
  public
      x: E3FloatT;
      y: E3FloatT;
      z: E3FloatT;

      function length: E3FloatT;
      function normalize: E3Vector3T;
      function crossProduct( const aVector: E3Vector3T ): E3Vector3T;

      class operator add( const aVector1, aVector2: E3Vector3T ): E3Vector3T;
      class operator subtract( const aVector1, aVector2: E3Vector3T ): E3Vector3T;
      class operator negative( const aVector: E3Vector3T ): E3Vector3T;
      class operator multiply( const aVector: E3Vector3T; const aScalar: E3FloatT ): E3Vector3T;
      class operator divide( const aVector: E3Vector3T; const aScalar: E3FloatT ): E3Vector3T;
  end;

What I wanted to do is introduce a variant record part to be able to access the three elements both individually and as an array, i.e.

  E3Vector3T = packed record
  public
      case boolean of
          true: (
              x: E3FloatT;
              y: E3FloatT;
              z: E3FloatT;
          );
          false: (
              elements: packed array[0..2] of E3FloatT;
          );

      function length: E3FloatT;
      ..
  end;

This will not compile (function needs a result type at function length). Anything obvious I'm doing wrong, or is this not supported? In that case, any suggestions for an elegant yet performant way of accessing the individual fields as an array?

p.s. E3FloatT is a simple type alias for Single.

+6  A: 

Move the function declaration to the top like this:

  E3Vector3T = packed record
  public
      function length: E3FloatT;
      case boolean of
          true: (
              x: E3FloatT;
              y: E3FloatT;
              z: E3FloatT;
          );
          false: (
              elements: packed array[0..2] of E3FloatT;
          );

  end;

This compiles in Delphi 2010.

Ville Krumlinde
+8  A: 

Maybe it is an oversight in the compiler, but it does compile when the methods are declared before the variant part. This seems a reasonable solution.

E3Vector3T = packed record
  public
      function length: E3FloatT;
      ..

      case boolean of
          true: (
              x: E3FloatT;
              y: E3FloatT;
              z: E3FloatT;
          );
          false: (
              elements: packed array[0..2] of E3FloatT;
          );
  end;
Lars Truijens
It's not an oversight. Just like it has always been, the variant portion of a variant record *must* always be declared last.
Allen Bauer
Since the Wirth Pascal days ...
gabr
@Allen: ... of course, thanks! I always thought that particular rule was there to make data access more straight-forward, it never occured to me it existed for grammatical reasons. :D
Paul-Jan