max@0
|
1 // Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
|
max@0
|
2 // Copyright (C) 2008-2010 Conrad Sanderson
|
max@0
|
3 //
|
max@0
|
4 // This file is part of the Armadillo C++ library.
|
max@0
|
5 // It is provided without any warranty of fitness
|
max@0
|
6 // for any purpose. You can redistribute this file
|
max@0
|
7 // and/or modify it under the terms of the GNU
|
max@0
|
8 // Lesser General Public License (LGPL) as published
|
max@0
|
9 // by the Free Software Foundation, either version 3
|
max@0
|
10 // of the License or (at your option) any later version.
|
max@0
|
11 // (see http://www.opensource.org/licenses for more info)
|
max@0
|
12
|
max@0
|
13
|
max@0
|
14 //! \addtogroup format_wrap
|
max@0
|
15 //! @{
|
max@0
|
16
|
max@0
|
17
|
max@0
|
18 //! \namespace arma_boost namespace for functions and classes which partially emulate Boost functionality
|
max@0
|
19 namespace arma_boost
|
max@0
|
20 {
|
max@0
|
21
|
max@0
|
22 #if defined(ARMA_USE_BOOST_FORMAT)
|
max@0
|
23
|
max@0
|
24 using boost::format;
|
max@0
|
25 using boost::basic_format;
|
max@0
|
26 using boost::str;
|
max@0
|
27
|
max@0
|
28 #else
|
max@0
|
29
|
max@0
|
30 #if defined(ARMA_HAVE_STD_SNPRINTF)
|
max@0
|
31
|
max@0
|
32 #define arma_snprintf std::snprintf
|
max@0
|
33
|
max@0
|
34 #else
|
max@0
|
35
|
max@0
|
36 // better-than-nothing emulation of C99 snprintf(),
|
max@0
|
37 // with correct return value and null-terminated output string.
|
max@0
|
38 // note that _snprintf() provided by MS is not a good substitute for snprintf()
|
max@0
|
39
|
max@0
|
40 inline
|
max@0
|
41 int
|
max@0
|
42 arma_snprintf(char* out, size_t size, const char* fmt, ...)
|
max@0
|
43 {
|
max@0
|
44 size_t i;
|
max@0
|
45
|
max@0
|
46 for(i=0; i<size; ++i)
|
max@0
|
47 {
|
max@0
|
48 out[i] = fmt[i];
|
max@0
|
49 if(fmt[i] == char(0))
|
max@0
|
50 break;
|
max@0
|
51 }
|
max@0
|
52
|
max@0
|
53 if(size > 0)
|
max@0
|
54 out[size-1] = char(0);
|
max@0
|
55
|
max@0
|
56 return int(i);
|
max@0
|
57 }
|
max@0
|
58
|
max@0
|
59 #endif
|
max@0
|
60
|
max@0
|
61 class format
|
max@0
|
62 {
|
max@0
|
63 public:
|
max@0
|
64
|
max@0
|
65 format(const char* in_fmt)
|
max@0
|
66 : A(in_fmt)
|
max@0
|
67 {
|
max@0
|
68 }
|
max@0
|
69
|
max@0
|
70 format(const std::string& in_fmt)
|
max@0
|
71 : A(in_fmt)
|
max@0
|
72 {
|
max@0
|
73 }
|
max@0
|
74
|
max@0
|
75
|
max@0
|
76 const std::string A;
|
max@0
|
77
|
max@0
|
78 private:
|
max@0
|
79 format();
|
max@0
|
80 };
|
max@0
|
81
|
max@0
|
82
|
max@0
|
83
|
max@0
|
84 template<typename T1, typename T2>
|
max@0
|
85 class basic_format
|
max@0
|
86 {
|
max@0
|
87 public:
|
max@0
|
88
|
max@0
|
89 basic_format(const T1& in_A, const T2& in_B)
|
max@0
|
90 : A(in_A)
|
max@0
|
91 , B(in_B)
|
max@0
|
92 {
|
max@0
|
93 }
|
max@0
|
94
|
max@0
|
95 const T1& A;
|
max@0
|
96 const T2& B;
|
max@0
|
97
|
max@0
|
98 private:
|
max@0
|
99 basic_format();
|
max@0
|
100 };
|
max@0
|
101
|
max@0
|
102
|
max@0
|
103
|
max@0
|
104 template<typename T2>
|
max@0
|
105 inline
|
max@0
|
106 basic_format< format, T2 >
|
max@0
|
107 operator% (const format& X, const T2& arg)
|
max@0
|
108 {
|
max@0
|
109 return basic_format< format, T2 >(X, arg);
|
max@0
|
110 }
|
max@0
|
111
|
max@0
|
112
|
max@0
|
113
|
max@0
|
114 template<typename T1, typename T2, typename T3>
|
max@0
|
115 inline
|
max@0
|
116 basic_format< basic_format<T1,T2>, T3 >
|
max@0
|
117 operator% (const basic_format<T1,T2>& X, const T3& arg)
|
max@0
|
118 {
|
max@0
|
119 return basic_format< basic_format<T1,T2>, T3 >(X, arg);
|
max@0
|
120 }
|
max@0
|
121
|
max@0
|
122
|
max@0
|
123
|
max@0
|
124 template<typename T2>
|
max@0
|
125 inline
|
max@0
|
126 std::string
|
max@0
|
127 str(const basic_format< format, T2>& X)
|
max@0
|
128 {
|
max@0
|
129 char local_buffer[1024];
|
max@0
|
130 char* buffer = local_buffer;
|
max@0
|
131
|
max@0
|
132 int buffer_size = 1024;
|
max@0
|
133 int required_size = buffer_size;
|
max@0
|
134
|
max@0
|
135 bool using_local_buffer = true;
|
max@0
|
136
|
max@0
|
137 std::string out;
|
max@0
|
138
|
max@0
|
139 do
|
max@0
|
140 {
|
max@0
|
141 if(using_local_buffer == false)
|
max@0
|
142 {
|
max@0
|
143 buffer = new char[buffer_size];
|
max@0
|
144 }
|
max@0
|
145
|
max@0
|
146 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B);
|
max@0
|
147
|
max@0
|
148 if(required_size < buffer_size)
|
max@0
|
149 {
|
max@0
|
150 if(required_size > 0)
|
max@0
|
151 {
|
max@0
|
152 out = buffer;
|
max@0
|
153 }
|
max@0
|
154 }
|
max@0
|
155 else
|
max@0
|
156 {
|
max@0
|
157 buffer_size *= 2;
|
max@0
|
158 }
|
max@0
|
159
|
max@0
|
160 if(using_local_buffer == true)
|
max@0
|
161 {
|
max@0
|
162 using_local_buffer = false;
|
max@0
|
163 }
|
max@0
|
164 else
|
max@0
|
165 {
|
max@0
|
166 delete[] buffer;
|
max@0
|
167 }
|
max@0
|
168
|
max@0
|
169 } while( (required_size >= buffer_size) );
|
max@0
|
170
|
max@0
|
171 return out;
|
max@0
|
172 }
|
max@0
|
173
|
max@0
|
174
|
max@0
|
175
|
max@0
|
176 template<typename T2, typename T3>
|
max@0
|
177 inline
|
max@0
|
178 std::string
|
max@0
|
179 str(const basic_format< basic_format< format, T2>, T3>& X)
|
max@0
|
180 {
|
max@0
|
181 char local_buffer[1024];
|
max@0
|
182 char* buffer = local_buffer;
|
max@0
|
183
|
max@0
|
184 int buffer_size = 1024;
|
max@0
|
185 int required_size = buffer_size;
|
max@0
|
186
|
max@0
|
187 bool using_local_buffer = true;
|
max@0
|
188
|
max@0
|
189 std::string out;
|
max@0
|
190
|
max@0
|
191 do
|
max@0
|
192 {
|
max@0
|
193 if(using_local_buffer == false)
|
max@0
|
194 {
|
max@0
|
195 buffer = new char[buffer_size];
|
max@0
|
196 }
|
max@0
|
197
|
max@0
|
198 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B);
|
max@0
|
199
|
max@0
|
200 if(required_size < buffer_size)
|
max@0
|
201 {
|
max@0
|
202 if(required_size > 0)
|
max@0
|
203 {
|
max@0
|
204 out = buffer;
|
max@0
|
205 }
|
max@0
|
206 }
|
max@0
|
207 else
|
max@0
|
208 {
|
max@0
|
209 buffer_size *= 2;
|
max@0
|
210 }
|
max@0
|
211
|
max@0
|
212 if(using_local_buffer == true)
|
max@0
|
213 {
|
max@0
|
214 using_local_buffer = false;
|
max@0
|
215 }
|
max@0
|
216 else
|
max@0
|
217 {
|
max@0
|
218 delete[] buffer;
|
max@0
|
219 }
|
max@0
|
220
|
max@0
|
221 } while( (required_size >= buffer_size) );
|
max@0
|
222
|
max@0
|
223 return out;
|
max@0
|
224 }
|
max@0
|
225
|
max@0
|
226
|
max@0
|
227
|
max@0
|
228 template<typename T2, typename T3, typename T4>
|
max@0
|
229 inline
|
max@0
|
230 std::string
|
max@0
|
231 str(const basic_format< basic_format< basic_format< format, T2>, T3>, T4>& X)
|
max@0
|
232 {
|
max@0
|
233 char local_buffer[1024];
|
max@0
|
234 char* buffer = local_buffer;
|
max@0
|
235
|
max@0
|
236 int buffer_size = 1024;
|
max@0
|
237 int required_size = buffer_size;
|
max@0
|
238
|
max@0
|
239 bool using_local_buffer = true;
|
max@0
|
240
|
max@0
|
241 std::string out;
|
max@0
|
242
|
max@0
|
243 do
|
max@0
|
244 {
|
max@0
|
245 if(using_local_buffer == false)
|
max@0
|
246 {
|
max@0
|
247 buffer = new char[buffer_size];
|
max@0
|
248 }
|
max@0
|
249
|
max@0
|
250 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B);
|
max@0
|
251
|
max@0
|
252 if(required_size < buffer_size)
|
max@0
|
253 {
|
max@0
|
254 if(required_size > 0)
|
max@0
|
255 {
|
max@0
|
256 out = buffer;
|
max@0
|
257 }
|
max@0
|
258 }
|
max@0
|
259 else
|
max@0
|
260 {
|
max@0
|
261 buffer_size *= 2;
|
max@0
|
262 }
|
max@0
|
263
|
max@0
|
264 if(using_local_buffer == true)
|
max@0
|
265 {
|
max@0
|
266 using_local_buffer = false;
|
max@0
|
267 }
|
max@0
|
268 else
|
max@0
|
269 {
|
max@0
|
270 delete[] buffer;
|
max@0
|
271 }
|
max@0
|
272
|
max@0
|
273 } while( (required_size >= buffer_size) );
|
max@0
|
274
|
max@0
|
275 return out;
|
max@0
|
276 }
|
max@0
|
277
|
max@0
|
278
|
max@0
|
279
|
max@0
|
280 template<typename T2, typename T3, typename T4, typename T5>
|
max@0
|
281 inline
|
max@0
|
282 std::string
|
max@0
|
283 str(const basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>& X)
|
max@0
|
284 {
|
max@0
|
285 char local_buffer[1024];
|
max@0
|
286 char* buffer = local_buffer;
|
max@0
|
287
|
max@0
|
288 int buffer_size = 1024;
|
max@0
|
289 int required_size = buffer_size;
|
max@0
|
290
|
max@0
|
291 bool using_local_buffer = true;
|
max@0
|
292
|
max@0
|
293 std::string out;
|
max@0
|
294
|
max@0
|
295 do
|
max@0
|
296 {
|
max@0
|
297 if(using_local_buffer == false)
|
max@0
|
298 {
|
max@0
|
299 buffer = new char[buffer_size];
|
max@0
|
300 }
|
max@0
|
301
|
max@0
|
302 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B);
|
max@0
|
303
|
max@0
|
304 if(required_size < buffer_size)
|
max@0
|
305 {
|
max@0
|
306 if(required_size > 0)
|
max@0
|
307 {
|
max@0
|
308 out = buffer;
|
max@0
|
309 }
|
max@0
|
310 }
|
max@0
|
311 else
|
max@0
|
312 {
|
max@0
|
313 buffer_size *= 2;
|
max@0
|
314 }
|
max@0
|
315
|
max@0
|
316 if(using_local_buffer == true)
|
max@0
|
317 {
|
max@0
|
318 using_local_buffer = false;
|
max@0
|
319 }
|
max@0
|
320 else
|
max@0
|
321 {
|
max@0
|
322 delete[] buffer;
|
max@0
|
323 }
|
max@0
|
324
|
max@0
|
325 } while( (required_size >= buffer_size) );
|
max@0
|
326
|
max@0
|
327 return out;
|
max@0
|
328 }
|
max@0
|
329
|
max@0
|
330
|
max@0
|
331
|
max@0
|
332 template<typename T2, typename T3, typename T4, typename T5, typename T6>
|
max@0
|
333 inline
|
max@0
|
334 std::string
|
max@0
|
335 str(const basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>& X)
|
max@0
|
336 {
|
max@0
|
337 char local_buffer[1024];
|
max@0
|
338 char* buffer = local_buffer;
|
max@0
|
339
|
max@0
|
340 int buffer_size = 1024;
|
max@0
|
341 int required_size = buffer_size;
|
max@0
|
342
|
max@0
|
343 bool using_local_buffer = true;
|
max@0
|
344
|
max@0
|
345 std::string out;
|
max@0
|
346
|
max@0
|
347 do
|
max@0
|
348 {
|
max@0
|
349 if(using_local_buffer == false)
|
max@0
|
350 {
|
max@0
|
351 buffer = new char[buffer_size];
|
max@0
|
352 }
|
max@0
|
353
|
max@0
|
354 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B);
|
max@0
|
355
|
max@0
|
356 if(required_size < buffer_size)
|
max@0
|
357 {
|
max@0
|
358 if(required_size > 0)
|
max@0
|
359 {
|
max@0
|
360 out = buffer;
|
max@0
|
361 }
|
max@0
|
362 }
|
max@0
|
363 else
|
max@0
|
364 {
|
max@0
|
365 buffer_size *= 2;
|
max@0
|
366 }
|
max@0
|
367
|
max@0
|
368 if(using_local_buffer == true)
|
max@0
|
369 {
|
max@0
|
370 using_local_buffer = false;
|
max@0
|
371 }
|
max@0
|
372 else
|
max@0
|
373 {
|
max@0
|
374 delete[] buffer;
|
max@0
|
375 }
|
max@0
|
376
|
max@0
|
377 } while( (required_size >= buffer_size) );
|
max@0
|
378
|
max@0
|
379 return out;
|
max@0
|
380 }
|
max@0
|
381
|
max@0
|
382
|
max@0
|
383
|
max@0
|
384 template<typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
max@0
|
385 inline
|
max@0
|
386 std::string
|
max@0
|
387 str(const basic_format< basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>, T7>& X)
|
max@0
|
388 {
|
max@0
|
389 char local_buffer[1024];
|
max@0
|
390 char* buffer = local_buffer;
|
max@0
|
391
|
max@0
|
392 int buffer_size = 1024;
|
max@0
|
393 int required_size = buffer_size;
|
max@0
|
394
|
max@0
|
395 bool using_local_buffer = true;
|
max@0
|
396
|
max@0
|
397 std::string out;
|
max@0
|
398
|
max@0
|
399 do
|
max@0
|
400 {
|
max@0
|
401 if(using_local_buffer == false)
|
max@0
|
402 {
|
max@0
|
403 buffer = new char[buffer_size];
|
max@0
|
404 }
|
max@0
|
405
|
max@0
|
406 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.A.c_str(), X.A.A.A.A.A.B, X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B);
|
max@0
|
407
|
max@0
|
408 if(required_size < buffer_size)
|
max@0
|
409 {
|
max@0
|
410 if(required_size > 0)
|
max@0
|
411 {
|
max@0
|
412 out = buffer;
|
max@0
|
413 }
|
max@0
|
414 }
|
max@0
|
415 else
|
max@0
|
416 {
|
max@0
|
417 buffer_size *= 2;
|
max@0
|
418 }
|
max@0
|
419
|
max@0
|
420 if(using_local_buffer == true)
|
max@0
|
421 {
|
max@0
|
422 using_local_buffer = false;
|
max@0
|
423 }
|
max@0
|
424 else
|
max@0
|
425 {
|
max@0
|
426 delete[] buffer;
|
max@0
|
427 }
|
max@0
|
428
|
max@0
|
429 } while( (required_size >= buffer_size) );
|
max@0
|
430
|
max@0
|
431 return out;
|
max@0
|
432 }
|
max@0
|
433
|
max@0
|
434
|
max@0
|
435
|
max@0
|
436 template<typename T1>
|
max@0
|
437 struct format_metaprog
|
max@0
|
438 {
|
max@0
|
439 static const uword depth = 0;
|
max@0
|
440
|
max@0
|
441 inline
|
max@0
|
442 static
|
max@0
|
443 const std::string&
|
max@0
|
444 get_fmt(const T1& X)
|
max@0
|
445 {
|
max@0
|
446 return X.A;
|
max@0
|
447 }
|
max@0
|
448 };
|
max@0
|
449
|
max@0
|
450
|
max@0
|
451
|
max@0
|
452 //template<>
|
max@0
|
453 template<typename T1, typename T2>
|
max@0
|
454 struct format_metaprog< basic_format<T1,T2> >
|
max@0
|
455 {
|
max@0
|
456 static const uword depth = 1 + format_metaprog<T1>::depth;
|
max@0
|
457
|
max@0
|
458 inline
|
max@0
|
459 static
|
max@0
|
460 const std::string&
|
max@0
|
461 get_fmt(const T1& X)
|
max@0
|
462 {
|
max@0
|
463 return format_metaprog<T1>::get_fmt(X.A);
|
max@0
|
464 }
|
max@0
|
465
|
max@0
|
466 };
|
max@0
|
467
|
max@0
|
468
|
max@0
|
469
|
max@0
|
470 template<typename T1, typename T2>
|
max@0
|
471 inline
|
max@0
|
472 std::string
|
max@0
|
473 str(const basic_format<T1,T2>& X)
|
max@0
|
474 {
|
max@0
|
475 return format_metaprog< basic_format<T1,T2> >::get_fmt(X.A);
|
max@0
|
476 }
|
max@0
|
477
|
max@0
|
478
|
max@0
|
479
|
max@0
|
480 template<typename T1, typename T2>
|
max@0
|
481 inline
|
max@0
|
482 std::ostream&
|
max@0
|
483 operator<< (std::ostream& o, const basic_format<T1,T2>& X)
|
max@0
|
484 {
|
max@0
|
485 o << str(X);
|
max@0
|
486 return o;
|
max@0
|
487 }
|
max@0
|
488
|
max@0
|
489
|
max@0
|
490 #endif
|
max@0
|
491
|
max@0
|
492
|
max@0
|
493 template<typename T> struct string_only { };
|
max@0
|
494 template<> struct string_only<std::string> { typedef std::string result; };
|
max@0
|
495
|
max@0
|
496 template<typename T> struct char_only { };
|
max@0
|
497 template<> struct char_only<char > { typedef char result; };
|
max@0
|
498
|
max@0
|
499 template<typename T>
|
max@0
|
500 struct basic_format_only { };
|
max@0
|
501
|
max@0
|
502 #if defined(ARMA_USE_BOOST_FORMAT)
|
max@0
|
503 template<typename T>
|
max@0
|
504 struct basic_format_only< basic_format<T> > { typedef basic_format<T> result; };
|
max@0
|
505 #else
|
max@0
|
506 template<typename T1, typename T2>
|
max@0
|
507 struct basic_format_only< basic_format<T1, T2> > { typedef basic_format<T1,T2> result; };
|
max@0
|
508 #endif
|
max@0
|
509
|
max@0
|
510
|
max@0
|
511
|
max@0
|
512 template<typename T1>
|
max@0
|
513 inline
|
max@0
|
514 static
|
max@0
|
515 const T1&
|
max@0
|
516 str_wrapper(const T1& x, const typename string_only<T1>::result* junk = 0)
|
max@0
|
517 {
|
max@0
|
518 arma_ignore(junk);
|
max@0
|
519
|
max@0
|
520 return x;
|
max@0
|
521 }
|
max@0
|
522
|
max@0
|
523
|
max@0
|
524
|
max@0
|
525 template<typename T1>
|
max@0
|
526 inline
|
max@0
|
527 static
|
max@0
|
528 const T1*
|
max@0
|
529 str_wrapper(const T1* x, const typename char_only<T1>::result* junk = 0)
|
max@0
|
530 {
|
max@0
|
531 arma_ignore(junk);
|
max@0
|
532
|
max@0
|
533 return x;
|
max@0
|
534 }
|
max@0
|
535
|
max@0
|
536
|
max@0
|
537
|
max@0
|
538 template<typename T1>
|
max@0
|
539 inline
|
max@0
|
540 static
|
max@0
|
541 std::string
|
max@0
|
542 str_wrapper(const T1& x, const typename basic_format_only<T1>::result* junk = 0)
|
max@0
|
543 {
|
max@0
|
544 arma_ignore(junk);
|
max@0
|
545
|
max@0
|
546 return str(x);
|
max@0
|
547 }
|
max@0
|
548
|
max@0
|
549 }
|
max@0
|
550
|
max@0
|
551 //! @}
|