www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - building char[][] in templates

reply BCS <f d.c> writes:
I'm about ready to pull my hair out!!!
I'm trying to write a template that will split a string based on a character:

 char[][] foo = SplitString!("hello|world|this|is|a|test",'|');
 // foo == ["hello","world","this","is","a","test"];

I keep getting an error about this being non-const:
 null[0..0] ~ "hello" ~ "world" ~ "this" ~ "is" ~ "a" ~ "test"

I'm doing something like this:
template SplitString(char[] string, char c)
{
	static if(string == "")
		char[][] SplitString = (char[][]).init;
	else
		char[][] SplitString = SplitString!(BeforLast!(string,c),c) ~
AfterLast!(string,c);
}

Any ideas?? Better yet would be a template that evaluates to a tuple
template SplitString(char[] string, char c, V...)
{
	static if(string == "")
		auto SplitString = V;
	else
		auto SplitString = SplitString!(BeforLast!(string,c),c, V,
AfterLast!(string,c));
}

that would allow this:
void foo(char[] string)
{
	// static foreach
	foreach(s;SplitString!("hello|world|this|is|a|test",'|'))
	{
		//use s as const
	}
}

Dec 16 2006
parent reply Kevin Bealer <kevinbealer gmail.com> writes:
I've never done this myself, but there is an example of a metaprogramming regex
parser at the bottom of this page:

http://www.digitalmars.com/d/templates-revisited.html

Kevin
Dec 17 2006
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Kevin Bealer wrote:
 I've never done this myself, but there is an example of a metaprogramming regex
 parser at the bottom of this page:
 
 http://www.digitalmars.com/d/templates-revisited.html
 
 Kevin

If actually splitting the string doesn't work then maybe you can manage to have it generate a tuple of ints that represent the split points. --bb
Dec 17 2006
parent BCS <BCS pathlink.com> writes:
Bill Baxter wrote:
 Kevin Bealer wrote:
 
 I've never done this myself, but there is an example of a 
 metaprogramming regex
 parser at the bottom of this page:

 http://www.digitalmars.com/d/templates-revisited.html

 Kevin

If actually splitting the string doesn't work then maybe you can manage to have it generate a tuple of ints that represent the split points. --bb

This is what I ended up using (and it actually does a better job for what I was trying to do) it returns a tuple. /************ Return a slice up-to but not including the first instance of t. */ template UseTill(char[] string, char t) { static if(string == "" || string[0] == t) const char[] UseTill = ""; else const char[] UseTill = string[0..1] ~ UseTill!(string[1..$],t); } /*********** Return a slice starting after the first instance of t and containing the rest of the string. */ template DiscardTill(char[] string, char t) { static if(string == "") const char[] DiscardTill = ""; else static if(string[0] == t) const char[] DiscardTill = string[1..$]; else const char[] DiscardTill = DiscardTill!(string[1..$],t); } /*********** mixin temp with {V + 'string' broken up by 'c'} */ template BreakBy(char[] string, char d, V...) { static if(string == "") alias V BreakBy; else static alias BreakBy!(DiscardTill!(string,d), d, V, UseTill!(string,d)) BreakBy; }
Dec 18 2006