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