On 14.05.2012 21:33, Dmitry Olshansky wrote:
On 14.05.2012 21:20, Roman D. Boiko wrote:
On Monday, 14 May 2012 at 16:41:39 UTC, Jonathan M Davis wrote:
On Monday, May 14, 2012 17:10:23 Roman D. Boiko wrote:
(Subj.) I'm in doubt which to choose for my case, but this is a
generic question.
http://forum.dlang.org/post/odcrgqxoldrktdtar...@forum.dlang.org
Cross-posting here. I would appreciate any feedback. (Whether to
reply in this or that thread is up to you.) Thanks
For the question in general, there are primarily 2 questions to
consider:
1. Do you need inheritance/polymorphism?
don't have inheritance.
2. Do you need a value type or a reference type?
If you need inheritance/polymorphism, you have to use classes, because
structs
If you want a value type, you have to use structs, because classes are
reference types.
If you want a reference type, then you can use either a class or a
struct, but
it's easier with classes, because classes are always reference types,
whereas
structs are naturally value types, so it can take more work to make them
reference types depending on what its member variables are.
One other thing to consider is deterministic destruction. The only way
to get
deterministic destruction is to have a struct on the stack. Value
types will
naturally get that, but if you want a reference type with determinstic
destruction, then you're probably going to have to use a ref-counted
struct.
In the vast majority of cases, that should be enough to decide whether
you
need a class or a struct. The main case that it doesn't is the case
where you
want a reference type and don't necessarily want a class, and that
decision
can get complicated.
In the case of a token in a lexer, I would definitely expect that to
be a value
type, which means using a struct.
- Jonathan M Davis
Semantics is clearly of value type. But it would be nice to
minimize size of instance to be copied. (I could simply split it
into two, if some part is not used in most scenarios.)
Just curious: how to implement a struct as ref type? I could add
indirection (but then why not just use a class?), or simply pass
by ref into all methods. Are there any other options?
Use the damn pointer ;)
In a few words (lines) overwrite struct contents (first 4-8 bytes) with
pointer to next free token:
//setup:
void get_some_memory()
{
Token pool = new Token[block_size];
for(size_t i=0;i<pool.length-1; i++)
*(void**)(tok.ptr+i) = tok.ptr+i+1;
*(void**)&tok[$-1] = null; //end of list
}
Token* head = pool.ptr;//this guy in TLS
//usage:
Token* new_tok(){
if(!head)
get_some_memory();
Token* r = head;
head = *(token**)head;
return r;
}
Not so trustworthy :o)
But hopefully you get the idea. See something simillar in std.regex,
though pointer in there also serves for intrusive linked-list.
void free_tok(Token* tok){
*(void**)tok = head;
head = tok;
}
Untested but trustworthy ;)
Thanks to everybody for your feedback, it looks like I'll stay
with struct.
--
Dmitry Olshansky