digitalmars.D - Add compile time mutable variable type
- "Chang Long" <changlon gmail.com> Jun 04 2012
- "Chang Long" <changlon gmail.com> Jun 04 2012
- "Chang Long" <changlon gmail.com> Jun 04 2012
- "Chang Long" <changlon gmail.com> Jun 04 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.
Jun 04 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 }
Jun 04 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 }
Jun 04 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
Jun 04 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
----------------------------------------------------------- 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 } }
Jun 04 2012









"Chang Long" <changlon gmail.com> 