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)