Re: Define methods using templates

2015-01-08 Thread Claude via Digitalmars-d-learn
I just saw this post, which is essentially the same question as 
Basile Burg's. I hope that a college (in France?) is teaching D 
and that this is a homework assignment. Cool stuff! :)


Maybe using templates to create properties is a bit overkill in 
this example. But I could not solve what I thought would be a 
very simple and straightforward template use-case (initially 
I'm an embedded RT system C/asm developer).


I'm doing this for a personal project of a 3D engine. As I know 
little about C++/Java or other OO language, I thought I would do 
it directly in D, which seems very promising to me (but 
unfortunately not taught in France as far as I know).


Re: Define methods using templates

2014-12-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/30/14 8:17 AM, Claude wrote:

Hello, I'm trying to use templates to define several methods (property
setters) within a class to avoid some code duplication.
Here is an attempt:

class Camera
{
private:
 Vector4 m_pos;
 float m_fov, m_ratio, m_near, m_far;
 bool m_matrixCalculated;

public:
 void SetProperty(Tin, alias Field)(ref Tin param) @property pure @safe
 {
 Field = param;
 m_matrixCalculated = false;
 }

 alias pos   = SetProperty!(float[], m_pos);
 alias pos   = SetProperty!(Vector4, m_pos);
 alias ratio = SetProperty!(float,   m_ratio);
 alias near  = SetProperty!(float,   m_near);
 alias far   = SetProperty!(float,   m_far);
}

I get this kind of compilation error:
Error: template instance SetProperty!(float[], m_pos) cannot use local
'm_pos' as parameter to non-global template SetProperty(Tin, alias
Field)(ref Tin param)

I don't understand why that error occurs.


I think it has to do with the fact that when you are defining the 
aliases, m_pos for example, is an *instance* member so requires an 
instance to get an alias.


What you are probably better off doing is:

void SetProperty(Tin, string Field)(ref Tin param) @property pure @safe
{
   mixin(Field ~  = param;);
   m_matrixCalculated = false;
}

alias pos = SetProperty!(float[], m_pos);

I would also put some strict template constraints on the Field string 
too, because one abuse SetProperty pretty easily there.


-Steve


Re: Define methods using templates

2014-12-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/30/14 8:48 AM, Steven Schveighoffer wrote:


I think it has to do with the fact that when you are defining the
aliases, m_pos for example, is an *instance* member so requires an
instance to get an alias.

What you are probably better off doing is:

void SetProperty(Tin, string Field)(ref Tin param) @property pure @safe
{
mixin(Field ~  = param;);
m_matrixCalculated = false;
}

alias pos = SetProperty!(float[], m_pos);

I would also put some strict template constraints on the Field string
too, because one abuse SetProperty pretty easily there.


A possibly more elegant solution, use opDispatch:

void opDispatch(string Field, Tin)(ref Tin param) @property pure @safe 
if(Field == pos || Field == ratio || ...)

{
   mixin(m_ ~ Field ~  = param;);
   m_matrixCalculated = false;
}

Not sure if opDispatch works as a @property this way...

-Steve


Re: Define methods using templates

2014-12-30 Thread Daniel Kozák via Digitalmars-d-learn
V Tue, 30 Dec 2014 13:17:08 +
Claude via Digitalmars-d-learn digitalmars-d-learn@puremagic.com
napsáno:

 Hello, I'm trying to use templates to define several methods 
 (property setters) within a class to avoid some code duplication.
 Here is an attempt:
 
 class Camera
 {
 private:
  Vector4 m_pos;
  float m_fov, m_ratio, m_near, m_far;
  bool m_matrixCalculated;
 
 public:
  void SetProperty(Tin, alias Field)(ref Tin param) @property 
 pure @safe
  {
  Field = param;
  m_matrixCalculated = false;
  }
 
  alias pos   = SetProperty!(float[], m_pos);
  alias pos   = SetProperty!(Vector4, m_pos);
  alias ratio = SetProperty!(float,   m_ratio);
  alias near  = SetProperty!(float,   m_near);
  alias far   = SetProperty!(float,   m_far);
 }
 
 I get this kind of compilation error:
 Error: template instance SetProperty!(float[], m_pos) cannot use 
 local 'm_pos' as parameter to non-global template 
 SetProperty(Tin, alias Field)(ref Tin param)
 
 I don't understand why that error occurs.
 
 And I cannot find any elegant solutions (even with mixin's) to 
 declare a template and then instantiate it in a single line to 
 define the methods I want.
 
 Does any of you have an idea?

 
 Thanks

class Camera
{
private:
int m_pos;
float m_fov, m_ratio, m_near, m_far;
bool m_matrixCalculated;

public:
mixin template opAssign(alias Field) {
void opAssign(Tin)(auto ref Tin param) @property pure @safe
{
Field = param;
m_matrixCalculated = false;
}
}

mixin opAssign!(m_pos)   pos;
mixin opAssign!(m_fov)   fov;
mixin opAssign!(m_ratio) ratio;
mixin opAssign!(m_near)  near;
mixin opAssign!(m_far)   far;

}

void main() {

Camera cam = new Camera();

cam.fov = 1.0;
stdin.readln;
}




Re: Define methods using templates

2014-12-30 Thread Claude via Digitalmars-d-learn

Thanks Steven and Daniel for your explanations.


mixin template opAssign(alias Field) {
void opAssign(Tin)(auto ref Tin param) @property pure 
@safe

{
Field = param;
m_matrixCalculated = false;
}
}

mixin opAssign!(m_pos)   pos;


I tested both the string mixin and opAssign implementations, 
and they work like a charm.
I would have never thought of using both @property and 
opAssign, but it looks like a secure way of doing it for the 
compilation fails nicely if I type a wrong field in.


src/camera.d(58): Error: undefined identifier m_os, did you mean 
variable m_pos?


Re: Define methods using templates

2014-12-30 Thread Ali Çehreli via Digitalmars-d-learn

On 12/30/2014 05:17 AM, Claude wrote:

 use templates to define several methods (property
 setters) within a class to avoid some code duplication.

I just saw this post, which is essentially the same question as Basile 
Burg's. I hope that a college (in France?) is teaching D and that this 
is a homework assignment. Cool stuff! :)


Ali