1 /**
2  * Copyright: Copyright (c) 2010 Jacob Carlborg.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Jan 26, 2010
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  */
7 module mambo.util.Ctfe;
8 
9 import mambo.core..string;
10 import mambo.util.Traits;
11 
12 template format (ARGS...)
13 {
14 	static if (ARGS.length == 0)
15 		const format = "";
16 
17 	else
18 	{
19 		static if (is(typeof(ARGS[0]) : string))
20 			const format = ARGS[0] ~ format!(ARGS[1 .. $]);
21 
22 		else
23 			const format = toString_!(ARGS[0]) ~ format!(ARGS[1 .. $]);
24 	}
25 }
26 
27 private
28 {
29 	template toString_ (T)
30 	{
31 		const toString_ = T.stringof;
32 	}
33 
34 	template toString_ (int i)
35 	{
36 		const toString_ = itoa!(i);
37 	}
38 
39 	template toString_ (long l)
40 	{
41 		const toString_ = itoa!(l);
42 	}
43 
44 	template toString_ (bool b)
45 	{
46 		const toString_ = b ? "true" : "false";
47 	}
48 
49 	template toString_ (float f)
50 	{
51 		const toString_ = "";
52 	}
53 
54 	template toString_ (alias a)
55 	{
56 		const toString_ = a.stringof;
57 	}
58 }
59 
60 /**
61  * Compile-time function to get the index of the give element.
62  *
63  * Performs a linear scan, returning the index of the first occurrence
64  * of the specified element in the array, or U.max if the array does
65  * not contain the element.
66  *
67  * Params:
68  *     arr = the array to get the index of the element from
69  *     element = the element to find
70  *
71  * Returns: the index of the element or size_t.max if the element was not found.
72  */
73 size_t indexOf (T) (T[] arr, dchar element) if (isChar!(T))
74 {
75 	foreach (i, dchar e ; arr)
76 		if (e == element)
77 			return i;
78 
79 	return size_t.max;
80 }
81 
82 /// Ditto
83 size_t indexOf (T) (T[] arr, T element)
84 {
85 	foreach (i, e ; arr)
86 		if (e == element)
87 			return i;
88 
89 	return size_t.max;
90 }
91 
92 /**
93  * Returns true if the given array contains the given element,
94  * otherwise false.
95  *
96  * Params:
97  *     arr = the array to search in for the element
98  *     element = the element to search for
99  *
100  * Returns: true if the array contains the element, otherwise false
101  */
102 bool contains (T) (T[] arr, T element)
103 {
104 	return arr.indexOf(element) != size_t.max;
105 }
106 
107 /**
108  * CTFE, splits the given string on the given pattern
109  *
110  * Params:
111  *     str = the string to split
112  *     splitChar = the character to split on
113  *
114  * Returns: an array of strings containing the splited string
115  */
116 T[][] split (T) (T[] str, T splitChar = ',')
117 {
118 	T[][] arr;
119 	size_t x;
120 
121 	foreach (i, c ; str)
122 	{
123 		if (splitChar == c)
124 		{
125 			if (str[x] == splitChar)
126 				x++;
127 
128 			arr ~= str[x .. i];
129 			x = i;
130 		}
131 	}
132 
133 	if (str[x] == splitChar)
134 		x++;
135 
136 	arr ~= str[x .. $];
137 
138 	return arr;
139 }
140 
141 private:
142 
143 template decimalDigit (int n)	// [3]
144 {
145 	const decimalDigit = "0123456789"[n .. n + 1];
146 }
147 
148 template itoa (long n)
149 {
150 	static if (n < 0)
151 		const itoa = "-" ~ itoa!(-n);
152 
153 	else static if (n < 10)
154 		const itoa = decimalDigit!(n);
155 
156 	else
157 		const itoa = itoa!(n / 10L) ~ decimalDigit!(n % 10L);
158 }