www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How to write a singleton template?

reply Li Jie <cpunion gmail.com> writes:
I try to write a singleton template, but has not succeeded:

A:
template Singleton(T)
{
private T _instance;

static this()
{
_instance = new T();
}

public T instance ()
{
return _instance;
}
}

B:
template Singleton(T)
{
class Singleton
{
private static T _instance;

static this()
{
_instance = new T();
}

public static T instance ()
{
return _instance;
}
}
}

C:
template Singleton(T)
{
class Singleton
{
private static T _instance = null;

public static T instance ()
{
if (_instance == null)
_instance = new T();
return _instance;
}
}
}


// use it:

class AAA
{
public void hello ()
{
printf("hello\n");
}
}

int main(char[][] args)
{
alias Singleton!(AAA) aaa;
aaa.instance().hello();  // <== Segment fault !!!!!

return 0;
}

I want to know, how to write a singleton template?



Thanks.

- Li Jie
Mar 14 2006
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Li Jie" <cpunion gmail.com> wrote in message 
news:dv7s7e$1hee$1 digitaldaemon.com...

Versions A and B work fine, but version C doesn't work because of this line:

 if (_instance == null)

Change it to if(_instance is null) This is because the == operator calls opEquals on the first object, so _instance == null is the same as _instance.opEquals(null) - which is obviously going to cause a segfault if _instance is null. Use the "is" (and the "!is") operator to determine what a class reference is pointing to (like null).
Mar 14 2006
parent Li Jie <cpunion gmail.com> writes:
In article <dv80jr$1m1g$1 digitaldaemon.com>, Jarrett Billingsley says...
Versions A and B work fine, but version C doesn't work because of this line:

 if (_instance == null)

Change it to if(_instance is null) This is because the == operator calls opEquals on the first object, so _instance == null is the same as _instance.opEquals(null) - which is obviously going to cause a segfault if _instance is null. Use the "is" (and the "!is") operator to determine what a class reference is pointing to (like null).

Thannnks. It works find. But, Versions A and B work can't work on my computer. Segment fault at the same line, and I don't know why. My system: P4 3.0G, 1G RAM, Gentoo 2006.0 gcc 3.4.4, dmd 0.149 Thanks again. - Li Jie
Mar 14 2006
prev sibling next sibling parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Li Jie wrote:
 I try to write a singleton template, but has not succeeded:
 
 A:
 template Singleton(T)
 {
 private T _instance;
 
 static this()
 {
 _instance = new T();
 }
 
 public T instance ()
 {
 return _instance;
 }
 }
 
 B:
 template Singleton(T)
 {
 class Singleton
 {
 private static T _instance;
 
 static this()
 {
 _instance = new T();
 }
 
 public static T instance ()
 {
 return _instance;
 }
 }
 }
 
 C:
 template Singleton(T)
 {
 class Singleton
 {
 private static T _instance = null;
 
 public static T instance ()
 {
 if (_instance == null)
 _instance = new T();
 return _instance;
 }
 }
 }
 
 
 // use it:
 
 class AAA
 {
 public void hello ()
 {
 printf("hello\n");
 }
 }
 
 int main(char[][] args)
 {
 alias Singleton!(AAA) aaa;
 aaa.instance().hello();  // <== Segment fault !!!!!
 
 return 0;
 }
 
 I want to know, how to write a singleton template?
 
 
 
 Thanks.
 
 - Li Jie
 
 

You might want to consider a mixin: template Singleton(T) { static this() { _instance = new T(); } public static T instance () { return _instance; } private static T _instance; } class OnlyOne { // Can't include this in the mixin, // because D can only mixin static things to classes private this() {} mixin Singleton!(OnlyOne); } Or with inheritance: // Note here that there is some syntactic sugar for templated classes class Singleton(T) { static this() { _instance = new T(); } public static T instance () { return _instance; } protected static T _instance; } class OnlyOne : Singleton!(OnlyOne) { private this() {} }
Mar 14 2006
next sibling parent reply Li Jie <cpunion gmail.com> writes:
In article <dv8anc$2109$1 digitaldaemon.com>, Kyle Furlong says...
You might want to consider a mixin:

template Singleton(T)
{
	static this()
	{
		_instance = new T();
	}
	public static T instance ()
	{
		return _instance;
	}
	private static T _instance;
}

class OnlyOne
{
	// Can't include this in the mixin,
	// because D can only mixin static things to classes
	private this() {}
	mixin Singleton!(OnlyOne);
}

Or with inheritance:

// Note here that there is some syntactic sugar for templated classes

class Singleton(T)
{
	static this()
	{
		_instance = new T();
	}
	public static T instance ()
	{
		return _instance;
	}
	protected static T _instance;
}

class OnlyOne : Singleton!(OnlyOne)
{
	private this() {}
}

Thanks. In the version 2, must 'Singleton' template class and 'OnlyOne' class be in the same file? I've never seen the usage of 'class XXX(T)', I read 'class.html' and 'template.html', but not found. Which document mention it? - Li Jie
Mar 15 2006
parent Kyle Furlong <kylefurlong gmail.com> writes:
Li Jie wrote:
 In article <dv8anc$2109$1 digitaldaemon.com>, Kyle Furlong says...
 You might want to consider a mixin:

 template Singleton(T)
 {
 	static this()
 	{
 		_instance = new T();
 	}
 	public static T instance ()
 	{
 		return _instance;
 	}
 	private static T _instance;
 }

 class OnlyOne
 {
 	// Can't include this in the mixin,
 	// because D can only mixin static things to classes
 	private this() {}
 	mixin Singleton!(OnlyOne);
 }

 Or with inheritance:

 // Note here that there is some syntactic sugar for templated classes

 class Singleton(T)
 {
 	static this()
 	{
 		_instance = new T();
 	}
 	public static T instance ()
 	{
 		return _instance;
 	}
 	protected static T _instance;
 }

 class OnlyOne : Singleton!(OnlyOne)
 {
 	private this() {}
 }

Thanks. In the version 2, must 'Singleton' template class and 'OnlyOne' class be in the same file?

No, D templates can be in separate modules, just import the module you put the template in.
 I've never seen the usage of 'class XXX(T)', I read 'class.html' and
 'template.html', but not found. Which document mention it?
 
 
 - Li Jie
 
 

Its in http://www.digitalmars.com/d/template.html, about 80% down the page, with the heading Class Templates. What is undocumented is the fact that struct templates are also legal. (a very nice feature IMHO)
Mar 15 2006
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Kyle Furlong wrote:
 
 You might want to consider a mixin:
 
 template Singleton(T)
 {
     static this()
     {
         _instance = new T();
     }
     public static T instance ()
     {
         return _instance;
     }
     private static T _instance;
 }
 
 class OnlyOne
 {
     // Can't include this in the mixin,
     // because D can only mixin static things to classes
     private this() {}
     mixin Singleton!(OnlyOne);
 }
 

"because D can only mixin static things to classes" -> That is incorrect, you can include instance methods and constructors just fine. See for yourself in a example such as this: template Baz() { public void func() { writefln(x); } public this() { writefln("Construct!"); } } class Foo { int x = 2; mixin Baz!(); } ... (new Foo).func(); The only problem is with private protection attributes and constructors, as reported in bug: news://news.digitalmars.com:119/bug-49-3 http.d.puremagic.com/bugzilla/ -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Mar 15 2006
parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Bruno Medeiros wrote:
 Kyle Furlong wrote:
 You might want to consider a mixin:

 template Singleton(T)
 {
     static this()
     {
         _instance = new T();
     }
     public static T instance ()
     {
         return _instance;
     }
     private static T _instance;
 }

 class OnlyOne
 {
     // Can't include this in the mixin,
     // because D can only mixin static things to classes
     private this() {}
     mixin Singleton!(OnlyOne);
 }

"because D can only mixin static things to classes" -> That is incorrect, you can include instance methods and constructors just fine. See for yourself in a example such as this: template Baz() { public void func() { writefln(x); } public this() { writefln("Construct!"); } } class Foo { int x = 2; mixin Baz!(); } ... (new Foo).func(); The only problem is with private protection attributes and constructors, as reported in bug: news://news.digitalmars.com:119/bug-49-3 http.d.puremagic.com/bugzilla/

The documentation leads one to believe that this is impossible. Look under the limitations header. This needs to be clarified.
Mar 15 2006
parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Kyle Furlong wrote:
 Bruno Medeiros wrote:
 Kyle Furlong wrote:
 You might want to consider a mixin:

 template Singleton(T)
 {
     static this()
     {
         _instance = new T();
     }
     public static T instance ()
     {
         return _instance;
     }
     private static T _instance;
 }

 class OnlyOne
 {
     // Can't include this in the mixin,
     // because D can only mixin static things to classes
     private this() {}
     mixin Singleton!(OnlyOne);
 }

"because D can only mixin static things to classes" -> That is incorrect, you can include instance methods and constructors just fine. See for yourself in a example such as this: template Baz() { public void func() { writefln(x); } public this() { writefln("Construct!"); } } class Foo { int x = 2; mixin Baz!(); } ... (new Foo).func(); The only problem is with private protection attributes and constructors, as reported in bug: news://news.digitalmars.com:119/bug-49-3 http.d.puremagic.com/bugzilla/

The documentation leads one to believe that this is impossible. Look under the limitations header. This needs to be clarified.

The limitations section is about instantiating templates that are defined inside a class, it is not about mixing in in a template inside a class, which is a different thing. The limitation exists only in the first case. This behaviour make sense. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Mar 19 2006
parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Bruno Medeiros wrote:
 Kyle Furlong wrote:
 Bruno Medeiros wrote:
 Kyle Furlong wrote:
 You might want to consider a mixin:

 template Singleton(T)
 {
     static this()
     {
         _instance = new T();
     }
     public static T instance ()
     {
         return _instance;
     }
     private static T _instance;
 }

 class OnlyOne
 {
     // Can't include this in the mixin,
     // because D can only mixin static things to classes
     private this() {}
     mixin Singleton!(OnlyOne);
 }

"because D can only mixin static things to classes" -> That is incorrect, you can include instance methods and constructors just fine. See for yourself in a example such as this: template Baz() { public void func() { writefln(x); } public this() { writefln("Construct!"); } } class Foo { int x = 2; mixin Baz!(); } ... (new Foo).func(); The only problem is with private protection attributes and constructors, as reported in bug: news://news.digitalmars.com:119/bug-49-3 http.d.puremagic.com/bugzilla/

The documentation leads one to believe that this is impossible. Look under the limitations header. This needs to be clarified.

The limitations section is about instantiating templates that are defined inside a class, it is not about mixing in in a template inside a class, which is a different thing. The limitation exists only in the first case. This behaviour make sense.

It is misleading because it asserts "Templates cannot be used to add non-static members or functions to classes." Even with the example, its still a blanket, general statement. It should specify that the example is the only case which has the limitation.
Mar 19 2006
parent Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Kyle Furlong wrote:
 Bruno Medeiros wrote:
 Kyle Furlong wrote:
 Bruno Medeiros wrote:
 Kyle Furlong wrote:
 You might want to consider a mixin:

 template Singleton(T)
 {
     static this()
     {
         _instance = new T();
     }
     public static T instance ()
     {
         return _instance;
     }
     private static T _instance;
 }

 class OnlyOne
 {
     // Can't include this in the mixin,
     // because D can only mixin static things to classes
     private this() {}
     mixin Singleton!(OnlyOne);
 }

"because D can only mixin static things to classes" -> That is incorrect, you can include instance methods and constructors just fine. See for yourself in a example such as this: template Baz() { public void func() { writefln(x); } public this() { writefln("Construct!"); } } class Foo { int x = 2; mixin Baz!(); } ... (new Foo).func(); The only problem is with private protection attributes and constructors, as reported in bug: news://news.digitalmars.com:119/bug-49-3 http.d.puremagic.com/bugzilla/

The documentation leads one to believe that this is impossible. Look under the limitations header. This needs to be clarified.

The limitations section is about instantiating templates that are defined inside a class, it is not about mixing in in a template inside a class, which is a different thing. The limitation exists only in the first case. This behaviour make sense.

It is misleading because it asserts "Templates cannot be used to add non-static members or functions to classes." Even with the example, its still a blanket, general statement. It should specify that the example is the only case which has the limitation.

The term, "Inner templates" should be clear enough then, as in "Inner Templates cannot be used to add non-static members or functions to classes." ? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Mar 20 2006
prev sibling parent Frank Benoit <frank nix.de> writes:
 printf("hello\n");

string not null terminated, change to one of printf("hello\n\x00"); writef("hello\n"); writefln("hello"); Frank
Mar 15 2006