Thread overview
Add compile time mutable variable type
Jun 05, 2012
Chang Long
Jun 05, 2012
Chang Long
Jun 05, 2012
Chang Long
Jun 05, 2012
Ali Çehreli
Jun 05, 2012
Chang Long
June 05, 2012
 I need a type can be change on compile time,  it can be immutable or mutable at run time.

For example :
-------------------------------------------------------------------------------
abstract class Template_parameter_Base{
        TypeInto ti;
        string file ;
        size_t  line l;
        string name ;

       this(TypeInto ti, string file, size_t line, string name){
            this.ti = ti ;
            this.file = file ;
           this.line = line ;
           this.name = name ;
        }
}

class Template_parameter(T) : Template_parameter_Base {
       T   value ;
       alias T this;
	void assign(ref T t){
		value = t ;
	}
}

class Template {
         static compile_time_mutable(string[Template_parameter_Base])  template_vars ;

	void assign(string name, string __file__ = __FILE__, size_t __line__ =__LINE__, T)(T t) {
		static if( name in template_vars ){
			static parameter = template_vars[name] ;
		} else {
			static parameter = template_vars[name] =  new Template_parameter(typeid(T),  __file__, __line__ );
		}
		parameter.assign(t);
	}
	
	string render(){
		// use template_vars comiplate a dynamic link lib ,  and load it,  and put the template_vars to it, and run it ,
		// if  dynamic link lib  already exists,  or the templte file is not changed, just run it .
	}
}

void main(){
	static tpl = new Template;
	auto  is_login  =  false ;
	tpl.assign!"is_login"( is_login) ) ;
	if( is_login ) {
		tpl.assign!"user"( new User() ) ;
	}
}

-------------------------------------------------------------------------------

Why I need this is because I need to know all parameters at first time call Template.render,  but a lot parameter will not be call at run time. so I need a type can be changed at compile time.
the new type is just like mutable type at CTFE.



June 05, 2012
On Tuesday, 5 June 2012 at 01:01:07 UTC, Chang Long wrote:
>  I need a type can be change on compile time,  it can be immutable or mutable at run time.
>
> For example :
> -------------------------------------------------------------------------------
> abstract class Template_parameter_Base{
>         TypeInto ti;
>         string file ;
>         size_t  line l;
>         string name ;
>
>        this(TypeInto ti, string file, size_t line, string name){
>             this.ti = ti ;
>             this.file = file ;
>            this.line = line ;
>            this.name = name ;
>         }
> }
>
> class Template_parameter(T) : Template_parameter_Base {
>        T   value ;
>        alias T this;
> 	void assign(ref T t){
> 		value = t ;
> 	}
> }
>
> class Template {
>          static compile_time_mutable(string[Template_parameter_Base])  template_vars ;
>
> 	void assign(string name, string __file__ = __FILE__, size_t __line__ =__LINE__, T)(T t) {
> 		static if( name in template_vars ){
> 			static parameter = template_vars[name] ;
> 		} else {
> 			static parameter = template_vars[name] =  new Template_parameter(typeid(T),  __file__, __line__ );
> 		}
> 		parameter.assign(t);
> 	}
> 	
> 	string render(){
> 		// use template_vars comiplate a dynamic link lib ,  and load it,  and put the template_vars to it, and run it ,
> 		// if  dynamic link lib  already exists,  or the templte file is not changed, just run it .
> 	}
> }
>
> void main(){
> 	static tpl = new Template;
> 	auto  is_login  =  false ;
> 	tpl.assign!"is_login"( is_login) ) ;
> 	if( is_login ) {
> 		tpl.assign!"user"( new User() ) ;
> 	}
> }
>
> -------------------------------------------------------------------------------
>
> Why I need this is because I need to know all parameters at first time call Template.render,  but a lot parameter will not be call at run time. so I need a type can be changed at compile time.
> the new type is just like mutable type at CTFE.

this example is more convincing:




abstract class Template_parameter_Base{
        TypeInto ti;
        string file ;
        size_t  line l;
        string name ;

       this(TypeInto ti, string file, size_t line, string name){
            this.ti = ti ;
            this.file = file ;
            this.line = line ;
            this.name = name ;
        }
}

class Template_parameter(T) : Template_parameter_Base {
       T   value ;
       alias T this;
	void assign(ref T t){
		value = t ;
	}
}

class Template {
         static compile_time_mutable(Template_parameter_Base[string])  template_vars ;

	void assign(string name, string __file__ = __FILE__, size_t __line__ =__LINE__, T)(T t) {
		static if( name in template_vars ){
			static compile_time_mutable(parameter) = template_vars[name] ;
			static assert( parameter.ti == typeid(T),  "assign var at " ~ __file__ ~ " line" ~ __line__ " with type " ~ T.stringof " ~ conflict with old parameter at file " ~ parameter.file  ~ " line " ~ parameter.line );
		} else {
			static compile_time_mutable(parameter) = template_vars[name] =  new Template_parameter(typeid(T),  __file__, __line__ , name );
		}
		// put the value to parameter at run time
		parameter.assign(t);
	}
	
	string render(){
		// use template_vars comiplate a dynamic link lib ,  and load it,  and put the template_vars to it, and run it ,
		// if  dynamic link lib  already exists,  or the templte file is not changed, just run it .
	}
}

void main(){
	static tpl = new Template;
	auto  is_login  =  false ;
	tpl.assign!"is_login"( is_login) ) ;
	if( is_login ) {
		tpl.assign!"user"( new User() ) ;
	}
	
	auto string switch_user = "new_user_email" ;
	if( switch_user !is null ) {
		tpl.assign!"user"( new User(switch_user) ) ;
	}
	
	tpl.assign!"user"( true )  ; // static assert error
}

June 05, 2012
On Tuesday, 5 June 2012 at 01:01:07 UTC, Chang Long wrote:
>  I need a type can be change on compile time,  it can be immutable or mutable at run time.
>
> For example :
> -------------------------------------------------------------------------------
> abstract class Template_parameter_Base{
>         TypeInto ti;
>         string file ;
>         size_t  line l;
>         string name ;
>
>        this(TypeInto ti, string file, size_t line, string name){
>             this.ti = ti ;
>             this.file = file ;
>            this.line = line ;
>            this.name = name ;
>         }
> }
>
> class Template_parameter(T) : Template_parameter_Base {
>        T   value ;
>        alias T this;
> 	void assign(ref T t){
> 		value = t ;
> 	}
> }
>
> class Template {
>          static compile_time_mutable(string[Template_parameter_Base])  template_vars ;
>
> 	void assign(string name, string __file__ = __FILE__, size_t __line__ =__LINE__, T)(T t) {
> 		static if( name in template_vars ){
> 			static parameter = template_vars[name] ;
> 		} else {
> 			static parameter = template_vars[name] =  new Template_parameter(typeid(T),  __file__, __line__ );
> 		}
> 		parameter.assign(t);
> 	}
> 	
> 	string render(){
> 		// use template_vars comiplate a dynamic link lib ,  and load it,  and put the template_vars to it, and run it ,
> 		// if  dynamic link lib  already exists,  or the templte file is not changed, just run it .
> 	}
> }
>
> void main(){
> 	static tpl = new Template;
> 	auto  is_login  =  false ;
> 	tpl.assign!"is_login"( is_login) ) ;
> 	if( is_login ) {
> 		tpl.assign!"user"( new User() ) ;
> 	}
> }
>
> -------------------------------------------------------------------------------
>
> Why I need this is because I need to know all parameters at first time call Template.render,  but a lot parameter will not be call at run time. so I need a type can be changed at compile time.
> the new type is just like mutable type at CTFE.


The previous two example is not correct, please see this one:





abstract class Template_parameter_Base{
        TypeInto ti;
        string file ;
        size_t  line l;
        string name ;

       this(TypeInto ti, string file, size_t line, string name){
            this.ti = ti ;
            this.file = file ;
            this.line = line ;
            this.name = name ;
        }
}

class Template_parameter(T) : Template_parameter_Base {
       T   value ;
       alias T this;
	void assign(ref T t){
		value = t ;
	}
}

class Template_Engine {
	string name ;
	Template_parameter_Base[string] parameters ;
	void this(string name) {
		this.name = name ;
	}
}


class Template (string name) {
	
	static compile_time_mutable(Template_Engine)  engine = new Template_Engine(name) ;
	
	void assign(string name, string __file__ = __FILE__, size_t __line__ =__LINE__, T)(T t) {
		static if( name in engine.parameters ){
			static compile_time_mutable(parameter) = engine.parameters[name] ;
			static assert( parameter.ti == typeid(T),  "assign var at " ~ __file__ ~ " line" ~ __line__ " with type " ~ T.stringof " ~ conflict with old parameter at file " ~ parameter.file  ~ " line " ~ parameter.line );
		} else {
			static compile_time_mutable(parameter) = engine.parameters[name] =  new Template_parameter(typeid(T),  __file__, __line__ , name );
		}
		// put the value to parameter at run time
		parameter.assign(t);
	}
	
	string render(){
		// use the engine.parameters can know all parameter type information
		// use template_vars comiplate a dynamic link lib ,  and load it,  and put the template_vars to it, and run it ,
		// if  dynamic link lib  already exists,  or the templte file is not changed, just run it .
	}
}

void main(){
	static tpl = new Template!"home_page" ;
	auto  is_login  =  false ;
	tpl.assign!"is_login"( is_login) ) ;
	if( is_login ) {
		tpl.assign!"user"( new User() ) ;
	}
	
	auto string switch_user = "new_user_email" ;
	if( switch_user !is null ) {
		tpl.assign!"user"( new User(switch_user) ) ;
	}
	
	tpl.assign!"user"( true )  ; // static assert error
}

June 05, 2012
On 06/04/2012 06:22 PM, Chang Long wrote:

> The previous two example is not correct, please see this one:

Your post sounds interesting but there are lots of errors:

> size_t line l;  <-- ERROR

> void this(string name) { <-- ERROR

etc. Can you actually compile that code?

It would be better if you can present your question with less code.

Ali

June 05, 2012
On Tuesday, 5 June 2012 at 05:39:34 UTC, Ali Çehreli wrote:
> On 06/04/2012 06:22 PM, Chang Long wrote:
>
> > The previous two example is not correct, please see this one:
>
> Your post sounds interesting but there are lots of errors:
>
> > size_t line l;  <-- ERROR
>
> > void this(string name) { <-- ERROR
>
> etc. Can you actually compile that code?
>
> It would be better if you can present your question with less code.
>
> Ali
this is what I mean, I can't make it more smaller.
-----------------------------------------------------------
abstract class Template_parameter_Base{
        TypeInto ti;
        string name ;
        this(TypeInto ti, string name) {
            this.ti = ti ;
            this.name = name ;
        }
}
class Template_parameter(T) : Template_parameter_Base {
	T   value ;
 	alias value this;
	void assign(ref T t){
		value = t ;
	}
}
class Template_Engine {
	string name ;
	Template_parameter_Base[string] parameters ;
	void this(string name) {
		this.name = name ;
	}
}
class Template(string name) {
	static compile_time_mutable(Template_Engine)  engine = new Template_Engine!name ;
	void assign(string name, T)(ref T t){
		static if(name in vars) {
			static const parameter	= cast(Template_parameter!T) engine.parameters[name];
			static assert( parameter.ti == typeid(T) );
		} else {
			static const parameter	=  new Template_parameter!T(typeid(T), name) ;
			static engine.parameters[name]		=  parameter ;
		}
		parameter.assign(t);
	}
}
void main(){
	static tpl = new Template!"home_page" ;
	auto  is_login  =  false ;
	tpl.assign!"is_login"( is_login) ) ;
	if( is_login ) {
		tpl.assign!"user"( new User() ) ;
	}
	
	auto string switch_user = "new_user_email" ;
	if( switch_user !is null ) {
		tpl.assign!"user"( new User(switch_user) ) ;
	}
	
	tpl.assign!"user"( true )  ; // static assert error
}
-----------------------------------------------------------

After think what is done,  a better way is put the Template_parameter on the annotation data section.

some things like this:
class Template_Engine(string name) {
     static this_ti =  typeid( typeof(this) ) ;
     void assign(string name, T)(ref T t){
            static const parameter = new Template_parameter!(T, name) ;
            ti.createAnnotation("Template_Engine_Parameter", parameter);
            parameter.assign(t);
      }
      void render(){
           auto parameters =  this_ti.getParametersByName("Template_Engine_Parameter") ;
           // compile template to dynamic link library by template file and parameters
     }
}