8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
36#define ARG1 (*(args+1))
37#define ARG2 (*(args+2))
38#define BOL(box) (box).Unbox<bool >()
39#define INT(box) (box).Unbox<integer>()
40#define FLT(box) (box).Unbox<double >()
41#define STR(box) (box).Unbox<String >()
42#define LEN(box) (box).UnboxLength()
43#define STR1K(str) String1K(STR(str))
44#define ALLOCS(str) String(scope.Allocator, str)
46#define FUNC( name,...) Box name( Scope& scope, \
49 { (void) scope; (void) args; (void) end; __VA_ARGS__ }
50#if !ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS
51# define TOINT(arg) arg
53# define TOINT(arg) integer(arg)
65 tmp.DbgDisableBufferReplacementWarning();
69 if( arg.IsType<
integer>() ) tmp <<
Dec( INT(arg), &scope.Formatter->DefaultNumberFormat);
70 else if( arg.IsType<
double >() ) tmp <<
Dec( FLT(arg), &scope.Formatter->DefaultNumberFormat);
76 return String(scope.Allocator, tmp);
85 buf.DbgDisableBufferReplacementWarning();
87 BoxesMA& formatterArgs= scope.Formatter->GetArgContainer();
89 formatterArgs.
Add( *args++ );
93 scope.Formatter->FormatArgs( buf );
100 return String( scope.Allocator, buf );
117FUNC(toUpper ,
return ALLOCS(STR1K(ARG0).
ToUpper()); )
118FUNC(toLower ,
return ALLOCS(STR1K(ARG0).
ToLower()); )
119FUNC(startsWith ,
return STR(ARG0).StartsWith<CHK,lang::Case::Sensitive>( STR(ARG1) ); )
120FUNC(startsWithC,
return BOL(ARG2) ? STR(ARG0).StartsWith<CHK,lang::Case::Ignore >( STR(ARG1) )
121 : STR(ARG0).StartsWith<CHK,lang::Case::Sensitive>( STR(ARG1) ); )
122FUNC(endsWith ,
return STR(ARG0). EndsWith<CHK,lang::Case::Sensitive>( STR(ARG1) ); )
123FUNC(endsWithC ,
return BOL(ARG2) ? STR(ARG0). EndsWith<CHK,lang::Case::Ignore >( STR(ARG1) )
124 : STR(ARG0). EndsWith<CHK,lang::Case::Sensitive>( STR(ARG1) ); )
125FUNC(substr ,
return STR(ARG0).
Substring( INT(ARG1) ); )
126FUNC(substr2 ,
return STR(ARG0).
Substring( INT(ARG1), INT(ARG2) ); )
127FUNC(idxof ,
String needle= STR(ARG1);
return needle.
Length() == 1 ? STR(ARG0).IndexOf ( needle[0], 0 )
128 : STR(ARG0).IndexOf( needle , 0 ); )
129FUNC(count ,
String needle= STR(ARG1);
return needle.
Length() == 1 ? STR(ARG0).CountChar ( needle[0] )
130 : STR(ARG0).Count ( needle , 0 ); )
132FUNC(trim ,
return Substring(STR(ARG0)).Trim ( ); )
134FUNC(trimStart ,
return Substring(STR(ARG0)).TrimStart( ); )
136FUNC(trimEnd ,
return Substring(STR(ARG0)).TrimEnd ( ); )
139FUNC(parsei ,
integer result;
Substring(STR(ARG0)).
ConsumeInt (result, &scope.Formatter->DefaultNumberFormat);
return result; )
140FUNC(parsef ,
double result;
Substring(STR(ARG0)).
ConsumeFloat(result, &scope.Formatter->DefaultNumberFormat);
return result; )
142FUNC(token ,
Tokenizer tknzr( STR(ARG0), STR(ARG1).CharAtStart() );
143 for(
integer i= INT(ARG2) ; i >= 0 ; --i )
145 return tknzr.Actual; )
148 buf <<
Hex( uint64_t(INT(ARG0)),
149 args + 1 != end ?
int(INT(ARG1)) : 0,
150 &scope.Formatter->DefaultNumberFormat );
151 return ALLOCS(buf); )
153 buf <<
Oct( uint64_t(INT(ARG0)),
154 args + 1 != end ?
int(INT(ARG1)) : 0,
155 &scope.Formatter->DefaultNumberFormat );
156 return ALLOCS(buf); )
158 buf <<
Bin( uint64_t(INT(ARG0)),
159 args + 1 != end ?
int(INT(ARG1)) : 0,
160 &scope.Formatter->DefaultNumberFormat );
161 return ALLOCS(buf); )
167 String needle = STR(ARG1);
168 String replacement= STR(ARG2);
171 if( needle.Length() == 1 && replacement.Length() == 1 )
174 result.SearchAndReplace( needle[0], replacement[0], 0 );
175 return ALLOCS(result);
180 buf.DbgDisableBufferReplacementWarning();
182 buf.SearchAndReplace( needle, replacement, 0 );
190 buf.DbgDisableBufferReplacementWarning();
191 for(
integer i= INT(ARG1) ; i > 0 ; --i )
199FUNC(boolNot,
return LEN(ARG0) == 0; )
206FUNC(add_SI,
return ALLOCS(STR1K(ARG0) <<
Dec( INT(ARG1), &scope.Formatter->DefaultNumberFormat )); )
207FUNC(add_SF, return ALLOCS(STR1K(ARG0) <<
Dec( FLT(ARG1), &scope.
Formatter->DefaultNumberFormat )); )
210FUNC(add_IS, return ALLOCS(
String1K() <<
Dec( INT(ARG0), &scope.
Formatter->DefaultNumberFormat) << STR(ARG1)); )
211FUNC(add_FS, return ALLOCS(
String1K() <<
Dec( FLT(ARG0), &scope.
Formatter->DefaultNumberFormat) << STR(ARG1)); )
212FUNC(add_SS, return ALLOCS(
String1K(STR(ARG0)) << STR(ARG1)); )
213FUNC(add_SX, return ALLOCS(
String1K(STR(ARG0)) << ARG1); )
214FUNC(add_XS, return ALLOCS(
String1K( ARG0) << STR(ARG1)); )
217FUNC( sm, return STR(ARG0) < ( STR(ARG1) ); )
218FUNC( smEq, return STR(ARG0) <= ( STR(ARG1) ); )
219FUNC( gt, return STR(ARG0) > ( STR(ARG1) ); )
220FUNC( gtEq, return STR(ARG0) >= ( STR(ARG1) ); )
221FUNC( eq, return STR(ARG0).
Equals( STR(ARG1) ); )
222FUNC( neq, return !STR(ARG0).
Equals( STR(ARG1) ); )
224FUNC( arr, return STR(ARG0).
Substring( INT(ARG1), 1); )
226FUNC( compSS, return TOINT( STR(ARG0).CompareTo<CHK
ALIB_COMMA lang::Case::Sensitive>( STR(ARG1) ) ); )
227FUNC(compSSB, return TOINT( BOL(ARG2) ? STR(ARG0).CompareTo<CHK
ALIB_COMMA lang::Case::Ignore >( STR(ARG1) )
228 : STR(ARG0).CompareTo<CHK
ALIB_COMMA lang::Case::Sensitive>( STR(ARG1) ) ); )
233DOX_MARKER([DOX_EXPR_CTRES_1])
234struct ScopeWildcardMatcher : public ScopeResource
240 virtual ~ScopeWildcardMatcher()
override {}
242DOX_MARKER([DOX_EXPR_CTRES_1])
244DOX_MARKER([DOX_EXPR_CTRES_6])
247 String haystack= STR(ARG0);
248 String pattern = STR(ARG1);
252 if( !scope.IsCompileTime() )
256 keyString.DbgDisableBufferReplacementWarning();
257 keyString << pattern;
258 auto storedMatcher= scope.EvalScopeVMMembers->CTScope->NamedResources->Find( keyString );
259 if( storedMatcher != scope.EvalScopeVMMembers->CTScope->NamedResources->end() )
260 return dynamic_cast<ScopeWildcardMatcher*
>( storedMatcher.Mapped() )
261 ->matcher.Match( haystack, sensitivity );
263DOX_MARKER([DOX_EXPR_CTRES_6])
265DOX_MARKER([DOX_EXPR_CTRES_7])
270 return matcher.Match( haystack, sensitivity );
273DOX_MARKER([DOX_EXPR_CTRES_7])
278#if ALIB_FEAT_BOOST_REGEX && (!ALIB_CHARACTERS_WIDE || ALIB_CHARACTERS_NATIVE_WCHAR)
279struct ScopeRegexMatcher :
public ScopeResource
285 virtual ~ScopeRegexMatcher()
override {}
290 String haystack= STR(ARG0);
291 String pattern = STR(ARG1);
293 if( !scope.IsCompileTime() )
297 keyString.DbgDisableBufferReplacementWarning();
298 keyString << pattern;
299 auto storedMatcher= scope.EvalScopeVMMembers->CTScope->NamedResources->Find( keyString );
300 if( storedMatcher != scope.EvalScopeVMMembers->CTScope->NamedResources->end() )
302 ScopeRegexMatcher* matcher=
dynamic_cast<ScopeRegexMatcher*
>( storedMatcher->second );
303 return matcher->matcher.Match( haystack );
310 return matcher.Match( haystack );
338 #if ALIB_FEAT_BOOST_REGEX && (!ALIB_CHARACTERS_WIDE || ALIB_CHARACTERS_NATIVE_WCHAR)
356 AddOperators( operatorTableStrings );
359 #if ALIB_FEAT_BOOST_REGEX && (!ALIB_CHARACTERS_WIDE || ALIB_CHARACTERS_NATIVE_WCHAR)
360 constexpr int tableSize= 25;
362 constexpr int tableSize= 24;
365 Token functionNames[tableSize];
366 strings::util::LoadResourcedTokens( EXPRESSIONS,
"CPS", functionNames
368 Token* descriptor= functionNames;
373 { *descriptor++, constNL },
374 { *descriptor++, constTAB },
413 #if ALIB_FEAT_BOOST_REGEX && (!ALIB_CHARACTERS_WIDE || ALIB_CHARACTERS_NATIVE_WCHAR)
419 "Descriptor table size mismatch: Consumed {} descriptors, {} available.",
420 descriptor - functionNames, tableSize )
424bool genericConcatenation( Type type )
428 || type.IsType<
double >()
429 || type.IsType<
String >() );
434DOX_MARKER([DOX_EXPR_CTRES_2])
435bool Strings::TryCompilation( CIFunction& ciFunction )
438 if( !Calculus::TryCompilation( ciFunction ) )
440DOX_MARKER([DOX_EXPR_CTRES_2])
442#if ALIB_FEAT_BOOST_REGEX && (!ALIB_CHARACTERS_WIDE || ALIB_CHARACTERS_NATIVE_WCHAR)
443 if( ciFunction.Callback == regex && (ciFunction.ArgsBegin + 1)->UnboxLength() > 0)
445 String pattern= (ciFunction.ArgsBegin + 1)->Unbox<String>();
447 keyString.DbgDisableBufferReplacementWarning();
448 keyString << pattern;
449 auto storedMatcher= ciFunction.CompileTimeScope.NamedResources->Find( keyString );
450 if( storedMatcher == ciFunction.CompileTimeScope.NamedResources->end() )
452 auto& alloc= ciFunction.CompileTimeScope.Allocator;
453 ScopeRegexMatcher* matcher= alloc().New<ScopeRegexMatcher>();
454 matcher->matcher.Compile( pattern );
455 ciFunction.CompileTimeScope.NamedResources->EmplaceOrAssign(
462DOX_MARKER([DOX_EXPR_CTRES_3])
463 if( ciFunction.Callback == wldcrd && (ciFunction.ArgsBegin + 1)->UnboxLength() > 0)
465DOX_MARKER([DOX_EXPR_CTRES_3])
466DOX_MARKER([DOX_EXPR_CTRES_4])
467 String pattern= (ciFunction.ArgsBegin + 1)->Unbox<String>();
469 keyString.DbgDisableBufferReplacementWarning();
470 keyString << pattern;
471DOX_MARKER([DOX_EXPR_CTRES_4])
472DOX_MARKER([DOX_EXPR_CTRES_5])
473 auto hashCode = keyString.Hashcode();
474 auto storedMatcher= ciFunction.CompileTimeScope.NamedResources->Find( keyString, hashCode );
475 if( storedMatcher == ciFunction.CompileTimeScope.NamedResources->end() )
477 auto& alloc= ciFunction.CompileTimeScope.Allocator;
478 ScopeWildcardMatcher* matcher= alloc().New<ScopeWildcardMatcher>();
479 matcher->matcher.Compile( pattern );
480 NString keyCopy( ciFunction.CompileTimeScope.Allocator, keyString );
481 ciFunction.CompileTimeScope.NamedResources->InsertUnique( std::make_pair(keyCopy, matcher),
486DOX_MARKER([DOX_EXPR_CTRES_5])
490bool Strings::TryCompilation( CIBinaryOp& ciBinaryOp )
492 Box& lhs= * ciBinaryOp.ArgsBegin;
493 Box& rhs= *(ciBinaryOp.ArgsBegin + 1);
496 if( ciBinaryOp.Operator ==
A_CHAR(
"+") )
498 bool argsAreConst= ciBinaryOp.LhsIsConst && ciBinaryOp.RhsIsConst;
500 if( lhs.IsType<String>() && genericConcatenation(rhs) )
505 ciBinaryOp.TypeOrValue = add_SX( ciBinaryOp.CompileTimeScope,
506 ciBinaryOp.ArgsBegin,
507 ciBinaryOp.ArgsEnd );
508 ALIB_DBG( ciBinaryOp.DbgCallbackName =
"add_SX"; )
512 ciBinaryOp.Callback = add_SX;
513 ciBinaryOp.TypeOrValue = Types::String;
517 if( genericConcatenation(lhs) && rhs.IsType<String>() )
521 ciBinaryOp.TypeOrValue = add_XS( ciBinaryOp.CompileTimeScope,
522 ciBinaryOp.ArgsBegin,
523 ciBinaryOp.ArgsEnd );
524 ALIB_DBG( ciBinaryOp.DbgCallbackName =
"add_XS"; )
528 ciBinaryOp.Callback = add_XS;
529 ciBinaryOp.TypeOrValue = Types::String;
535 if( !Calculus::TryCompilation( ciBinaryOp ) )
540#if ALIB_FEAT_BOOST_REGEX && (!ALIB_CHARACTERS_WIDE || ALIB_CHARACTERS_NATIVE_WCHAR)
541 if( ciBinaryOp.Operator ==
A_CHAR(
"%") && !ciBinaryOp.LhsIsConst && ciBinaryOp.RhsIsConst )
543 String pattern= (ciBinaryOp.ArgsBegin + 1)->Unbox<String>();
544 NString128 keyString(A_CHAR(
"_re"));
545 keyString.DbgDisableBufferReplacementWarning();
546 keyString << pattern;
547 auto hashCode = keyString.Hashcode();
549 auto storedMatcher= ciBinaryOp.CompileTimeScope.NamedResources->Find( keyString, hashCode );
550 if( storedMatcher == ciBinaryOp.CompileTimeScope.NamedResources->end() )
552 auto& alloc= ciBinaryOp.CompileTimeScope.Allocator;
553 ScopeRegexMatcher* matcher= alloc().New<ScopeRegexMatcher>();
554 matcher->matcher.Compile( pattern );
555 ciBinaryOp.CompileTimeScope.NamedResources->InsertOrAssign(
556 NString(alloc, keyString ),
564 if( ciBinaryOp.Operator ==
A_CHAR(
"*") && !ciBinaryOp.LhsIsConst && ciBinaryOp.RhsIsConst )
566 String pattern= (ciBinaryOp.ArgsBegin + 1)->Unbox<String>();
567 NString128 keyString(A_CHAR(
"_wc"));
568 keyString.DbgDisableBufferReplacementWarning();
569 keyString << pattern;
570 auto hashCode = keyString.Hashcode();
572 auto storedMatcher= ciBinaryOp.CompileTimeScope.NamedResources->Find( keyString, hashCode );
573 if( storedMatcher == ciBinaryOp.CompileTimeScope.NamedResources->end() )
575 auto& alloc= ciBinaryOp.CompileTimeScope.Allocator;
576 ScopeWildcardMatcher* matcher= alloc().New<ScopeWildcardMatcher>();
577 matcher->matcher.Compile( pattern );
579 NString keyCopy(alloc, keyString);
580 ciBinaryOp.CompileTimeScope.NamedResources->InsertUnique( std::make_pair(keyCopy, matcher),
601#undef BIN_ALIAS_ENTRY
constexpr integer Length() const
TSubstring & TrimStart(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
ALIB_DLL bool ConsumeFloat(double &result, TNumberFormat< TChar > *numberFormat=nullptr)
bool ConsumeInt(std::integral auto &result, TNumberFormat< TChar > *numberFormat=nullptr)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
TSubstring & TrimEnd(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
ALIB_DLL TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
#define CALCULUS_CALLBACK(func)
#define CALCULUS_SIGNATURE(BoxPointerArray)
#define ALIB_ASSERT_ERROR(cond, domain,...)
ALIB_DLL Box CBFormat(Scope &scope, ArgIterator args, ArgIterator)
ALIB_DLL Box CBToString(Scope &scope, ArgIterator args, ArgIterator)
@ Equals
Verbal alias "Equals" to operator '=='.
StdVectorMono< Box >::iterator ArgIterator
platform_specific integer
Case
Denotes upper and lower case character treatment.
@ Keep
Keep whitespaces in string.
strings::TDec< character > Dec
Type alias in namespace alib.
NLocalString< 128 > NString128
Type alias name for TLocalString<nchar,128>.
strings::util::Token Token
Type alias in namespace alib.
LocalString< 256 > String256
Type alias name for TLocalString<character,256>.
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace alib.
lox::Scope Scope
Type alias in namespace alib.
LocalString< 128 > String128
Type alias name for TLocalString<character,128>.
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
lang::integer integer
Type alias in namespace alib.
strings::TString< nchar > NString
Type alias in namespace alib.
strings::TOct< character > Oct
Type alias in namespace alib.
strings::util::TWildcardMatcher< character > WildcardMatcher
Type alias in namespace alib.
strings::THex< character > Hex
Type alias in namespace alib.
format::Formatter Formatter
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
LocalString< 1024 > String1K
Type alias name for TLocalString<character,1024>.
strings::util::RegexMatcher RegexMatcher
Type alias in namespace alib.
exceptions::Exception Exception
Type alias in namespace alib.
boxing::TBoxes< MonoAllocator > BoxesMA
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
expressions::Compiler Compiler
Type alias in namespace alib.
strings::TBin< character > Bin
Type alias in namespace alib.
LocalString< 2048 > String2K
Type alias name for TLocalString<character,2048>.
strings::TSubstring< character > Substring
Type alias in namespace alib.
static ALIB_DLL Box Integer
Sample type-box for integer types. (Precisely for type integer.)
static ALIB_DLL Box Boolean
Sample type-box for C++ type bool.
static ALIB_DLL Box Void
Sample type-box for C++ type void.
static ALIB_DLL Box Float
Sample type-box for C++ type double.
static ALIB_DLL Box String
static constexpr CTInvokable CTI
const std::tuple< String, Type, Type, CallbackDecl, Type, CTInvokable > OperatorTableEntry
ALIB_DLL Strings(Compiler &compiler)