Arcane  v3.16.6.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/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)
32/*!
33 * \file StringUtils.h
34 *
35 * \brief Fonctions utilitaires sur les chaînes de caractères.
36 */
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
47String(const std::string& str)
48: m_p(new StringImpl(str))
49, m_const_ptr_size(-1)
50{
51 m_p->addReference();
52}
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
58String(std::string_view str)
59: m_p(new StringImpl(str))
60, m_const_ptr_size(-1)
61{
62 m_p->addReference();
63}
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
70: m_p(new StringImpl(str.toStdStringView()))
71, m_const_ptr(nullptr)
72, m_const_ptr_size(-1)
73{
74 m_p->addReference();
75}
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
81String(const UCharConstArrayView& ustr)
82: m_p(new StringImpl(ustr))
83, m_const_ptr_size(-1)
84{
85 m_p->addReference();
86}
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
92String(const Span<const Byte>& ustr)
93: m_p(new StringImpl(ustr))
94, m_const_ptr_size(-1)
95{
96 m_p->addReference();
97}
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
103String(StringImpl* impl)
104: m_p(impl)
105, m_const_ptr_size(-1)
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)))
117, m_const_ptr_size(-1)
118{
119 m_p->addReference();
120}
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
126String(char* str)
127: m_p(new StringImpl(str))
128, m_const_ptr_size(-1)
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)
140, m_const_ptr_size(-1)
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)
160, m_const_ptr_size(str.m_const_ptr_size)
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();
174 _removeReferenceIfNeeded();
175 _copyFields(str);
176 return (*this);
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
183operator=(String&& str)
184{
185 _removeReferenceIfNeeded();
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
240void String::
241_removeImplReference()
242{
243 m_p->removeReference();
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249ConstArrayView<UChar> String::
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.
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: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
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
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
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::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.