Arcane  v3.15.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
ValueConvert.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ValueConvert.cc (C) 2000-2025 */
9/* */
10/* Fonctions pour convertir une chaîne de caractère en un type donné. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ValueConvert.h"
15
16#include "arcane/utils/OStringStream.h"
17#include "arcane/utils/internal/ValueConvertInternal.h"
18
19// En théorie std::from_chars() est disponible avec le C++17 mais pour
20// GCC cela n'est implémenté pour les flottants qu'à partir de GCC 11.
21// Comme c'est la version requise pour le C++20, on n'active cette fonctionnalité
22// qu'à partir du C++20.
23#if defined(ARCANE_HAS_CXX20)
24#define ARCANE_USE_FROMCHARS
25#endif
26
27#if defined(ARCANE_USE_FROMCHARS)
28#include <charconv>
29#endif
30
31// TODO: Pour builtInGetValue(), retourner `true` si la chaîne en entrée est vide.
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane
37{
38namespace
39{
40 const char* _stringViewData(StringView s)
41 {
42 return reinterpret_cast<const char*>(s.bytes().data());
43 }
44
45} // namespace
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
50impl::StringViewInputStream::
51StringViewInputStream(StringView v)
52: m_view(v)
53, m_stream(this)
54{
55 auto b = v.bytes();
56 char* begin_ptr = const_cast<char*>(reinterpret_cast<const char*>(b.data()));
57 char* end_ptr = begin_ptr + b.size();
58 setg(begin_ptr, begin_ptr, end_ptr);
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64namespace
65{
66 Int32 global_value_convert_verbosity = 0;
67 bool global_use_from_chars = true;
68} // namespace
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73void impl::
74arcaneSetIsValueConvertUseFromChars(bool v)
75{
76 global_use_from_chars = v;
77}
78
79void impl::
80arcaneSetValueConvertVerbosity(Int32 v)
81{
82 global_value_convert_verbosity = v;
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88#if defined(ARCANE_USE_FROMCHARS)
89namespace
90{
91 /*!
92 * \brief Converti une chaîne de caractères en un double.
93 *
94 * Converti \a s en un double et range la valeur dans \a v.
95 * Il ne doit pas y avoir de caractères blancs au début de \a s.
96 *
97 * Le comportement de cette méthode est identique à std::strtod()
98 * avec le locale 'C' si on est en C++20. Sinon il est identique
99 * à std::strtod() avec le locale actuel (ce qui peut changer par exemple
100 * le séparateur décimal). La documentation de référence est
101 * ici: https://en.cppreference.com/w/cpp/utility/from_chars.
102 *
103 * \retval (-1) si la conversion a échouée.
104 * \retval la position dans \s du dernier caratère lu plus 1.
105 */
106 Int64 _getDoubleValue(double& v, StringView s)
107 {
108 // ATTENTION: il ne faut pas d'espace en début de \a s
109 auto bytes = s.bytes();
110 Int64 size = bytes.size();
111 if (size == 0)
112 // NOTE: Avec la version historique d'Arcane (avant la 3.15) il
113 // n'y avait pas d'erreur retournée lorsqu'on converti une chaîne vide.
114 // A priori cela n'était jamais utilisé donc cela ne pose pas de
115 // problème de corriger ce bug.
116 return (-1);
117 const char* orig_data = reinterpret_cast<const char*>(bytes.data());
118 const char* last_ptr = nullptr;
119 std::chars_format fmt = std::chars_format::general;
120 const char* data = orig_data;
121 bool do_negatif = false;
122 const bool is_verbose = global_value_convert_verbosity > 0;
123 // std::from_chars() peut lire les valeurs au format hexadécimal
124 // mais il ne doit pas contenir le '0x' ou '0X' du début, contrairement
125 // à std::strtod(). On détecte ce cas et on commence la conversion
126 // après le '0x' ou '0X'.
127
128 // Détecte '-0x' ou '-0X'
129 if (size >= 3 && (bytes[0] == '-') && (bytes[1] == '0') && (bytes[2] == 'x' || bytes[2] == 'X')) {
130 fmt = std::chars_format::hex;
131 data += 3;
132 do_negatif = true;
133 }
134 // Détecte '0x' ou '0X'
135 else if (size >= 2 && (bytes[0] == '0') && (bytes[1] == 'x' || bytes[1] == 'X')) {
136 fmt = std::chars_format::hex;
137 data += 2;
138 }
139 // Cas général
140 {
141 auto [ptr, ec] = std::from_chars(data, data + size, v, fmt);
142 last_ptr = ptr;
143 if (is_verbose)
144 std::cout << "FromChars:TRY GET_DOUBLE data=" << data << " v=" << v << " is_ok=" << (ec == std::errc()) << "\n";
145 if (ec != std::errc())
146 return (-1);
147 }
148 // Prend en compte le signe '-' si demandé
149 if (do_negatif)
150 v = -v;
151 if (is_verbose) {
152 char* ptr2 = nullptr;
153 double v2 = ::strtod(orig_data, &ptr2);
154 std::cout << "FromChars: COMPARE GET_DOUBLE via strtod v2=" << v2 << " pos=" << (ptr2 - orig_data) << "\n";
155 }
156 return (last_ptr - orig_data);
157 }
158
159} // namespace
160#endif
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
165template <> ARCANE_UTILS_EXPORT bool
166builtInGetValue(double& v, StringView s)
167{
168#if defined(ARCANE_USE_FROMCHARS)
169 if (global_use_from_chars) {
170 Int64 p = _getDoubleValue(v, s);
171 return (p == (-1) || (p != s.size()));
172 }
173#endif
174
175 const char* ptr = _stringViewData(s);
176#ifdef WIN32
177 if (s == "infinity" || s == "inf") {
178 v = std::numeric_limits<double>::infinity();
179 return false;
180 }
181#endif
182 char* ptr2 = nullptr;
183 v = ::strtod(ptr, &ptr2);
184 return (ptr2 != (ptr + s.length()));
185}
186
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
190template <> ARCANE_UTILS_EXPORT bool
191builtInGetValue(BFloat16& v, StringView s)
192{
193 float z = 0.0;
194 bool r = builtInGetValue(z, s);
195 v = z;
196 return r;
197}
198
199template <> ARCANE_UTILS_EXPORT bool
200builtInGetValue(Float16& v, StringView s)
201{
202 float z = 0.0;
203 bool r = builtInGetValue(z, s);
204 v = z;
205 return r;
206}
207
208template <> ARCANE_UTILS_EXPORT bool
209builtInGetValue(Float128& v, StringView s)
210{
211 // Pour l'instant (12/2024), il n'y a pas de fonctions natives pour lire un Float128.
212 // On utilise donc un 'long double'.
213 // TODO: à implémenter correctement
214 long double z = 0.0;
215 bool r = builtInGetValue(z, s);
216 v = z;
217 return r;
218}
219
220template <> ARCANE_UTILS_EXPORT bool
221builtInGetValue(float& v, StringView s)
222{
223 double z = 0.;
224 bool r = builtInGetValue(z, s);
225 v = (float)z;
226 return r;
227}
228
229template <> ARCANE_UTILS_EXPORT bool
230builtInGetValue(long& v, StringView s)
231{
232 const char* ptr = _stringViewData(s);
233 char* ptr2 = 0;
234 v = ::strtol(ptr, &ptr2, 0);
235 return (ptr2 != (ptr + s.length()));
236}
237
238template <> ARCANE_UTILS_EXPORT bool
239builtInGetValue(int& v, StringView s)
240{
241 long z = 0;
242 bool r = builtInGetValue(z, s);
243 v = (int)z;
244 return r;
245}
246
247template <> ARCANE_UTILS_EXPORT bool
248builtInGetValue(short& v, StringView s)
249{
250 long z = 0;
251 bool r = builtInGetValue(z, s);
252 v = (short)z;
253 return r;
254}
255
256template <> ARCANE_UTILS_EXPORT bool
257builtInGetValue(unsigned long& v, StringView s)
258{
259 const char* ptr = _stringViewData(s);
260 char* ptr2 = 0;
261 v = ::strtoul(ptr, &ptr2, 0);
262 return (ptr2 != (ptr + s.length()));
263}
264
265template <> ARCANE_UTILS_EXPORT bool
266builtInGetValue(unsigned int& v, StringView s)
267{
268 unsigned long z = 0;
269 bool r = builtInGetValue(z, s);
270 v = (unsigned int)z;
271 return r;
272}
273
274template <> ARCANE_UTILS_EXPORT bool
275builtInGetValue(unsigned short& v, StringView s)
276{
277 unsigned long z = 0;
278 bool r = builtInGetValue(z, s);
279 v = (unsigned short)z;
280 return r;
281}
282
283template <> ARCANE_UTILS_EXPORT bool
284builtInGetValue(long long& v, StringView s)
285{
286 const char* ptr = _stringViewData(s);
287 char* ptr2 = 0;
288 v = ::strtoll(ptr, &ptr2, 0);
289 return (ptr2 != (ptr + s.length()));
290}
291
292template <> ARCANE_UTILS_EXPORT bool
293builtInGetValue(Real2& v, StringView s)
294{
295 return impl::builtInGetValueGeneric(v, s);
296}
297template <> ARCANE_UTILS_EXPORT bool
298builtInGetValue(Real3& v, StringView s)
299{
300 return impl::builtInGetValueGeneric(v, s);
301}
302
303template <> ARCANE_UTILS_EXPORT bool
304builtInGetValue(Real2x2& v, StringView s)
305{
306 return impl::builtInGetValueGeneric(v, s);
307}
308
309template <> ARCANE_UTILS_EXPORT bool
310builtInGetValue(Real3x3& v, StringView s)
311{
312 return impl::builtInGetValueGeneric(v, s);
313}
314
315template <> ARCANE_UTILS_EXPORT bool
316builtInGetValue(Int128& v, StringView s)
317{
318 // Pour l'instant (12/2024), il n'y a pas de fonctions natives pour lire un Int128.
319 // On utilise donc un 'Int64' en attendant.
320 // TODO: il existe des exemples sur internet. A implémenter correctement
321 long long v2 = 0;
322 const char* ptr = _stringViewData(s);
323 char* ptr2 = 0;
324 v2 = ::strtoll(ptr, &ptr2, 0);
325 v = v2;
326 return (ptr2 != (ptr + s.length()));
327}
328
329template <> ARCANE_UTILS_EXPORT bool
330builtInGetValue(unsigned long long& v, StringView s)
331{
332 const char* ptr = _stringViewData(s);
333 char* ptr2 = 0;
334 v = ::strtoull(ptr, &ptr2, 0);
335 return (ptr2 != (ptr + s.length()));
336}
337
338/*---------------------------------------------------------------------------*/
339/*---------------------------------------------------------------------------*/
340
341#ifdef ARCANE_REAL_NOT_BUILTIN
342template <> ARCANE_UTILS_EXPORT bool
343builtInGetValue(Real& v, StringView s)
344{
345#if 0
346 double vz = 0.0;
347 if (builtInGetValue(vz,s))
348 return true;
349 v = vz;
350 cout << "** CONVERT DOUBLE TO REAL s=" << s << " vz=" << vz << " v=" << v << '\n';
351 return false;
352#endif
353 double vz = 0.0;
354 if (builtInGetValue(vz, s))
355 return true;
356 v = Real((char*)s.localstr(), 1000);
357 cout << "** CONVERT DOUBLE TO REAL s=" << s << '\n';
358 return false;
359}
360#endif
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365template <> bool
366builtInGetValue(String& v, StringView s)
367{
368 v = s;
369 return false;
370}
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374
375namespace
376{
377 bool _builtInGetBoolArrayValue(BoolArray& v, StringView s)
378 {
379 // Le type 'bool' est un peu spécial car il doit pouvoir lire les
380 // valeurs comme 'true' ou 'false'.
381 // On le lit donc comme un 'StringUniqueArray', puis on converti en bool
382 //cout << "** GET BOOL ARRAY V=" << s << '\n';
383 //return builtInGetArrayValue(v,s);
384
386 if (builtInGetValue(sa, s))
387 return true;
388 for (Integer i = 0, is = sa.size(); i < is; ++i) {
389 bool read_val = false;
390 if (builtInGetValue(read_val, sa[i]))
391 return true;
392 v.add(read_val);
393 }
394 return false;
395 }
396
397 bool
398 _builtInGetStringArrayValue(StringArray& v, StringView s)
399 {
400 std::string s2;
401 String read_val = String();
402 impl::StringViewInputStream svis(s);
403 std::istream& sbuf = svis.stream();
404 while (!sbuf.eof()) {
405 sbuf >> s2;
406 //cout << " ** CHECK READ v='" << s2 << "' '" << sv << "'\n";
407 if (sbuf.bad()) // non-recoverable error
408 return true;
409 if (sbuf.fail()) // recoverable error : this means good conversion
410 return false;
411 read_val = StringView(s2.c_str());
412 v.add(read_val);
413 }
414 return false;
415 }
416} // namespace
417
418template <> ARCANE_UTILS_EXPORT bool
419builtInGetValue(RealArray& v, StringView s)
420{
421 return builtInGetArrayValue(v, s);
422}
423
424template <> ARCANE_UTILS_EXPORT bool
425builtInGetValue(Real2Array& v, StringView s)
426{
427 return builtInGetArrayValue(v, s);
428}
429
430template <> ARCANE_UTILS_EXPORT bool
431builtInGetValue(Real3Array& v, StringView s)
432{
433 return builtInGetArrayValue(v, s);
434}
435
436template <> ARCANE_UTILS_EXPORT bool
437builtInGetValue(Real2x2Array& v, StringView s)
438{
439 return builtInGetArrayValue(v, s);
440}
441
442template <> ARCANE_UTILS_EXPORT bool
443builtInGetValue(Real3x3Array& v, StringView s)
444{
445 return builtInGetArrayValue(v, s);
446}
447
448template <> ARCANE_UTILS_EXPORT bool
449builtInGetValue(Int8Array& v, StringView s)
450{
451 return builtInGetArrayValue(v, s);
452}
453
454template <> ARCANE_UTILS_EXPORT bool
455builtInGetValue(Int16Array& v, StringView s)
456{
457 return builtInGetArrayValue(v, s);
458}
459
460template <> ARCANE_UTILS_EXPORT bool
461builtInGetValue(Int32Array& v, StringView s)
462{
463 return builtInGetArrayValue(v, s);
464}
465
466template <> ARCANE_UTILS_EXPORT bool
467builtInGetValue(Int64Array& v, StringView s)
468{
469 return builtInGetArrayValue(v, s);
470}
471
472template <> ARCANE_UTILS_EXPORT bool
473builtInGetValue(BoolArray& v, StringView s)
474{
475 return _builtInGetBoolArrayValue(v, s);
476}
477
478template <> ARCANE_UTILS_EXPORT bool
479builtInGetValue(StringArray& v, StringView s)
480{
481 return _builtInGetStringArrayValue(v, s);
482}
483
484/*---------------------------------------------------------------------------*/
485/*---------------------------------------------------------------------------*/
486
487template <> ARCANE_UTILS_EXPORT bool
488builtInGetValue(RealUniqueArray& v, StringView s)
489{
490 return builtInGetArrayValue(v, s);
491}
492
493template <> ARCANE_UTILS_EXPORT bool
494builtInGetValue(Real2UniqueArray& v, StringView s)
495{
496 return builtInGetArrayValue(v, s);
497}
498
499template <> ARCANE_UTILS_EXPORT bool
500builtInGetValue(Real3UniqueArray& v, StringView s)
501{
502 return builtInGetArrayValue(v, s);
503}
504
505template <> ARCANE_UTILS_EXPORT bool
506builtInGetValue(Real2x2UniqueArray& v, StringView s)
507{
508 return builtInGetArrayValue(v, s);
509}
510
511template <> ARCANE_UTILS_EXPORT bool
512builtInGetValue(Real3x3UniqueArray& v, StringView s)
513{
514 return builtInGetArrayValue(v, s);
515}
516
517template <> ARCANE_UTILS_EXPORT bool
518builtInGetValue(Int8UniqueArray& v, StringView s)
519{
520 return builtInGetArrayValue(v, s);
521}
522
523template <> ARCANE_UTILS_EXPORT bool
524builtInGetValue(Int16UniqueArray& v, StringView s)
525{
526 return builtInGetArrayValue(v, s);
527}
528
529template <> ARCANE_UTILS_EXPORT bool
530builtInGetValue(Int32UniqueArray& v, StringView s)
531{
532 return builtInGetArrayValue(v, s);
533}
534
535template <> ARCANE_UTILS_EXPORT bool
536builtInGetValue(Int64UniqueArray& v, StringView s)
537{
538 return builtInGetArrayValue(v, s);
539}
540
541template <> ARCANE_UTILS_EXPORT bool
542builtInGetValue(BoolUniqueArray& v, StringView s)
543{
544 return _builtInGetBoolArrayValue(v, s);
545}
546
547template <> ARCANE_UTILS_EXPORT bool
548builtInGetValue(StringUniqueArray& v, StringView s)
549{
550 return _builtInGetStringArrayValue(v, s);
551}
552
553/*---------------------------------------------------------------------------*/
554/*---------------------------------------------------------------------------*/
555
556template <> ARCANE_UTILS_EXPORT bool
557builtInGetValue(RealSharedArray& v, StringView s)
558{
559 return builtInGetArrayValue(v, s);
560}
561
562template <> ARCANE_UTILS_EXPORT bool
563builtInGetValue(Real2SharedArray& v, StringView s)
564{
565 return builtInGetArrayValue(v, s);
566}
567
568template <> ARCANE_UTILS_EXPORT bool
569builtInGetValue(Real3SharedArray& v, StringView s)
570{
571 return builtInGetArrayValue(v, s);
572}
573
574template <> ARCANE_UTILS_EXPORT bool
575builtInGetValue(Real2x2SharedArray& v, StringView s)
576{
577 return builtInGetArrayValue(v, s);
578}
579
580template <> ARCANE_UTILS_EXPORT bool
581builtInGetValue(Real3x3SharedArray& v, StringView s)
582{
583 return builtInGetArrayValue(v, s);
584}
585
586template <> ARCANE_UTILS_EXPORT bool
587builtInGetValue(Int8SharedArray& v, StringView s)
588{
589 return builtInGetArrayValue(v, s);
590}
591
592template <> ARCANE_UTILS_EXPORT bool
593builtInGetValue(Int16SharedArray& v, StringView s)
594{
595 return builtInGetArrayValue(v, s);
596}
597
598template <> ARCANE_UTILS_EXPORT bool
599builtInGetValue(Int32SharedArray& v, StringView s)
600{
601 return builtInGetArrayValue(v, s);
602}
603
604template <> ARCANE_UTILS_EXPORT bool
605builtInGetValue(Int64SharedArray& v, StringView s)
606{
607 return builtInGetArrayValue(v, s);
608}
609
610template <> ARCANE_UTILS_EXPORT bool
611builtInGetValue(BoolSharedArray& v, StringView s)
612{
613 return _builtInGetBoolArrayValue(v, s);
614}
615
616template <> ARCANE_UTILS_EXPORT bool
617builtInGetValue(StringSharedArray& v, StringView s)
618{
619 return _builtInGetStringArrayValue(v, s);
620}
621
622/*---------------------------------------------------------------------------*/
623/*---------------------------------------------------------------------------*/
624
625namespace
626{
627 template <class T> inline bool
628 _builtInPutValue(const T& v, String& s)
629 {
630 OStringStream ostr;
631 ostr() << v;
632 if (ostr().fail() || ostr().bad())
633 return true;
634 s = ostr.str();
635 return false;
636 }
637 template <class T> inline bool
638 _builtInPutArrayValue(Span<const T> v, String& s)
639 {
640 OStringStream ostr;
641 for (Int64 i = 0, n = v.size(); i < n; ++i) {
642 if (i != 0)
643 ostr() << ' ';
644 ostr() << v[i];
645 }
646 if (ostr().fail() || ostr().bad())
647 return true;
648 s = ostr.str();
649 return false;
650 }
651} // namespace
652
653/*---------------------------------------------------------------------------*/
654/*---------------------------------------------------------------------------*/
655
656bool builtInPutValue(const String& v, String& s)
657{
658 return _builtInPutValue(v, s);
659}
660bool builtInPutValue(double v, String& s)
661{
662 return _builtInPutValue(v, s);
663}
664bool builtInPutValue(float v, String& s)
665{
666 return _builtInPutValue(v, s);
667}
668bool builtInPutValue(int v, String& s)
669{
670 return _builtInPutValue(v, s);
671}
672bool builtInPutValue(unsigned int v, String& s)
673{
674 return _builtInPutValue(v, s);
675}
676bool builtInPutValue(long v, String& s)
677{
678 return _builtInPutValue(v, s);
679}
680bool builtInPutValue(long long v, String& s)
681{
682 return _builtInPutValue(v, s);
683}
684bool builtInPutValue(short v, String& s)
685{
686 return _builtInPutValue(v, s);
687}
688bool builtInPutValue(unsigned short v, String& s)
689{
690 return _builtInPutValue(v, s);
691}
692bool builtInPutValue(unsigned long v, String& s)
693{
694 return _builtInPutValue(v, s);
695}
696bool builtInPutValue(unsigned long long v, String& s)
697{
698 return _builtInPutValue(v, s);
699}
700#ifdef ARCANE_REAL_NOT_BUILTIN
701bool builtInPutValue(Real v, String& s)
702{
703 return _builtInPutValue(v, s);
704}
705#endif
706bool builtInPutValue(Real2 v, String& s)
707{
708 return _builtInPutValue(v, s);
709}
710bool builtInPutValue(Real3 v, String& s)
711{
712 return _builtInPutValue(v, s);
713}
714bool builtInPutValue(const Real2x2& v, String& s)
715{
716 return _builtInPutValue(v, s);
717}
718bool builtInPutValue(const Real3x3& v, String& s)
719{
720 return _builtInPutValue(v, s);
721}
722
723bool builtInPutValue(Span<const Real> v, String& s)
724{
725 return _builtInPutArrayValue(v, s);
726}
727bool builtInPutValue(Span<const Real2> v, String& s)
728{
729 return _builtInPutArrayValue(v, s);
730}
731bool builtInPutValue(Span<const Real3> v, String& s)
732{
733 return _builtInPutArrayValue(v, s);
734}
735bool builtInPutValue(Span<const Real2x2> v, String& s)
736{
737 return _builtInPutArrayValue(v, s);
738}
739bool builtInPutValue(Span<const Real3x3> v, String& s)
740{
741 return _builtInPutArrayValue(v, s);
742}
743bool builtInPutValue(Span<const Int16> v, String& s)
744{
745 return _builtInPutArrayValue(v, s);
746}
747bool builtInPutValue(Span<const Int32> v, String& s)
748{
749 return _builtInPutArrayValue(v, s);
750}
751bool builtInPutValue(Span<const Int64> v, String& s)
752{
753 return _builtInPutArrayValue(v, s);
754}
755bool builtInPutValue(Span<const bool> v, String& s)
756{
757 return _builtInPutArrayValue(v, s);
758}
759bool builtInPutValue(Span<const String> v, String& s)
760{
761 return _builtInPutArrayValue(v, s);
762}
763//@}
764
765/*---------------------------------------------------------------------------*/
766/*---------------------------------------------------------------------------*/
767
768} // namespace Arcane
769
770/*---------------------------------------------------------------------------*/
771/*---------------------------------------------------------------------------*/
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Chaîne de caractères unicode.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
bool builtInPutValue(const String &v, String &s)
Converti la valeur v dans la chaîne s.
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Definition UtilsTypes.h:570
double Real
Type représentant un réel.