Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
String.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/* String.cc (C) 2000-2025 */
9/* */
10/* Chaîne de caractères unicode. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/base/String.h"
15#include "arccore/base/StringBuilder.h"
16#include "arccore/base/CStringUtils.h"
17#include "arccore/base/APReal.h"
18#include "arccore/base/TraceInfo.h"
19#include "arccore/base/FatalErrorException.h"
20#include "arccore/base/StringView.h"
22
23#include "arccore/base/internal/StringImpl.h"
24
25#include <iostream>
26#include <cstring>
27#include <limits>
28#include <vector>
29
30#define A_FASTLOCK(ptr)
31/*!
32 * \file StringUtils.h
33 *
34 * \brief Fonctions utilitaires sur les chaînes de caractères.
35 */
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39namespace Arcane
40{
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
46String(const std::string& str)
47: m_p(new StringImpl(str))
48, m_const_ptr_size(-1)
49{
50 m_p->addReference();
51}
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
57String(std::string_view str)
58: m_p(new StringImpl(str))
59, m_const_ptr_size(-1)
60{
61 m_p->addReference();
62}
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
69: m_p(new StringImpl(str.toStdStringView()))
70, m_const_ptr(nullptr)
71, m_const_ptr_size(-1)
72{
73 m_p->addReference();
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
80String(const UCharConstArrayView& ustr)
81: m_p(new StringImpl(ustr))
82, m_const_ptr_size(-1)
83{
84 m_p->addReference();
85}
86
87/*---------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
89
91String(const Span<const Byte>& ustr)
92: m_p(new StringImpl(ustr))
93, m_const_ptr_size(-1)
94{
95 m_p->addReference();
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
102String(StringImpl* impl)
103: m_p(impl)
104, m_const_ptr_size(-1)
105{
106 if (m_p)
107 m_p->addReference();
108}
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
114String(const char* str,Integer len)
115: m_p(new StringImpl(std::string_view(str,len)))
116, m_const_ptr_size(-1)
117{
118 m_p->addReference();
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
125String(char* str)
126: m_p(new StringImpl(str))
127, m_const_ptr_size(-1)
128{
129 m_p->addReference();
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
136String(const char* str,bool do_alloc)
137: m_p(nullptr)
138, m_const_ptr(nullptr)
139, m_const_ptr_size(-1)
140{
141 if (do_alloc){
142 m_p = new StringImpl(str);
143 m_p->addReference();
144 }
145 else{
146 m_const_ptr = str;
147 if (m_const_ptr)
148 m_const_ptr_size = std::strlen(str);
149 }
150}
151
152/*---------------------------------------------------------------------------*/
153/*---------------------------------------------------------------------------*/
154
156String(const String& str)
157: m_p(str.m_p)
158, m_const_ptr(str.m_const_ptr)
159, m_const_ptr_size(str.m_const_ptr_size)
160{
161 if (m_p)
162 m_p->addReference();
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
167
169operator=(const String& str)
170{
171 if (str.m_p)
172 str.m_p->addReference();
173 _removeReferenceIfNeeded();
174 _copyFields(str);
175 return (*this);
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
182operator=(String&& str)
183{
184 _removeReferenceIfNeeded();
185
186 _copyFields(str);
187 str._resetFields();
188
189 return (*this);
190
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
198{
199 return this->operator=(String(str));
200}
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
206operator=(std::string_view str)
207{
208 return this->operator=(String(str));
209}
210
211/*---------------------------------------------------------------------------*/
212/*---------------------------------------------------------------------------*/
213
215operator=(const std::string& str)
216{
217 return this->operator=(String(str));
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
226const char* String::
227localstr() const
228{
229 if (m_const_ptr)
230 return m_const_ptr;
231 if (m_p)
232 return m_p->toStdStringView().data();
233 return "";
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239void String::
240_removeImplReference()
241{
242 m_p->removeReference();
243}
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
248ConstArrayView<UChar> String::
249_internalUtf16BE() const
250{
251 A_FASTLOCK(this);
252 if (!m_p){
253 if (m_const_ptr){
254 _checkClone();
255 }
256 }
257 if (m_p)
258 return m_p->utf16();
259 return ConstArrayView<UChar>();
260}
261
262/*---------------------------------------------------------------------------*/
263/*---------------------------------------------------------------------------*/
264
266utf16() const
267{
268 return _internalUtf16BE();
269}
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273
275utf8() const
276{
277 if (m_p)
278 return m_p->largeUtf8().smallView();
279 if (m_const_ptr){
280 Int64 ts = m_const_ptr_size+1;
282 return ByteConstArrayView(s,reinterpret_cast<const Byte*>(m_const_ptr));
283 }
284 return ByteConstArrayView();
285}
286
287/*---------------------------------------------------------------------------*/
288/*---------------------------------------------------------------------------*/
289
291bytes() const
292{
293 if (m_p)
294 return m_p->bytes();
295 if (m_const_ptr)
296 return Span<const Byte>(reinterpret_cast<const Byte*>(m_const_ptr),m_const_ptr_size);
297 return Span<const Byte>();
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
304null() const
305{
306 if (m_const_ptr)
307 return false;
308 return m_p==0;
309}
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313
315empty() const
316{
317 if (m_const_ptr)
318 return m_const_ptr[0]=='\0';
319 if (m_p)
320 return m_p->empty();
321 return true;
322}
323
324/*---------------------------------------------------------------------------*/
325/*---------------------------------------------------------------------------*/
326
328len() const
329{
330 auto x = this->toStdStringView();
331 return arccoreCheckArraySize(x.size());
332}
333
334/*---------------------------------------------------------------------------*/
335/*---------------------------------------------------------------------------*/
336
338length() const
339{
340 auto x = this->toStdStringView();
341 return x.size();
342}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
347std::string_view String::
348toStdStringView() const
349{
350 if (m_const_ptr){
351#ifdef ARCCORE_CHECK
352 Int64 xlen = std::strlen(m_const_ptr);
353 if (xlen!=m_const_ptr_size)
354 ARCCORE_FATAL("Bad length (computed={0} stored={1})",xlen,m_const_ptr_size);
355#endif
356 return _viewFromConstChar();
357 }
358 if (m_p)
359 return m_p->toStdStringView();
360 return std::string_view();
361}
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
367view() const
368{
369 if (m_const_ptr)
370 return StringView(_viewFromConstChar());
371 if (m_p)
372 return m_p->view();
373 return StringView();
374}
375
376/*---------------------------------------------------------------------------*/
377/*---------------------------------------------------------------------------*/
378
379String::operator StringView() const
380{
381 return view();
382}
383
384/*---------------------------------------------------------------------------*/
385/*---------------------------------------------------------------------------*/
386
387void String::
388_checkClone() const
389{
390 if (m_const_ptr || !m_p){
391 std::string_view sview;
392 if (m_const_ptr)
393 sview = _viewFromConstChar();
394 m_p = new StringImpl(sview);
395 m_p->addReference();
396 m_const_ptr = nullptr;
397 m_const_ptr_size = -1;
398 return;
399 }
400 if (m_p->nbReference()!=1){
401 StringImpl* old_p = m_p;
402 m_p = m_p->clone();
403 m_p->addReference();
404 old_p->removeReference();
405 }
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
412clone() const
413{
414 if (m_p)
415 return String(m_p->clone());
416 return String(*this);
417}
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
422String& String::
423_append(const String& str)
424{
425 if (str.null())
426 return *this;
427 _checkClone();
428 if (str.m_const_ptr){
429 m_p = m_p->append(str._viewFromConstChar());
430 }
431 else
432 m_p = m_p->append(str.m_p);
433 return *this;
434}
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
438
441{
442 String s2(s);
443 s2._checkClone();
444 s2.m_p = s2.m_p->replaceWhiteSpace();
445 return s2;
446}
447
448/*---------------------------------------------------------------------------*/
449/*---------------------------------------------------------------------------*/
450
453{
454 if (s.null())
455 return String();
456 String s2(s);
457 s2._checkClone();
458 s2.m_p = s2.m_p->collapseWhiteSpace();
459 return s2;
460}
461
462/*---------------------------------------------------------------------------*/
463/*---------------------------------------------------------------------------*/
464
466upper() const
467{
468 String s2(*this);
469 s2._checkClone();
470 s2.m_p = s2.m_p->toUpper();
471 return s2;
472}
473
474/*---------------------------------------------------------------------------*/
475/*---------------------------------------------------------------------------*/
476
478lower() const
479{
480 String s2(*this);
481 s2._checkClone();
482 s2.m_p = s2.m_p->toLower();
483 return s2;
484}
485
486/*---------------------------------------------------------------------------*/
487/*---------------------------------------------------------------------------*/
488
490operator+(std::string_view str) const
491{
492 if (str.empty())
493 return (*this);
494 String s2(*this);
495 return s2._append(str);
496}
497
498/*---------------------------------------------------------------------------*/
499/*---------------------------------------------------------------------------*/
500
502operator+(const std::string& str) const
503{
504 if (str.empty())
505 return (*this);
506 String s2(*this);
507 return s2._append(str);
508}
509
510/*---------------------------------------------------------------------------*/
511/*---------------------------------------------------------------------------*/
512
514operator+(const String& str) const
515{
516 String s2(*this);
517 return s2._append(str);
518}
519
520/*---------------------------------------------------------------------------*/
521/*---------------------------------------------------------------------------*/
522
523String String::
524fromNumber(unsigned long v)
525{
526 return StringFormatterArg(v).value();
527}
528
529String String::
530fromNumber(unsigned int v)
531{
532 return StringFormatterArg(v).value();
533}
534
535String String::
536fromNumber(double v)
537{
538 return StringFormatterArg(v).value();
539}
540
541String String::
542fromNumber(long double v)
543{
544 return StringFormatterArg(v).value();
545}
546
547String String::
548fromNumber(int v)
549{
550 return StringFormatterArg(v).value();
551}
552
553String String::
554fromNumber(long v)
555{
556 return StringFormatterArg(v).value();
557}
558
559String String::
560fromNumber(unsigned long long v)
561{
562 return StringFormatterArg(v).value();
563}
564
565String String::
566fromNumber(long long v)
567{
568 return StringFormatterArg(v).value();
569}
570
571String String::
572fromNumber(const APReal& v)
573{
574 return StringFormatterArg(v).value();
575}
576
577String String::
578fromNumber(double v,Integer nb_digit_after_point)
579{
580 Int64 mulp = 1;
581 for( Integer z=0; z<nb_digit_after_point; ++z )
582 mulp *= 10;
583 Int64 p = (Int64)(v * (Real)mulp);
584 Int64 after_digit = p % mulp;
585 Int64 before_digit = p / mulp;
586 StringBuilder s(String::fromNumber(before_digit) + ".");
587 {
588 Integer nb_zero = 0;
589 Int64 mv = mulp / 10;
590 for( Integer i=0; i<(nb_digit_after_point-1); ++i ){
591 if (after_digit>=mv){
592 break;
593 }
594 ++nb_zero;
595 mv /= 10;
596 }
597 for( Integer i=0; i<nb_zero; ++i )
598 s += "0";
599 }
600 s += String::fromNumber(after_digit);
601 return s;
602}
603
604/*---------------------------------------------------------------------------*/
605/*---------------------------------------------------------------------------*/
606
608operator+(unsigned long v) const
609{
610 String s2(*this);
611 return s2._append(String::fromNumber(v));
612}
613
615operator+(unsigned int v) const
616{
617 String s2(*this);
618 return s2._append(String::fromNumber(v));
619}
620
622operator+(double v) const
623{
624 String s2(*this);
625 return s2._append(String::fromNumber(v));
626}
627
629operator+(long double v) const
630{
631 String s2(*this);
632 return s2._append(String::fromNumber(v));
633}
634
636operator+(int v) const
637{
638 String s2(*this);
639 return s2._append(String::fromNumber(v));
640}
641
643operator+(long v) const
644{
645 String s2(*this);
646 return s2._append(String::fromNumber(v));
647}
648
650operator+(unsigned long long v) const
651{
652 String s2(*this);
653 return s2._append(String::fromNumber(v));
654}
655
657operator+(long long v) const
658{
659 String s2(*this);
660 return s2._append(String::fromNumber(v));
661}
662
664operator+(const APReal& v) const
665{
666 String s2(*this);
667 return s2._append(String::fromNumber(v));
668}
669
670/*---------------------------------------------------------------------------*/
671/*---------------------------------------------------------------------------*/
672
673bool String::
674isLess(const String& b) const
675{
676 if (m_const_ptr){
677 if (b.m_const_ptr)
678 return CStringUtils::isLess(m_const_ptr,b.m_const_ptr);
679 if (b.m_p){
680 if (b.m_p->isEqual(m_const_ptr))
681 return false;
682 return !(b.m_p->isLessThan(m_const_ptr));
683 }
684 // b est la chaîne nulle mais pas moi.
685 return false;
686 }
687
688 if (b.m_const_ptr){
689 if (m_p)
690 return m_p->isLessThan(b.m_const_ptr);
691 // Je suis la chaîne nulle mais pas b.
692 return true;
693 }
694
695 if (m_p){
696 if (b.m_p)
697 return m_p->isLessThan(b.m_p);
698 // b est la chaine nulle mais pas moi
699 return false;
700 }
701
702 // Je suis la chaine nulle
703 return b.m_p==nullptr;
704}
705
706/*---------------------------------------------------------------------------*/
707/*---------------------------------------------------------------------------*/
708
709String String::
710fromUtf8(Span<const Byte> bytes)
711{
712 return String(new StringImpl(bytes));
713}
714
715/*---------------------------------------------------------------------------*/
716/*---------------------------------------------------------------------------*/
717
719internalDump(std::ostream& ostr) const
720{
721 ostr << "StringDump(m_const_ptr=" << (void*)m_const_ptr << ",m_p=" << m_p;
722 if (m_p){
723 ostr << ",";
724 m_p->internalDump(ostr);
725 }
726 ostr << ")";
727}
728
729/*---------------------------------------------------------------------------*/
730/*---------------------------------------------------------------------------*/
731
733hashCode() const
734{
736 Int32 h = 0;
737 Int64 n = s.size();
738 for( Int64 i=0; i<n; ++i ){
739 h = (h << 5) - h + s[i];
740 }
741 return h;
742}
743
744/*---------------------------------------------------------------------------*/
745/*---------------------------------------------------------------------------*/
746
747void StringFormatterArg::
748_formatReal(Real avalue)
749{
750 std::ostringstream ostr;
751 ostr.precision(std::numeric_limits<Real>::digits10);
752 ostr << avalue;
753 m_str_value = ostr.str();
754}
755
756/*---------------------------------------------------------------------------*/
757/*---------------------------------------------------------------------------*/
758
759class StringFormatter
760{
761 public:
762 StringFormatter(const String& format)
763 : m_format(format), m_current_arg(0) {}
764 public:
765 void addArg(const String& ostr)
766 {
767 char buf[20];
768 Integer nb_z = 0;
769 Integer z = m_current_arg;
770 ++m_current_arg;
771 if (z>=100){
772 // N'arrive normalement jamais car seul ce fichier a accès à cette
773 // méthode.
774 std::cerr << "Too many args (maximum is 100)";
775 return;
776 }
777 else if (z>=10){
778 nb_z = 2;
779 buf[0] = (char)('0' + (z / 10));
780 buf[1] = (char)('0' + (z % 10));
781 }
782 else{
783 nb_z = 1;
784 buf[0] = (char)('0' + z);
785 }
786 buf[nb_z] = '}';
787 ++nb_z;
788 buf[nb_z] = '\0';
789
790 std::string str = m_format.localstr();
791 const char* local_str = str.c_str();
792 // TODO: ne pas utiliser de String mais un StringBuilder pour format
793 const Int64 slen = str.length();
794 for( Int64 i=0; i<slen; ++i ){
795 if (local_str[i]=='{'){
796 if (i+nb_z>=slen)
797 break;
798 bool is_ok = true;
799 for( Integer j=0; j<nb_z; ++j )
800 if (local_str[i+1+j]!=buf[j]){
801 is_ok = false;
802 break;
803 }
804 if (is_ok){
805 std::string str1(local_str,local_str+i);
806 std::string str2(local_str+i+1+nb_z);
807 m_format = String(str1) + ostr + str2;
808 // Il faut quitter tout de suite car str n'est plus valide
809 // puisque m_format a changé.
810 break;
811 }
812 }
813 }
814 }
815 public:
816 const String& value() const { return m_format; }
817 public:
818 String m_format;
819 Integer m_current_arg;
820 public:
821};
822
823/*---------------------------------------------------------------------------*/
824/*---------------------------------------------------------------------------*/
825
826String String::
827format(const String& str)
828{
829 return str;
830}
831
832/*---------------------------------------------------------------------------*/
833/*---------------------------------------------------------------------------*/
834
835String String::
836format(const String& str,const StringFormatterArg& arg1)
837{
838 StringFormatter sf(str);
839 sf.addArg(arg1.value());
840 return sf.value();
841}
842
843/*---------------------------------------------------------------------------*/
844/*---------------------------------------------------------------------------*/
845
846String String::
847format(const String& str,const StringFormatterArg& arg1,
848 const StringFormatterArg& arg2)
849{
850 StringFormatter sf(str);
851 sf.addArg(arg1.value());
852 sf.addArg(arg2.value());
853 return sf.value();
854}
855
856/*---------------------------------------------------------------------------*/
857/*---------------------------------------------------------------------------*/
858
859String String::
860format(const String& str,const StringFormatterArg& arg1,
861 const StringFormatterArg& arg2,
862 const StringFormatterArg& arg3)
863{
864 StringFormatter sf(str);
865 sf.addArg(arg1.value());
866 sf.addArg(arg2.value());
867 sf.addArg(arg3.value());
868 return sf.value();
869}
870
871/*---------------------------------------------------------------------------*/
872/*---------------------------------------------------------------------------*/
873
874String String::
875format(const String& str,const StringFormatterArg& arg1,
876 const StringFormatterArg& arg2,
877 const StringFormatterArg& arg3,
878 const StringFormatterArg& arg4)
879{
880 StringFormatter sf(str);
881 sf.addArg(arg1.value());
882 sf.addArg(arg2.value());
883 sf.addArg(arg3.value());
884 sf.addArg(arg4.value());
885 return sf.value();
886}
887
888/*---------------------------------------------------------------------------*/
889/*---------------------------------------------------------------------------*/
890
891String String::
892format(const String& str,const StringFormatterArg& arg1,
893 const StringFormatterArg& arg2,
894 const StringFormatterArg& arg3,
895 const StringFormatterArg& arg4,
896 const StringFormatterArg& arg5)
897{
898 StringFormatter sf(str);
899 sf.addArg(arg1.value());
900 sf.addArg(arg2.value());
901 sf.addArg(arg3.value());
902 sf.addArg(arg4.value());
903 sf.addArg(arg5.value());
904 return sf.value();
905}
906
907/*---------------------------------------------------------------------------*/
908/*---------------------------------------------------------------------------*/
909
910String String::
911format(const String& str,const StringFormatterArg& arg1,
912 const StringFormatterArg& arg2,
913 const StringFormatterArg& arg3,
914 const StringFormatterArg& arg4,
915 const StringFormatterArg& arg5,
916 const StringFormatterArg& arg6)
917{
918 StringFormatter sf(str);
919 sf.addArg(arg1.value());
920 sf.addArg(arg2.value());
921 sf.addArg(arg3.value());
922 sf.addArg(arg4.value());
923 sf.addArg(arg5.value());
924 sf.addArg(arg6.value());
925 return sf.value();
926}
927
928/*---------------------------------------------------------------------------*/
929/*---------------------------------------------------------------------------*/
930
931String String::
932format(const String& str,const StringFormatterArg& arg1,
933 const StringFormatterArg& arg2,
934 const StringFormatterArg& arg3,
935 const StringFormatterArg& arg4,
936 const StringFormatterArg& arg5,
937 const StringFormatterArg& arg6,
938 const StringFormatterArg& arg7)
939{
940 StringFormatter sf(str);
941 sf.addArg(arg1.value());
942 sf.addArg(arg2.value());
943 sf.addArg(arg3.value());
944 sf.addArg(arg4.value());
945 sf.addArg(arg5.value());
946 sf.addArg(arg6.value());
947 sf.addArg(arg7.value());
948 return sf.value();
949}
950
951/*---------------------------------------------------------------------------*/
952/*---------------------------------------------------------------------------*/
953
954String String::
955format(const String& str,const StringFormatterArg& arg1,
956 const StringFormatterArg& arg2,
957 const StringFormatterArg& arg3,
958 const StringFormatterArg& arg4,
959 const StringFormatterArg& arg5,
960 const StringFormatterArg& arg6,
961 const StringFormatterArg& arg7,
962 const StringFormatterArg& arg8)
963{
964 StringFormatter sf(str);
965 sf.addArg(arg1.value());
966 sf.addArg(arg2.value());
967 sf.addArg(arg3.value());
968 sf.addArg(arg4.value());
969 sf.addArg(arg5.value());
970 sf.addArg(arg6.value());
971 sf.addArg(arg7.value());
972 sf.addArg(arg8.value());
973 return sf.value();
974}
975
976/*---------------------------------------------------------------------------*/
977/*---------------------------------------------------------------------------*/
978
979String String::
980format(const String& str,const StringFormatterArg& arg1,
981 const StringFormatterArg& arg2,
982 const StringFormatterArg& arg3,
983 const StringFormatterArg& arg4,
984 const StringFormatterArg& arg5,
985 const StringFormatterArg& arg6,
986 const StringFormatterArg& arg7,
987 const StringFormatterArg& arg8,
988 const StringFormatterArg& arg9)
989{
990 StringFormatter sf(str);
991 sf.addArg(arg1.value());
992 sf.addArg(arg2.value());
993 sf.addArg(arg3.value());
994 sf.addArg(arg4.value());
995 sf.addArg(arg5.value());
996 sf.addArg(arg6.value());
997 sf.addArg(arg7.value());
998 sf.addArg(arg8.value());
999 sf.addArg(arg9.value());
1000 return sf.value();
1001}
1002
1003/*---------------------------------------------------------------------------*/
1004/*---------------------------------------------------------------------------*/
1005
1006String String::
1007concat(const StringFormatterArg& arg1)
1008{
1009 return arg1.value();
1010}
1011
1012String String::
1013concat(const StringFormatterArg& arg1,
1014 const StringFormatterArg& arg2)
1015{
1016 return arg1.value()+arg2.value();
1017}
1018
1019String String::
1020concat(const StringFormatterArg& arg1,
1021 const StringFormatterArg& arg2,
1022 const StringFormatterArg& arg3)
1023{
1024 return arg1.value()+arg2.value()+arg3.value();
1025}
1026
1027String String::
1028concat(const StringFormatterArg& arg1,
1029 const StringFormatterArg& arg2,
1030 const StringFormatterArg& arg3,
1031 const StringFormatterArg& arg4)
1032{
1033 return arg1.value()+arg2.value()+arg3.value()+arg4.value();
1034}
1035
1036/*---------------------------------------------------------------------------*/
1037/*---------------------------------------------------------------------------*/
1038
1040plural(const Integer n, const String & str, const bool with_number)
1041{
1042 return String::plural(n, str, str+"s", with_number);
1043}
1044
1045namespace
1046{
1047inline int
1048_abs(Integer a)
1049{
1050 return (a>0) ? a : (-a);
1051}
1052}
1053
1055plural(const Integer n, const String & str, const String & str2, const bool with_number)
1056{
1057 if (with_number)
1058 return String::concat(n, " ", ((_abs(n) > 1)?str2:str) );
1059 else
1060 return ((_abs(n) > 1)?str2:str);
1061}
1062
1063/*---------------------------------------------------------------------------*/
1064/*---------------------------------------------------------------------------*/
1065
1067contains(const String& arg1) const
1068{
1069 // Considère que la chaîne nulle est incluse dans toute chaîne
1070 if (arg1.null())
1071 return true;
1072 if (null())
1073 return false;
1074 std::string_view a = this->toStdStringView();
1075 std::string_view b = arg1.toStdStringView();
1076 return a.find(b) != std::string_view::npos;
1077}
1078
1079/*---------------------------------------------------------------------------*/
1080/*---------------------------------------------------------------------------*/
1081
1083endsWith(const String& s) const
1084{
1085 Span<const Byte> v = bytes();
1086 Span<const Byte> ref = s.bytes();
1087 Int64 ref_size = ref.size();
1088 Int64 v_size = v.size();
1089 if (ref_size>v_size)
1090 return false;
1091 const Byte* v_begin = &v[v_size-ref_size];
1092 return std::memcmp(v_begin,ref.data(),ref_size)==0;
1093}
1094
1095/*---------------------------------------------------------------------------*/
1096/*---------------------------------------------------------------------------*/
1097
1099startsWith(const String& s) const
1100{
1101 Span<const Byte> v = bytes();
1102 Span<const Byte> ref = s.bytes();
1103 Int64 ref_size = ref.size();
1104 Int64 v_size = v.size();
1105 if (ref_size>v_size)
1106 return false;
1107 return memcmp(v.data(),ref.data(),ref_size)==0;
1108}
1109
1110/*---------------------------------------------------------------------------*/
1111/*---------------------------------------------------------------------------*/
1112
1114substring(Int64 pos) const
1115{
1116 return substring(pos,length()-pos);
1117}
1118
1119/*---------------------------------------------------------------------------*/
1120/*---------------------------------------------------------------------------*/
1121
1123substring(Int64 pos,Int64 len) const
1124{
1125 if (pos<0)
1126 pos = 0;
1127 //TODO: normalement le _checkClone() n'est pas utile
1128 _checkClone();
1129 String s2(StringImpl::substring(m_p,pos,len));
1130 return s2;
1131}
1132
1133/*---------------------------------------------------------------------------*/
1134/*---------------------------------------------------------------------------*/
1135
1136String String::
1137join(String delim,ConstArrayView<String> strs)
1138{
1139 StringBuilder sb;
1140 for( Integer i=0, n=strs.size(); i<n; ++i ){
1141 if (i!=0)
1142 sb += delim;
1143 sb += strs[i];
1144 }
1145 return sb.toString();
1146}
1147
1148/*---------------------------------------------------------------------------*/
1149/*---------------------------------------------------------------------------*/
1150
1151extern "C++" bool
1152operator==(const String& a,const String& b)
1153{
1154 //cout << "COMPARE String String a='" << a << "' b='" << b << "'\n";
1155 if (a.m_const_ptr){
1156 if (b.m_const_ptr)
1157 return CStringUtils::isEqual(a.m_const_ptr,b.m_const_ptr);
1158 if (b.m_p)
1159 return b.m_p->isEqual(a.m_const_ptr);
1160 // Si je suis ici, 'b' est la chaine nulle et pas 'a'
1161 return false;
1162 }
1163
1164 if (b.m_const_ptr){
1165 if (a.m_p)
1166 return a.m_p->isEqual(b.m_const_ptr);
1167 return false;
1168 }
1169 if (a.m_p){
1170 if (b.m_p)
1171 return a.m_p->isEqual(b.m_p);
1172 // b est la chaine nulle mais pas moi
1173 return false;
1174 }
1175
1176 // Je suis la chaine nulle
1177 return b.m_p==nullptr;
1178}
1179
1180extern "C++" bool
1181operator==(const String& a,const char* b)
1182{
1183 return a==String(b);
1184}
1185
1186
1187extern "C++" bool
1188operator==(const char* a,const String& b)
1189{
1190 return String(a)==b;
1191}
1192
1193extern "C++" bool
1194operator<(const String& a,const String& b)
1195{
1196 bool v = a.isLess(b);
1197 //cout << "IsLess a='" << a << "' b='" << b << "' v=" << v << '\n';
1198 /*cout << "COMPARE A=" << a << " B=" << b << " V=" << v;
1199 if (a.m_const_ptr)
1200 cout << " AConst = " << a.m_const_ptr;
1201 if (b.m_const_ptr)
1202 cout << " BConst = " << b.m_const_ptr;
1203 cout << '\n';*/
1204 return v;
1205}
1206
1207extern "C++" String
1208operator+(const char* a,const String& b)
1209{
1210 return String(a)+b;
1211}
1212
1213/*---------------------------------------------------------------------------*/
1214/*---------------------------------------------------------------------------*/
1215
1216namespace
1217{
1218bool global_write_utf8 = false;
1219}
1220std::ostream&
1221operator<<(std::ostream& o,const String& str)
1222{
1223 // A utiliser plus tard lorsque l'encodage par défaut sera UTF8
1224 if (global_write_utf8)
1225 str.writeBytes(o);
1226 else
1227 o << str.localstr();
1228
1229 return o;
1230}
1231
1232/*---------------------------------------------------------------------------*/
1233/*---------------------------------------------------------------------------*/
1234
1236writeBytes(std::ostream& o) const
1237{
1238 Span<const Byte> v = this->bytes();
1239 Int64 vlen = v.size();
1240 o.write((const char*)v.data(),vlen);
1241}
1242
1243/*---------------------------------------------------------------------------*/
1244/*---------------------------------------------------------------------------*/
1245
1246std::istream&
1247operator>>(std::istream& i,String& str)
1248{
1249 std::string s;
1250 i >> s;
1251 str = s;
1252 return i;
1253}
1254
1255/*---------------------------------------------------------------------------*/
1256/*---------------------------------------------------------------------------*/
1257
1259{
1260 public:
1261 static std::vector<UChar>
1262 toUtf16BE(const String& str)
1263 {
1264 ConstArrayView<UChar> x{ str._internalUtf16BE() };
1265 Int32 n = x.size();
1266 if (n==0)
1267 return {};
1268 // x contient normalement toujours un zéro terminal que l'on ne met
1269 // pas dans le vecteur
1270 return { x.begin(), x.begin()+(n-1) };
1271 }
1272};
1273
1274/*---------------------------------------------------------------------------*/
1275/*---------------------------------------------------------------------------*/
1276
1277std::vector<UChar> StringUtils::
1278asUtf16BE(const String& str)
1279{
1280 return StringUtilsImpl::toUtf16BE(str);
1281}
1282
1283/*---------------------------------------------------------------------------*/
1284/*---------------------------------------------------------------------------*/
1285
1286} // End namespace Arccore
1287
1288/*---------------------------------------------------------------------------*/
1289/*---------------------------------------------------------------------------*/
1290
Fonctions utilitaires sur les chaînes de caractères.
Emulation de réel en précision arbitraire.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:212
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:422
Vue d'un tableau d'éléments de type T.
Definition Span.h:513
Constructeur de chaîne de caractère unicode.
String toString() const
Retourne la chaîne de caractères construite.
Vue sur une chaîne de caractères UTF-8.
Definition StringView.h:47
Chaîne de caractères unicode.
bool startsWith(const String &s) const
Indique si la chaîne commence par les caractères de s.
Definition String.cc:1099
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
static String plural(const Integer n, const String &str, const bool with_number=true)
Forme standard du pluriel par ajout d'un 's'.
Definition String.cc:1040
String upper() const
Transforme tous les caractères de la chaîne en majuscules.
Definition String.cc:466
Int64 length() const
Retourne la longueur de la chaîne.
Definition String.cc:338
String clone() const
Clone cette chaîne.
Definition String.cc:412
String lower() const
Transforme tous les caractères de la chaîne en minuscules.
Definition String.cc:478
void writeBytes(std::ostream &o) const
Écrit la chaîne au format UTF-8 sur le flot o.
Definition String.cc:1236
void internalDump(std::ostream &ostr) const
Affiche les infos internes de la classe.
Definition String.cc:719
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:227
ByteConstArrayView utf8() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:275
String()
Crée une chaîne nulle.
Int32 hashCode() const
Calcule une valeur de hashage pour cette chaîne de caractères.
Definition String.cc:733
friend ARCCORE_BASE_EXPORT bool operator==(const String &a, const String &b)
Compare deux chaînes unicode.
Definition String.cc:1152
static String replaceWhiteSpace(const String &rhs)
Effectue une normalisation des caractères espaces.
Definition String.cc:440
Span< const Byte > bytes() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:291
bool endsWith(const String &s) const
Indique si la chaîne se termine par les caractères de s.
Definition String.cc:1083
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
Definition String.cc:315
friend ARCCORE_BASE_EXPORT String operator+(const char *a, const String &b)
Ajoute deux chaînes.
Definition String.cc:1208
static String collapseWhiteSpace(const String &rhs)
Effectue une normalisation des caractères espaces.
Definition String.cc:452
ConstArrayView< UChar > utf16() const
Retourne la conversion de l'instance dans l'encodage UTF-16.
Definition String.cc:266
StringView view() const
Retourne une vue sur la chaîne actuelle.
Definition String.cc:367
String & operator=(const String &str)
Copie str dans cette instance.
Definition String.cc:169
bool contains(const String &s) const
Indique si la chaîne contient s.
Definition String.cc:1067
std::string_view toStdStringView() const
Retourne une vue de la STL sur la chaîne actuelle.
Definition String.cc:348
Integer len() const
Retourne la longueur de la chaîne en 32 bits.
Definition String.cc:328
String substring(Int64 pos) const
Sous-chaîne commençant à la position pos.
Definition String.cc:1114
bool isLess(const char *s1, const char *s2)
Retourne true si s1 est inférieur (ordre alphabétique) à s2 , false sinon.
bool isEqual(const char *s1, const char *s2)
Retourne true si s1 et s2 sont identiques, false sinon.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
constexpr __host__ __device__ Integer arccoreCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
bool operator<(const Item &item1, const Item &item2)
Compare deux entités.
Definition Item.h:542
std::istream & operator>>(std::istream &istr, eItemKind &item_kind)
Opérateur d'entrée depuis un flot.
double Real
Type représentant un réel.
ConstArrayView< UChar > UCharConstArrayView
Equivalent C d'un tableau à une dimension de caractères unicode.
Definition UtilsTypes.h:565
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:563
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:43
std::ostream & operator<<(std::ostream &ostr, eItemKind item_kind)
Opérateur de sortie sur un flot.
std::int32_t Int32
Type entier signé sur 32 bits.