Commit 3b012a8086d550433188cebbf95746d2455f0b6f
1 parent
7731cf24
added code for command-line arguments
Showing
5 changed files
with
480 additions
and
48 deletions
Show diff stats
math/complex.h
@@ -143,8 +143,8 @@ struct complex | @@ -143,8 +143,8 @@ struct complex | ||
143 | } | 143 | } |
144 | CUDA_CALLABLE complex<T> & operator=(const T &rhs) | 144 | CUDA_CALLABLE complex<T> & operator=(const T &rhs) |
145 | { | 145 | { |
146 | - this->r = rhs; | ||
147 | - this->i = 0; | 146 | + this->r = rhs; |
147 | + this->i = 0; | ||
148 | 148 | ||
149 | return *this; | 149 | return *this; |
150 | } | 150 | } |
@@ -153,34 +153,34 @@ struct complex | @@ -153,34 +153,34 @@ struct complex | ||
153 | CUDA_CALLABLE complex<T> operator+=(const complex<T> &rhs) | 153 | CUDA_CALLABLE complex<T> operator+=(const complex<T> &rhs) |
154 | { | 154 | { |
155 | *this = *this + rhs; | 155 | *this = *this + rhs; |
156 | - return *this; | 156 | + return *this; |
157 | } | 157 | } |
158 | CUDA_CALLABLE complex<T> operator+=(const T &rhs) | 158 | CUDA_CALLABLE complex<T> operator+=(const T &rhs) |
159 | { | 159 | { |
160 | *this = *this + rhs; | 160 | *this = *this + rhs; |
161 | - return *this; | 161 | + return *this; |
162 | } | 162 | } |
163 | 163 | ||
164 | CUDA_CALLABLE complex<T> operator*=(const complex<T> &rhs) | 164 | CUDA_CALLABLE complex<T> operator*=(const complex<T> &rhs) |
165 | { | 165 | { |
166 | *this = *this * rhs; | 166 | *this = *this * rhs; |
167 | - return *this; | 167 | + return *this; |
168 | } | 168 | } |
169 | CUDA_CALLABLE complex<T> operator*=(const T &rhs) | 169 | CUDA_CALLABLE complex<T> operator*=(const T &rhs) |
170 | { | 170 | { |
171 | *this = *this * rhs; | 171 | *this = *this * rhs; |
172 | - return *this; | 172 | + return *this; |
173 | } | 173 | } |
174 | //divide and assign | 174 | //divide and assign |
175 | CUDA_CALLABLE complex<T> operator/=(const complex<T> &rhs) | 175 | CUDA_CALLABLE complex<T> operator/=(const complex<T> &rhs) |
176 | { | 176 | { |
177 | *this = *this / rhs; | 177 | *this = *this / rhs; |
178 | - return *this; | 178 | + return *this; |
179 | } | 179 | } |
180 | CUDA_CALLABLE complex<T> operator/=(const T &rhs) | 180 | CUDA_CALLABLE complex<T> operator/=(const T &rhs) |
181 | { | 181 | { |
182 | *this = *this / rhs; | 182 | *this = *this / rhs; |
183 | - return *this; | 183 | + return *this; |
184 | } | 184 | } |
185 | 185 | ||
186 | //absolute value operator (returns the absolute value of the complex number) | 186 | //absolute value operator (returns the absolute value of the complex number) |
@@ -191,23 +191,23 @@ struct complex | @@ -191,23 +191,23 @@ struct complex | ||
191 | 191 | ||
192 | CUDA_CALLABLE complex<T> log() | 192 | CUDA_CALLABLE complex<T> log() |
193 | { | 193 | { |
194 | - complex<T> result; | ||
195 | - result.r = std::log(std::sqrt(r * r + i * i)); | ||
196 | - result.i = std::atan2(i, r); | 194 | + complex<T> result; |
195 | + result.r = (T)std::log(std::sqrt(r * r + i * i)); | ||
196 | + result.i = (T)std::atan2(i, r); | ||
197 | 197 | ||
198 | 198 | ||
199 | - return result; | 199 | + return result; |
200 | } | 200 | } |
201 | 201 | ||
202 | CUDA_CALLABLE complex<T> exp() | 202 | CUDA_CALLABLE complex<T> exp() |
203 | { | 203 | { |
204 | - complex<T> result; | 204 | + complex<T> result; |
205 | 205 | ||
206 | - T e_r = std::exp(r); | ||
207 | - result.r = e_r * std::cos(i); | ||
208 | - result.i = e_r * std::sin(i); | 206 | + T e_r = std::exp(r); |
207 | + result.r = e_r * (T)std::cos(i); | ||
208 | + result.i = e_r * (T)std::sin(i); | ||
209 | 209 | ||
210 | - return result; | 210 | + return result; |
211 | } | 211 | } |
212 | 212 | ||
213 | /*CUDA_CALLABLE complex<T> pow(int y) | 213 | /*CUDA_CALLABLE complex<T> pow(int y) |
@@ -218,11 +218,11 @@ struct complex | @@ -218,11 +218,11 @@ struct complex | ||
218 | 218 | ||
219 | CUDA_CALLABLE complex<T> pow(T y) | 219 | CUDA_CALLABLE complex<T> pow(T y) |
220 | { | 220 | { |
221 | - complex<T> result; | 221 | + complex<T> result; |
222 | 222 | ||
223 | - result = log() * y; | 223 | + result = (T)log() * y; |
224 | 224 | ||
225 | - return result.exp(); | 225 | + return result.exp(); |
226 | } | 226 | } |
227 | 227 | ||
228 | CUDA_CALLABLE complex<T> sqrt() | 228 | CUDA_CALLABLE complex<T> sqrt() |
@@ -275,14 +275,14 @@ struct complex | @@ -275,14 +275,14 @@ struct complex | ||
275 | template<typename T> | 275 | template<typename T> |
276 | CUDA_CALLABLE static rts::complex<T> operator+(const double a, const rts::complex<T> b) | 276 | CUDA_CALLABLE static rts::complex<T> operator+(const double a, const rts::complex<T> b) |
277 | { | 277 | { |
278 | - return rts::complex<T>(a + b.r, b.i); | 278 | + return rts::complex<T>((T)a + b.r, b.i); |
279 | } | 279 | } |
280 | 280 | ||
281 | //subtraction with a real value | 281 | //subtraction with a real value |
282 | template<typename T> | 282 | template<typename T> |
283 | CUDA_CALLABLE static rts::complex<T> operator-(const double a, const rts::complex<T> b) | 283 | CUDA_CALLABLE static rts::complex<T> operator-(const double a, const rts::complex<T> b) |
284 | { | 284 | { |
285 | - return rts::complex<T>(a - b.r, -b.i); | 285 | + return rts::complex<T>((T)a - b.r, -b.i); |
286 | } | 286 | } |
287 | 287 | ||
288 | //minus sign | 288 | //minus sign |
@@ -303,23 +303,16 @@ CUDA_CALLABLE static rts::complex<T> operator*(const double a, const rts::comple | @@ -303,23 +303,16 @@ CUDA_CALLABLE static rts::complex<T> operator*(const double a, const rts::comple | ||
303 | template<typename T> | 303 | template<typename T> |
304 | CUDA_CALLABLE static rts::complex<T> operator/(const double a, const rts::complex<T> b) | 304 | CUDA_CALLABLE static rts::complex<T> operator/(const double a, const rts::complex<T> b) |
305 | { | 305 | { |
306 | - //return complex<T>(a * b.r, a * b.i); | ||
307 | rts::complex<T> result; | 306 | rts::complex<T> result; |
308 | 307 | ||
309 | T denom = b.r * b.r + b.i * b.i; | 308 | T denom = b.r * b.r + b.i * b.i; |
310 | 309 | ||
311 | - result.r = (a * b.r) / denom; | ||
312 | - result.i = -(a * b.i) / denom; | 310 | + result.r = ((T)a * b.r) / denom; |
311 | + result.i = -((T)a * b.i) / denom; | ||
313 | 312 | ||
314 | return result; | 313 | return result; |
315 | } | 314 | } |
316 | 315 | ||
317 | -//POW function | ||
318 | -/*template<typename T> | ||
319 | -CUDA_CALLABLE static complex<T> pow(complex<T> x, int y) | ||
320 | -{ | ||
321 | - return x.pow(y); | ||
322 | -}*/ | ||
323 | 316 | ||
324 | template<typename T> | 317 | template<typename T> |
325 | CUDA_CALLABLE static rts::complex<T> pow(rts::complex<T> x, T y) | 318 | CUDA_CALLABLE static rts::complex<T> pow(rts::complex<T> x, T y) |
@@ -374,22 +367,43 @@ CUDA_CALLABLE static T imag(rts::complex<T> a) | @@ -374,22 +367,43 @@ CUDA_CALLABLE static T imag(rts::complex<T> a) | ||
374 | } | 367 | } |
375 | 368 | ||
376 | //trigonometric functions | 369 | //trigonometric functions |
370 | +//template<class A> | ||
371 | +/*CUDA_CALLABLE static rts::complex<float> sinf(const rts::complex<float> x) | ||
372 | +{ | ||
373 | + rts::complex<float> result; | ||
374 | + result.r = sinf(x.r) * coshf(x.i); | ||
375 | + result.i = cosf(x.r) * sinhf(x.i); | ||
376 | + | ||
377 | + return result; | ||
378 | +}*/ | ||
379 | + | ||
377 | template<class A> | 380 | template<class A> |
378 | CUDA_CALLABLE rts::complex<A> sin(const rts::complex<A> x) | 381 | CUDA_CALLABLE rts::complex<A> sin(const rts::complex<A> x) |
379 | { | 382 | { |
380 | rts::complex<A> result; | 383 | rts::complex<A> result; |
381 | - result.r = std::sin(x.r) * std::cosh(x.i); | ||
382 | - result.i = std::cos(x.r) * std::sinh(x.i); | 384 | + result.r = (A)std::sin(x.r) * (A)std::cosh(x.i); |
385 | + result.i = (A)std::cos(x.r) * (A)std::sinh(x.i); | ||
383 | 386 | ||
384 | return result; | 387 | return result; |
385 | } | 388 | } |
386 | 389 | ||
390 | +//floating point template | ||
391 | +//template<class A> | ||
392 | +/*CUDA_CALLABLE static rts::complex<float> cosf(const rts::complex<float> x) | ||
393 | +{ | ||
394 | + rts::complex<float> result; | ||
395 | + result.r = cosf(x.r) * coshf(x.i); | ||
396 | + result.i = -(sinf(x.r) * sinhf(x.i)); | ||
397 | + | ||
398 | + return result; | ||
399 | +}*/ | ||
400 | + | ||
387 | template<class A> | 401 | template<class A> |
388 | CUDA_CALLABLE rts::complex<A> cos(const rts::complex<A> x) | 402 | CUDA_CALLABLE rts::complex<A> cos(const rts::complex<A> x) |
389 | { | 403 | { |
390 | rts::complex<A> result; | 404 | rts::complex<A> result; |
391 | - result.r = std::cos(x.r) * std::cosh(x.i); | ||
392 | - result.i = -(std::sin(x.r) * std::sinh(x.i)); | 405 | + result.r = (A)std::cos(x.r) * (A)std::cosh(x.i); |
406 | + result.i = -((A)std::sin(x.r) * (A)std::sinh(x.i)); | ||
393 | 407 | ||
394 | return result; | 408 | return result; |
395 | } | 409 | } |
math/quad.h
@@ -192,7 +192,7 @@ struct quad | @@ -192,7 +192,7 @@ struct quad | ||
192 | T dc = (A+Y - p).len(); | 192 | T dc = (A+Y - p).len(); |
193 | T dd = (A+X+Y - p).len(); | 193 | T dd = (A+X+Y - p).len(); |
194 | 194 | ||
195 | - return fmax( da, fmax(db, fmax(dc, dd) ) ); | 195 | + return std::max( da, std::max(db, std::max(dc, dd) ) ); |
196 | } | 196 | } |
197 | }; | 197 | }; |
198 | 198 |
math/spherical_bessel.h
@@ -5,20 +5,20 @@ | @@ -5,20 +5,20 @@ | ||
5 | 5 | ||
6 | namespace rts{ | 6 | namespace rts{ |
7 | 7 | ||
8 | -#define RTS_BESSEL_CONVERGENCE_MIN 0.0145 | ||
9 | -#define RTS_BESSEL_CONVERGENCE_MAX 0.4 | ||
10 | -#define RTS_BESSEL_MAXIMUM_FLOAT -1e33 | 8 | +#define RTS_BESSEL_CONVERGENCE_MIN 0.0145f |
9 | +#define RTS_BESSEL_CONVERGENCE_MAX 0.4f | ||
10 | +#define RTS_BESSEL_MAXIMUM_FLOAT -1e33f | ||
11 | 11 | ||
12 | template <typename T> | 12 | template <typename T> |
13 | CUDA_CALLABLE void sbesselj(int n, complex<T> x, complex<T>* j) | 13 | CUDA_CALLABLE void sbesselj(int n, complex<T> x, complex<T>* j) |
14 | { | 14 | { |
15 | //compute the first bessel function | 15 | //compute the first bessel function |
16 | if(n >= 0) | 16 | if(n >= 0) |
17 | - j[0] = sin(x) / x; | 17 | + j[0] = (T)sin(x) / x; |
18 | 18 | ||
19 | //compute the second bessel function | 19 | //compute the second bessel function |
20 | if(n >= 1) | 20 | if(n >= 1) |
21 | - j[1] = j[0] / x - cos(x) / x; | 21 | + j[1] = j[0] / x - (T)cos(x) / x; |
22 | 22 | ||
23 | //use the recurrence relation to compute the rest | 23 | //use the recurrence relation to compute the rest |
24 | for(int i = 2; i <= n; i++) | 24 | for(int i = 2; i <= n; i++) |
@@ -40,11 +40,11 @@ CUDA_CALLABLE void sbessely(int n, complex<T> x, complex<T>* y) | @@ -40,11 +40,11 @@ CUDA_CALLABLE void sbessely(int n, complex<T> x, complex<T>* y) | ||
40 | { | 40 | { |
41 | //compute the first bessel function | 41 | //compute the first bessel function |
42 | if(n >= 0) | 42 | if(n >= 0) |
43 | - y[0] = -cos(x) / x; | 43 | + y[0] = -(T)cos(x) / x; |
44 | 44 | ||
45 | //compute the second bessel function | 45 | //compute the second bessel function |
46 | if(n >= 1) | 46 | if(n >= 1) |
47 | - y[1] = y[0] / x - sin(x) / x; | 47 | + y[1] = y[0] / x - (T)sin(x) / x; |
48 | 48 | ||
49 | //use the recurrence relation to compute the rest | 49 | //use the recurrence relation to compute the rest |
50 | for(int i = 2; i <= n; i++) | 50 | for(int i = 2; i <= n; i++) |
@@ -85,18 +85,18 @@ template <typename T> | @@ -85,18 +85,18 @@ template <typename T> | ||
85 | CUDA_CALLABLE void init_sbesselj(T x, T* j) | 85 | CUDA_CALLABLE void init_sbesselj(T x, T* j) |
86 | { | 86 | { |
87 | //compute the first 2 bessel functions | 87 | //compute the first 2 bessel functions |
88 | - j[0] = sin(x) / x; | 88 | + j[0] = (T)sin(x) / x; |
89 | 89 | ||
90 | - j[1] = j[0] / x - cos(x) / x; | 90 | + j[1] = j[0] / x - (T)cos(x) / x; |
91 | } | 91 | } |
92 | 92 | ||
93 | template <typename T> | 93 | template <typename T> |
94 | CUDA_CALLABLE void init_sbessely(T x, T* y) | 94 | CUDA_CALLABLE void init_sbessely(T x, T* y) |
95 | { | 95 | { |
96 | //compute the first 2 bessel functions | 96 | //compute the first 2 bessel functions |
97 | - y[0] = -cos(x) / x; | 97 | + y[0] = -(T)cos(x) / x; |
98 | 98 | ||
99 | - y[1] = y[0] / x - sin(x) / x; | 99 | + y[1] = y[0] / x - (T)sin(x) / x; |
100 | } | 100 | } |
101 | 101 | ||
102 | template <typename T> | 102 | template <typename T> |
optics/material.h
@@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
11 | #include "rts/math/complex.h" | 11 | #include "rts/math/complex.h" |
12 | #include "rts/math/function.h" | 12 | #include "rts/math/function.h" |
13 | 13 | ||
14 | -#define PI 3.14159 | 14 | +#define PI 3.14159f |
15 | 15 | ||
16 | namespace rts{ | 16 | namespace rts{ |
17 | 17 | ||
@@ -144,6 +144,8 @@ namespace rts{ | @@ -144,6 +144,8 @@ namespace rts{ | ||
144 | case field_A: | 144 | case field_A: |
145 | newRI.n.imag(_A(val * scaleA, newRI.lambda)); | 145 | newRI.n.imag(_A(val * scaleA, newRI.lambda)); |
146 | break; | 146 | break; |
147 | + default: | ||
148 | + break; | ||
147 | } | 149 | } |
148 | } | 150 | } |
149 | 151 |
1 | +#ifndef RTS_ARGUMENTS | ||
2 | +#define RTS_ARGUMENTS | ||
3 | + | ||
4 | +#include <string> | ||
5 | +#include <vector> | ||
6 | +#include <iostream> | ||
7 | +#include <iomanip> | ||
8 | +#include <sstream> | ||
9 | +#include <iterator> | ||
10 | +#include <algorithm> | ||
11 | + | ||
12 | +#ifdef _WIN32 | ||
13 | +#include <Windows.h> | ||
14 | +#endif | ||
15 | + | ||
16 | +namespace rts{ | ||
17 | + | ||
18 | + class argument | ||
19 | + { | ||
20 | + private: | ||
21 | + bool ansi; | ||
22 | + | ||
23 | + //argument name | ||
24 | + std::string name; | ||
25 | + | ||
26 | + //description of the argument | ||
27 | + std::vector<std::string> desc; | ||
28 | + | ||
29 | + //argument values | ||
30 | + std::vector<std::string> vals; | ||
31 | + | ||
32 | + //range or example | ||
33 | + std::string range; | ||
34 | + | ||
35 | + //flag is true when the argument is user-specified | ||
36 | + bool flag; | ||
37 | + | ||
38 | + void parse_val(const std::string &s){ | ||
39 | + | ||
40 | + vals.clear(); | ||
41 | + | ||
42 | + std::stringstream ss(s); | ||
43 | + std::string item; | ||
44 | + while (std::getline(ss, item, ' ')) { | ||
45 | + vals.push_back(item); | ||
46 | + } | ||
47 | + } | ||
48 | + | ||
49 | + void parse_desc(const std::string &s){ | ||
50 | + | ||
51 | + desc.clear(); | ||
52 | + | ||
53 | + std::stringstream ss(s); | ||
54 | + std::string item; | ||
55 | + while (std::getline(ss, item, '\n')) { | ||
56 | + desc.push_back(item); | ||
57 | + } | ||
58 | + } | ||
59 | + | ||
60 | + public: | ||
61 | + void set_ansi(bool b){ ansi = b; } | ||
62 | + //create an argument with a given name, description, and default value | ||
63 | + argument(std::string _name, std::string _desc, std::string _default = "", std::string _range = "") | ||
64 | + { | ||
65 | + name = _name; | ||
66 | + parse_desc(_desc); | ||
67 | + parse_val(_default); | ||
68 | + | ||
69 | + //if a default value is provided, set the flag | ||
70 | + if(_default != "") | ||
71 | + flag = true; | ||
72 | + else flag = false; | ||
73 | + | ||
74 | + range = _range; | ||
75 | + | ||
76 | + | ||
77 | + } | ||
78 | + | ||
79 | + int nargs() | ||
80 | + { | ||
81 | + return vals.size(); | ||
82 | + } | ||
83 | + | ||
84 | + //return the value of a text argument | ||
85 | + std::string as_text(int n = 0) | ||
86 | + { | ||
87 | + if(!flag) | ||
88 | + { | ||
89 | + std::cout<<"ERROR - Argument requested without being set: "<<name<<std::endl; | ||
90 | + exit(1); | ||
91 | + } | ||
92 | + | ||
93 | + if(vals.size() > n) | ||
94 | + return vals[n]; | ||
95 | + | ||
96 | + else return ""; | ||
97 | + } | ||
98 | + | ||
99 | + //return the value of a floating point argument | ||
100 | + float as_float(int n = 0) | ||
101 | + { | ||
102 | + if(!flag) | ||
103 | + { | ||
104 | + std::cout<<"ERROR - Argument requested without being set: "<<name<<std::endl; | ||
105 | + exit(1); | ||
106 | + } | ||
107 | + | ||
108 | + if(vals.size() > n) | ||
109 | + { | ||
110 | + float r; | ||
111 | + if ( ! (istringstream(vals[n]) >> r) ) r = 0; | ||
112 | + return r; | ||
113 | + } | ||
114 | + | ||
115 | + else return 0; | ||
116 | + } | ||
117 | + | ||
118 | + //return the value of an integer argument | ||
119 | + int as_int(int n = 0) | ||
120 | + { | ||
121 | + if(!flag) | ||
122 | + { | ||
123 | + std::cout<<"ERROR - Argument requested without being set: "<<name<<std::endl; | ||
124 | + exit(1); | ||
125 | + } | ||
126 | + | ||
127 | + if(vals.size() > n) | ||
128 | + { | ||
129 | + int r; | ||
130 | + if ( ! (istringstream(vals[n]) >> r) ) r = 0; | ||
131 | + return r; | ||
132 | + } | ||
133 | + | ||
134 | + else return 0; | ||
135 | + } | ||
136 | + | ||
137 | + //get the width of the left column | ||
138 | + int col_width() | ||
139 | + { | ||
140 | + int n = 3; | ||
141 | + //add the length of the argument name | ||
142 | + n += name.size(); | ||
143 | + | ||
144 | + //if there are any default parameters | ||
145 | + if(vals.size() > 0) | ||
146 | + { | ||
147 | + //padding (parenthesis, =, etc.) | ||
148 | + n += 6; | ||
149 | + | ||
150 | + //for each default argument value | ||
151 | + for(int v=0; v<vals.size(); v++) | ||
152 | + n += vals[v].size() + 1; | ||
153 | + } | ||
154 | + | ||
155 | + //add a buffer of 4 characters | ||
156 | + n += 4; | ||
157 | + | ||
158 | + return n; | ||
159 | + } | ||
160 | + | ||
161 | + | ||
162 | + //string output | ||
163 | + std::string toStr(int width = 0) | ||
164 | + { | ||
165 | + std::stringstream ss; | ||
166 | + | ||
167 | + int color_size = 0; | ||
168 | + | ||
169 | + | ||
170 | + //create the left column | ||
171 | + std::string left_part = std::string(" --") + name; | ||
172 | + if(vals.size() != 0) | ||
173 | + { | ||
174 | + if(ansi) | ||
175 | + left_part += "\033[1;32m"; | ||
176 | + left_part += " ( = "; | ||
177 | + for(int v=0; v<vals.size(); v++) | ||
178 | + left_part += vals[v] + std::string(" "); | ||
179 | + left_part += ")"; | ||
180 | + if(ansi) | ||
181 | + left_part += "\033[0m"; | ||
182 | + if(ansi) | ||
183 | + color_size = 11; | ||
184 | + } | ||
185 | + else | ||
186 | + color_size = 0; | ||
187 | + | ||
188 | + //if no width is passed, put 4 spaces between left and right columns | ||
189 | + if(width == 0) width = col_width(); | ||
190 | + | ||
191 | + ss<<std::left<<std::setw(width + color_size)<<left_part; | ||
192 | + | ||
193 | + //output right column | ||
194 | + for(int d=0; d<desc.size(); d++) | ||
195 | + { | ||
196 | + if(d == 0) | ||
197 | + ss<<desc[0]; | ||
198 | + else | ||
199 | + ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<desc[d]; | ||
200 | + | ||
201 | + } | ||
202 | + | ||
203 | + //output the range in the right column | ||
204 | + if(range != "" && ansi) | ||
205 | + ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<" "<<std::string("\033[1;36m") + range + "\033[0m"; | ||
206 | + else if(range != "") | ||
207 | + ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<" "<<range; | ||
208 | + | ||
209 | + return ss.str(); | ||
210 | + } | ||
211 | + | ||
212 | + //compare the name of the argument to a string | ||
213 | + bool operator==(std::string rhs) | ||
214 | + { | ||
215 | + return (name == rhs); | ||
216 | + } | ||
217 | + | ||
218 | + //set the argument to a given value | ||
219 | + void set(std::string _value) | ||
220 | + { | ||
221 | + parse_val(_value); | ||
222 | + | ||
223 | + //set the flag | ||
224 | + flag = true; | ||
225 | + } | ||
226 | + | ||
227 | + bool is_set() | ||
228 | + { | ||
229 | + return flag; | ||
230 | + } | ||
231 | + | ||
232 | + }; | ||
233 | + | ||
234 | + struct argsection | ||
235 | + { | ||
236 | + std::string name; | ||
237 | + unsigned int index; | ||
238 | + }; | ||
239 | + | ||
240 | + class arglist | ||
241 | + { | ||
242 | + private: | ||
243 | + bool ansi; | ||
244 | + | ||
245 | + //vector of arguments | ||
246 | + std::vector<argument> args; | ||
247 | + | ||
248 | + //column width of the longest argument | ||
249 | + int col_width; | ||
250 | + | ||
251 | + //list of sections | ||
252 | + std::vector<argsection> sections; | ||
253 | + | ||
254 | + public: | ||
255 | + | ||
256 | + arglist(){ col_width = 0; } | ||
257 | + | ||
258 | + void set_ansi(bool b) | ||
259 | + { | ||
260 | + ansi = b; | ||
261 | + for(int i=0; i<args.size(); i++) | ||
262 | + args[i].set_ansi(ansi); | ||
263 | + } | ||
264 | + | ||
265 | + void add(std::string _name, std::string _desc, std::string _default = "", std::string _range = "") | ||
266 | + { | ||
267 | + argument arg(_name, _desc, _default, _range); | ||
268 | + arg.set_ansi(ansi); | ||
269 | + args.push_back(arg); | ||
270 | + | ||
271 | + col_width = std::max<int>(col_width, arg.col_width()); | ||
272 | + } | ||
273 | + | ||
274 | + void section(std::string _name) | ||
275 | + { | ||
276 | + argsection s; | ||
277 | + s.name = _name; | ||
278 | + s.index = args.size(); | ||
279 | + sections.push_back(s); | ||
280 | + } | ||
281 | + | ||
282 | + //output the arguments (generally in response to --help) | ||
283 | + std::string toStr() | ||
284 | + { | ||
285 | + std::stringstream ss; | ||
286 | + | ||
287 | + int si = -1; | ||
288 | + | ||
289 | + if(sections.size() > 0) | ||
290 | + si = 0; | ||
291 | + | ||
292 | + //for each argument | ||
293 | + for(int a=0; a<args.size(); a++) | ||
294 | + { | ||
295 | + if(si != -1 && a == sections[si].index) | ||
296 | + { | ||
297 | + if(ansi) | ||
298 | + ss<<std::endl<<std::left<<setfill('=')<<setw(col_width)<<std::string("\033[1;31m") + sections[si].name<<"\033[0m"<<std::endl; | ||
299 | + else | ||
300 | + ss<<std::endl<<std::left<<setfill('=')<<setw(col_width)<<sections[si].name<<std::endl; | ||
301 | + si++; | ||
302 | + if(si == sections.size()) si = -1; | ||
303 | + } | ||
304 | + | ||
305 | + ss<<args[a].toStr(col_width)<<std::endl; | ||
306 | + } | ||
307 | + | ||
308 | + return ss.str(); | ||
309 | + } | ||
310 | + | ||
311 | + int index(std::string _name) | ||
312 | + { | ||
313 | + int i = find(args.begin(), args.end(), _name) - args.begin(); | ||
314 | + | ||
315 | + if(i >= args.size()) | ||
316 | + i = -1; | ||
317 | + | ||
318 | + return i; | ||
319 | + } | ||
320 | + | ||
321 | + void set(std::string _name, std::string _value) | ||
322 | + { | ||
323 | + int i = index(_name); | ||
324 | + | ||
325 | + if(i != -1) | ||
326 | + { | ||
327 | + args[i].set(_value); | ||
328 | + //adjust the column width if necessary | ||
329 | + col_width = max(col_width, args[i].col_width()); | ||
330 | + } | ||
331 | + else | ||
332 | + std::cout<<"ERROR - Argument not recognized: "<<_name<<std::endl; | ||
333 | + } | ||
334 | + | ||
335 | + //parse a parameter string | ||
336 | + void parse(int argc, char* argv[]) | ||
337 | + { | ||
338 | + //if the number of arguments is 1, we're done | ||
339 | + if(argc <= 1) return; | ||
340 | + | ||
341 | + std::string name; | ||
342 | + std::string params; | ||
343 | + | ||
344 | + for(int i=1; i<argc; i++) | ||
345 | + { | ||
346 | + //if the argument is a parameter name | ||
347 | + if(argv[i][0] == '-' && argv[i][1] == '-') | ||
348 | + { | ||
349 | + //add any previous arguments | ||
350 | + if(name != "") | ||
351 | + set(name, params); | ||
352 | + //set the current argument to this name | ||
353 | + name = argv[i]+2; | ||
354 | + //clear the parameters list | ||
355 | + params = ""; | ||
356 | + } | ||
357 | + else | ||
358 | + { | ||
359 | + if(params != "") | ||
360 | + params += " "; | ||
361 | + params += argv[i]; | ||
362 | + } | ||
363 | + } | ||
364 | + | ||
365 | + //set the last argument | ||
366 | + set(name, params); | ||
367 | + } | ||
368 | + | ||
369 | + //determine if a parameter has been set (either specified by the user or with a default value) | ||
370 | + bool operator()(std::string _name) | ||
371 | + { | ||
372 | + int i = find(args.begin(), args.end(), _name) - args.begin(); | ||
373 | + | ||
374 | + if(i < 0) | ||
375 | + { | ||
376 | + std::cout<<"ERROR - Unspecified parameter name: "<<_name<<std::endl; | ||
377 | + exit(1); | ||
378 | + } | ||
379 | + | ||
380 | + return args[i].is_set(); | ||
381 | + } | ||
382 | + | ||
383 | + int nargs(std::string _name) | ||
384 | + { | ||
385 | + int i = find(args.begin(), args.end(), _name) - args.begin(); | ||
386 | + | ||
387 | + if(i < 0) | ||
388 | + { | ||
389 | + std::cout<<"ERROR - Unspecified parameter name: "<<_name<<std::endl; | ||
390 | + exit(1); | ||
391 | + } | ||
392 | + | ||
393 | + return args[i].nargs(); | ||
394 | + } | ||
395 | + | ||
396 | + argument operator[](std::string _name) | ||
397 | + { | ||
398 | + int i = find(args.begin(), args.end(), _name) - args.begin(); | ||
399 | + | ||
400 | + if(i < 0) | ||
401 | + { | ||
402 | + std::cout<<"ERROR - Unspecified parameter name: "<<_name<<std::endl; | ||
403 | + exit(1); | ||
404 | + } | ||
405 | + | ||
406 | + return args[i]; | ||
407 | + } | ||
408 | + | ||
409 | + | ||
410 | + }; | ||
411 | + | ||
412 | + | ||
413 | + | ||
414 | +} //end namespace rts | ||
415 | + | ||
416 | +#endif |