LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/util - string.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 270 292 92.5 %
Date: 2026-04-26 10:45:53 Functions: 34 35 97.1 %
Branches: 204 256 79.7 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * Implementation of the string data type.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "util/string.h"
      14                 :            : 
      15                 :            : #include <algorithm>
      16                 :            : #include <climits>
      17                 :            : #include <iostream>
      18                 :            : #include <limits>
      19                 :            : #include <sstream>
      20                 :            : 
      21                 :            : #include "base/check.h"
      22                 :            : #include "base/exception.h"
      23                 :            : #include "util/hash.h"
      24                 :            : 
      25                 :            : using namespace std;
      26                 :            : 
      27                 :            : namespace cvc5::internal {
      28                 :            : 
      29                 :            : static_assert(UCHAR_MAX == 255, "Unsigned char is assumed to have 256 values.");
      30                 :            : 
      31                 :          2 : String::String(const std::wstring& s)
      32                 :            : {
      33                 :          2 :   d_str.resize(s.size());
      34         [ -  + ]:          2 :   for (size_t i = 0, n = s.size(); i < n; ++i)
      35                 :            :   {
      36                 :          0 :     unsigned u = static_cast<unsigned>(s[i]);
      37                 :            : #ifdef CVC5_ASSERTIONS
      38                 :          0 :     Assert(u < num_codes());
      39                 :            : #endif
      40                 :          0 :     d_str[i] = u;
      41                 :            :   }
      42                 :          2 : }
      43                 :            : 
      44                 :         84 : String::String(const std::u32string& s)
      45                 :            : {
      46                 :         84 :   d_str.resize(s.size());
      47         [ +  + ]:         96 :   for (size_t i = 0, n = s.size(); i < n; ++i)
      48                 :            :   {
      49                 :         12 :     d_str[i] = static_cast<unsigned>(s[i]);
      50                 :            :   }
      51                 :         84 : }
      52                 :            : 
      53                 :    5267089 : String::String(const std::vector<unsigned>& s) : d_str(s)
      54                 :            : {
      55                 :            : #ifdef CVC5_ASSERTIONS
      56         [ +  + ]:    7172246 :   for (unsigned u : d_str)
      57                 :            :   {
      58 [ -  + ][ -  + ]:    1905157 :     Assert(u < num_codes());
                 [ -  - ]
      59                 :            :   }
      60                 :            : #endif
      61                 :    5267089 : }
      62                 :            : 
      63                 :    5592800 : int String::cmp(const String& y) const
      64                 :            : {
      65         [ +  + ]:    5592800 :   if (size() != y.size())
      66                 :            :   {
      67         [ +  + ]:      17502 :     return size() < y.size() ? -1 : 1;
      68                 :            :   }
      69         [ +  + ]:    8037964 :   for (unsigned int i = 0; i < size(); ++i)
      70                 :            :   {
      71         [ +  + ]:    2476364 :     if (d_str[i] != y.d_str[i])
      72                 :            :     {
      73                 :      13698 :       unsigned cp = d_str[i];
      74                 :      13698 :       unsigned cpy = y.d_str[i];
      75         [ +  + ]:      13698 :       return cp < cpy ? -1 : 1;
      76                 :            :     }
      77                 :            :   }
      78                 :    5561600 :   return 0;
      79                 :            : }
      80                 :            : 
      81                 :       9431 : String String::concat(const String& other) const
      82                 :            : {
      83                 :       9431 :   std::vector<unsigned int> ret_vec(d_str);
      84                 :       9431 :   ret_vec.insert(ret_vec.end(), other.d_str.begin(), other.d_str.end());
      85                 :      18862 :   return String(ret_vec);
      86                 :       9431 : }
      87                 :            : 
      88                 :      32641 : bool String::strncmp(const String& y, std::size_t n) const
      89                 :            : {
      90         [ +  + ]:      32641 :   std::size_t b = (size() >= y.size()) ? size() : y.size();
      91         [ +  + ]:      32641 :   std::size_t s = (size() <= y.size()) ? size() : y.size();
      92         [ -  + ]:      32641 :   if (n > s)
      93                 :            :   {
      94         [ -  - ]:          0 :     if (b == s)
      95                 :            :     {
      96                 :          0 :       n = s;
      97                 :            :     }
      98                 :            :     else
      99                 :            :     {
     100                 :          0 :       return false;
     101                 :            :     }
     102                 :            :   }
     103         [ +  + ]:     129908 :   for (std::size_t i = 0; i < n; ++i)
     104                 :            :   {
     105         [ +  + ]:     106380 :     if (d_str[i] != y.d_str[i]) return false;
     106                 :            :   }
     107                 :      23528 :   return true;
     108                 :            : }
     109                 :            : 
     110                 :      24554 : bool String::rstrncmp(const String& y, std::size_t n) const
     111                 :            : {
     112         [ +  + ]:      24554 :   std::size_t b = (size() >= y.size()) ? size() : y.size();
     113         [ +  + ]:      24554 :   std::size_t s = (size() <= y.size()) ? size() : y.size();
     114         [ -  + ]:      24554 :   if (n > s)
     115                 :            :   {
     116         [ -  - ]:          0 :     if (b == s)
     117                 :            :     {
     118                 :          0 :       n = s;
     119                 :            :     }
     120                 :            :     else
     121                 :            :     {
     122                 :          0 :       return false;
     123                 :            :     }
     124                 :            :   }
     125         [ +  + ]:      57534 :   for (std::size_t i = 0; i < n; ++i)
     126                 :            :   {
     127         [ +  + ]:      41104 :     if (d_str[size() - i - 1] != y.d_str[y.size() - i - 1]) return false;
     128                 :            :   }
     129                 :      16430 :   return true;
     130                 :            : }
     131                 :            : 
     132                 :     239720 : void String::addCharToInternal(unsigned char ch, std::vector<unsigned>& str)
     133                 :            : {
     134                 :            :   // if not a printable character
     135 [ +  - ][ -  + ]:     239720 :   if (ch > 127 || ch < 32)
     136                 :            :   {
     137                 :          0 :     std::stringstream serr;
     138                 :            :     serr << "Illegal string character: \"" << ch
     139                 :          0 :          << "\", must use escape sequence";
     140                 :          0 :     throw cvc5::internal::Exception(serr.str());
     141                 :          0 :   }
     142                 :            :   else
     143                 :            :   {
     144                 :     239720 :     str.push_back(static_cast<unsigned>(ch));
     145                 :            :   }
     146                 :     239720 : }
     147                 :            : 
     148                 :     146582 : std::vector<unsigned> String::toInternal(const std::string& s,
     149                 :            :                                          bool useEscSequences)
     150                 :            : {
     151                 :     146582 :   std::vector<unsigned> str;
     152                 :     146582 :   unsigned i = 0;
     153         [ +  + ]:     368810 :   while (i < s.size())
     154                 :            :   {
     155                 :            :     // get the current character
     156                 :     222228 :     char si = s[i];
     157 [ +  + ][ +  + ]:     222228 :     if (si != '\\' || !useEscSequences)
     158                 :            :     {
     159                 :     218386 :       addCharToInternal(si, str);
     160                 :     218386 :       ++i;
     161                 :     218386 :       continue;
     162                 :            :     }
     163                 :            :     // the vector of characters, in case we fail to read an escape sequence
     164                 :       3842 :     std::vector<unsigned> nonEscCache;
     165                 :            :     // process the '\'
     166                 :       3842 :     addCharToInternal(si, nonEscCache);
     167                 :       3842 :     ++i;
     168                 :            :     // are we an escape sequence?
     169                 :       3842 :     bool isEscapeSequence = true;
     170                 :            :     // the string corresponding to the hexadecimal code point
     171                 :       3842 :     std::stringstream hexString;
     172                 :            :     // is the slash followed by a 'u'? Could be last character.
     173 [ +  - ][ +  + ]:       3842 :     if (i >= s.size() || s[i] != 'u')
                 [ +  + ]
     174                 :            :     {
     175                 :        333 :       isEscapeSequence = false;
     176                 :            :     }
     177                 :            :     else
     178                 :            :     {
     179                 :            :       // process the 'u'
     180                 :       3509 :       addCharToInternal(s[i], nonEscCache);
     181                 :       3509 :       ++i;
     182                 :       3509 :       bool isStart = true;
     183                 :       3509 :       bool isEnd = false;
     184                 :       3509 :       bool hasBrace = false;
     185         [ +  + ]:      14017 :       while (i < s.size())
     186                 :            :       {
     187                 :            :         // add the next character
     188                 :      13992 :         si = s[i];
     189         [ +  + ]:      13992 :         if (isStart)
     190                 :            :         {
     191                 :       3503 :           isStart = false;
     192                 :            :           // possibly read '{'
     193         [ +  + ]:       3503 :           if (si == '{')
     194                 :            :           {
     195                 :       3416 :             hasBrace = true;
     196                 :       3416 :             addCharToInternal(si, nonEscCache);
     197                 :       3416 :             ++i;
     198                 :       3416 :             continue;
     199                 :            :           }
     200                 :            :         }
     201         [ +  + ]:      10489 :         else if (si == '}')
     202                 :            :         {
     203                 :            :           // can only end if we had an open brace and read at least one digit
     204 [ +  - ][ +  + ]:       3391 :           isEscapeSequence = hasBrace && !hexString.str().empty();
         [ +  - ][ -  - ]
     205                 :       3391 :           isEnd = true;
     206                 :       3391 :           addCharToInternal(si, nonEscCache);
     207                 :       3391 :           ++i;
     208                 :       3391 :           break;
     209                 :            :         }
     210                 :            :         // must be a hex digit at this point
     211         [ +  + ]:       7185 :         if (!isHexDigit(static_cast<unsigned>(si)))
     212                 :            :         {
     213                 :          9 :           isEscapeSequence = false;
     214                 :          9 :           break;
     215                 :            :         }
     216                 :       7176 :         hexString << si;
     217                 :       7176 :         addCharToInternal(si, nonEscCache);
     218                 :       7176 :         ++i;
     219 [ +  + ][ +  + ]:       7176 :         if (!hasBrace && hexString.str().size() == 4)
         [ +  + ][ +  + ]
                 [ -  - ]
     220                 :            :         {
     221                 :            :           // will be finished reading \ u d_3 d_2 d_1 d_0 with no parens
     222                 :         81 :           isEnd = true;
     223                 :         81 :           break;
     224                 :            :         }
     225 [ +  + ][ +  + ]:       7095 :         else if (hasBrace && hexString.str().size() > 5)
         [ +  + ][ +  + ]
                 [ -  - ]
     226                 :            :         {
     227                 :            :           // too many digits enclosed in brace, not an escape sequence
     228                 :          3 :           isEscapeSequence = false;
     229                 :          3 :           break;
     230                 :            :         }
     231                 :            :       }
     232         [ +  + ]:       3509 :       if (!isEnd)
     233                 :            :       {
     234                 :            :         // if we were interrupted before ending, then this is not a valid
     235                 :            :         // escape sequence
     236                 :         37 :         isEscapeSequence = false;
     237                 :            :       }
     238                 :            :     }
     239         [ +  + ]:       3842 :     if (isEscapeSequence)
     240                 :            :     {
     241                 :       3469 :       Assert(!hexString.str().empty() && hexString.str().size() <= 5);
     242                 :            :       // Otherwise, we add the escaped character.
     243                 :            :       // This is guaranteed not to overflow due to the length of hstr.
     244                 :            :       uint32_t val;
     245                 :       3469 :       hexString >> std::hex >> val;
     246         [ +  + ]:       3469 :       if (val >= num_codes())
     247                 :            :       {
     248                 :            :         // Failed due to being out of range. This can happen for strings of
     249                 :            :         // the form \ u { d_4 d_3 d_2 d_1 d_0 } where d_4 is a hexadecimal not
     250                 :            :         // in the range [0-2], or the code point is exactly num_codes().
     251                 :          9 :         isEscapeSequence = false;
     252                 :            :       }
     253                 :            :       else
     254                 :            :       {
     255                 :       3460 :         str.push_back(val);
     256                 :            :       }
     257                 :            :     }
     258                 :            :     // if we did not successfully parse an escape sequence, we add back all
     259                 :            :     // characters that we cached
     260         [ +  + ]:       3842 :     if (!isEscapeSequence)
     261                 :            :     {
     262                 :        382 :       str.insert(str.end(), nonEscCache.begin(), nonEscCache.end());
     263                 :            :     }
     264                 :       3842 :   }
     265                 :            : #ifdef CVC5_ASSERTIONS
     266         [ +  + ]:     369004 :   for (unsigned u : str)
     267                 :            :   {
     268 [ -  + ][ -  + ]:     222422 :     Assert(u < num_codes());
                 [ -  - ]
     269                 :            :   }
     270                 :            : #endif
     271                 :     146582 :   return str;
     272                 :          0 : }
     273                 :            : 
     274                 :     100912 : unsigned String::front() const
     275                 :            : {
     276 [ -  + ][ -  + ]:     100912 :   Assert(!d_str.empty());
                 [ -  - ]
     277                 :     100912 :   return d_str.front();
     278                 :            : }
     279                 :            : 
     280                 :       1649 : unsigned String::back() const
     281                 :            : {
     282 [ -  + ][ -  + ]:       1649 :   Assert(!d_str.empty());
                 [ -  - ]
     283                 :       1649 :   return d_str.back();
     284                 :            : }
     285                 :            : 
     286                 :       9761 : std::size_t String::overlap(const String& y) const
     287                 :            : {
     288         [ +  + ]:       9761 :   std::size_t i = size() < y.size() ? size() : y.size();
     289         [ +  + ]:      18921 :   for (; i > 0; i--)
     290                 :            :   {
     291                 :      11629 :     String s = suffix(i);
     292                 :      11629 :     String p = y.prefix(i);
     293         [ +  + ]:      11629 :     if (s == p)
     294                 :            :     {
     295                 :       2469 :       return i;
     296                 :            :     }
     297 [ +  + ][ +  + ]:      14098 :   }
     298                 :       7292 :   return i;
     299                 :            : }
     300                 :            : 
     301                 :       3887 : std::size_t String::roverlap(const String& y) const
     302                 :            : {
     303         [ +  + ]:       3887 :   std::size_t i = size() < y.size() ? size() : y.size();
     304         [ +  + ]:       5510 :   for (; i > 0; i--)
     305                 :            :   {
     306                 :       2676 :     String s = prefix(i);
     307                 :       2676 :     String p = y.suffix(i);
     308         [ +  + ]:       2676 :     if (s == p)
     309                 :            :     {
     310                 :       1053 :       return i;
     311                 :            :     }
     312 [ +  + ][ +  + ]:       3729 :   }
     313                 :       2834 :   return i;
     314                 :            : }
     315                 :            : 
     316                 :      72324 : std::string String::toString(bool useEscSequences) const
     317                 :            : {
     318                 :      72324 :   std::stringstream str;
     319         [ +  + ]:     286573 :   for (unsigned int i = 0; i < size(); ++i)
     320                 :            :   {
     321                 :            :     // we always print backslash as a code point so that it cannot be
     322                 :            :     // interpreted as specifying part of a code point, e.g. the string '\' +
     323                 :            :     // 'u' + '0' of length three.
     324 [ +  + ][ +  + ]:     214249 :     if (isPrintable(d_str[i]) && d_str[i] != '\\' && !useEscSequences)
         [ +  - ][ +  + ]
     325                 :            :     {
     326                 :     213241 :       str << static_cast<char>(d_str[i]);
     327                 :            :     }
     328                 :            :     else
     329                 :            :     {
     330                 :       1008 :       std::stringstream ss;
     331                 :       1008 :       ss << std::hex << d_str[i];
     332                 :       1008 :       str << "\\u{" << ss.str() << "}";
     333                 :       1008 :     }
     334                 :            :   }
     335                 :     144648 :   return str.str();
     336                 :      72324 : }
     337                 :            : 
     338                 :          2 : std::wstring String::toWString() const
     339                 :            : {
     340                 :          2 :   std::wstring res(size(), static_cast<wchar_t>(0));
     341         [ -  + ]:          2 :   for (std::size_t i = 0; i < size(); ++i)
     342                 :            :   {
     343                 :          0 :     res[i] = static_cast<wchar_t>(d_str[i]);
     344                 :            :   }
     345                 :          2 :   return res;
     346                 :          0 : }
     347                 :            : 
     348                 :        159 : std::u32string String::toU32String() const
     349                 :            : {
     350                 :        159 :   std::u32string res(size(), static_cast<char32_t>(0));
     351         [ +  + ]:        594 :   for (std::size_t i = 0; i < size(); ++i)
     352                 :            :   {
     353                 :        435 :     res[i] = static_cast<char32_t>(d_str[i]);
     354                 :            :   }
     355                 :        159 :   return res;
     356                 :          0 : }
     357                 :            : 
     358                 :        391 : bool String::isLeq(const String& y) const
     359                 :            : {
     360         [ +  + ]:        625 :   for (unsigned i = 0; i < size(); ++i)
     361                 :            :   {
     362         [ +  + ]:        503 :     if (i >= y.size())
     363                 :            :     {
     364                 :         44 :       return false;
     365                 :            :     }
     366                 :        459 :     unsigned ci = d_str[i];
     367                 :        459 :     unsigned cyi = y.d_str[i];
     368         [ +  + ]:        459 :     if (ci > cyi)
     369                 :            :     {
     370                 :         97 :       return false;
     371                 :            :     }
     372         [ +  + ]:        362 :     if (ci < cyi)
     373                 :            :     {
     374                 :        128 :       return true;
     375                 :            :     }
     376                 :            :   }
     377                 :        122 :   return true;
     378                 :            : }
     379                 :            : 
     380                 :         20 : bool String::isRepeated() const
     381                 :            : {
     382         [ +  - ]:         20 :   if (size() > 1)
     383                 :            :   {
     384                 :         20 :     unsigned int f = d_str[0];
     385         [ +  + ]:         34 :     for (unsigned i = 1; i < size(); ++i)
     386                 :            :     {
     387         [ +  + ]:         20 :       if (f != d_str[i]) return false;
     388                 :            :     }
     389                 :            :   }
     390                 :         14 :   return true;
     391                 :            : }
     392                 :            : 
     393                 :         18 : bool String::tailcmp(const String& y, int& c) const
     394                 :            : {
     395                 :         18 :   int id_x = size() - 1;
     396                 :         18 :   int id_y = y.size() - 1;
     397 [ +  - ][ +  + ]:         78 :   while (id_x >= 0 && id_y >= 0)
     398                 :            :   {
     399         [ -  + ]:         60 :     if (d_str[id_x] != y.d_str[id_y])
     400                 :            :     {
     401                 :          0 :       c = id_x;
     402                 :          0 :       return false;
     403                 :            :     }
     404                 :         60 :     --id_x;
     405                 :         60 :     --id_y;
     406                 :            :   }
     407         [ -  + ]:         18 :   c = id_x == -1 ? (-(id_y + 1)) : (id_x + 1);
     408                 :         18 :   return true;
     409                 :            : }
     410                 :            : 
     411                 :     104878 : std::size_t String::find(const String& y, const std::size_t start) const
     412                 :            : {
     413         [ +  + ]:     104878 :   if (size() < y.size() + start) return std::string::npos;
     414         [ +  + ]:      96646 :   if (y.empty()) return start;
     415         [ -  + ]:      94574 :   if (empty()) return std::string::npos;
     416                 :            : 
     417                 :     189148 :   std::vector<unsigned>::const_iterator itr = std::search(
     418                 :      94574 :       d_str.begin() + start, d_str.end(), y.d_str.begin(), y.d_str.end());
     419         [ +  + ]:      94574 :   if (itr != d_str.end())
     420                 :            :   {
     421                 :      83174 :     return itr - d_str.begin();
     422                 :            :   }
     423                 :      11400 :   return std::string::npos;
     424                 :            : }
     425                 :            : 
     426                 :      16385 : std::size_t String::rfind(const String& y, const std::size_t start) const
     427                 :            : {
     428         [ +  + ]:      16385 :   if (size() < y.size() + start) return std::string::npos;
     429         [ +  + ]:      12801 :   if (y.empty()) return start;
     430         [ -  + ]:      12800 :   if (empty()) return std::string::npos;
     431                 :            : 
     432                 :            :   std::vector<unsigned>::const_reverse_iterator itr = std::search(
     433                 :      12800 :       d_str.rbegin() + start, d_str.rend(), y.d_str.rbegin(), y.d_str.rend());
     434         [ +  + ]:      12800 :   if (itr != d_str.rend())
     435                 :            :   {
     436                 :      10486 :     return itr - d_str.rbegin();
     437                 :            :   }
     438                 :       2314 :   return std::string::npos;
     439                 :            : }
     440                 :            : 
     441                 :       7288 : bool String::hasPrefix(const String& y) const
     442                 :            : {
     443                 :       7288 :   size_t s = size();
     444                 :       7288 :   size_t ys = y.size();
     445         [ +  + ]:       7288 :   if (ys > s)
     446                 :            :   {
     447                 :          1 :     return false;
     448                 :            :   }
     449         [ +  + ]:      20690 :   for (size_t i = 0; i < ys; i++)
     450                 :            :   {
     451         [ +  + ]:      13480 :     if (d_str[i] != y.d_str[i])
     452                 :            :     {
     453                 :         77 :       return false;
     454                 :            :     }
     455                 :            :   }
     456                 :       7210 :   return true;
     457                 :            : }
     458                 :            : 
     459                 :      18838 : bool String::hasSuffix(const String& y) const
     460                 :            : {
     461                 :      18838 :   size_t s = size();
     462                 :      18838 :   size_t ys = y.size();
     463         [ +  + ]:      18838 :   if (ys > s)
     464                 :            :   {
     465                 :          1 :     return false;
     466                 :            :   }
     467                 :      18837 :   size_t idiff = s - ys;
     468         [ +  + ]:      49039 :   for (size_t i = 0; i < ys; i++)
     469                 :            :   {
     470         [ +  + ]:      30347 :     if (d_str[i + idiff] != y.d_str[i])
     471                 :            :     {
     472                 :        145 :       return false;
     473                 :            :     }
     474                 :            :   }
     475                 :      18692 :   return true;
     476                 :            : }
     477                 :            : 
     478                 :        170 : String String::update(std::size_t i, const String& t) const
     479                 :            : {
     480         [ +  - ]:        170 :   if (i < size())
     481                 :            :   {
     482                 :        170 :     std::vector<unsigned> vec(d_str.begin(), d_str.begin() + i);
     483                 :        170 :     size_t remNum = size() - i;
     484                 :        170 :     size_t tnum = t.d_str.size();
     485         [ +  + ]:        170 :     if (tnum >= remNum)
     486                 :            :     {
     487                 :         61 :       vec.insert(vec.end(), t.d_str.begin(), t.d_str.begin() + remNum);
     488                 :            :     }
     489                 :            :     else
     490                 :            :     {
     491                 :        109 :       vec.insert(vec.end(), t.d_str.begin(), t.d_str.end());
     492                 :        109 :       vec.insert(vec.end(), d_str.begin() + i + tnum, d_str.end());
     493                 :            :     }
     494                 :        170 :     return String(vec);
     495                 :        170 :   }
     496                 :          0 :   return *this;
     497                 :            : }
     498                 :            : 
     499                 :        275 : String String::replace(const String& s, const String& t) const
     500                 :            : {
     501                 :        275 :   std::size_t ret = find(s);
     502         [ +  + ]:        275 :   if (ret != std::string::npos)
     503                 :            :   {
     504                 :        190 :     std::vector<unsigned> vec;
     505                 :        190 :     vec.insert(vec.begin(), d_str.begin(), d_str.begin() + ret);
     506                 :        190 :     vec.insert(vec.end(), t.d_str.begin(), t.d_str.end());
     507                 :        190 :     vec.insert(vec.end(), d_str.begin() + ret + s.size(), d_str.end());
     508                 :        190 :     return String(vec);
     509                 :        190 :   }
     510                 :            :   else
     511                 :            :   {
     512                 :         85 :     return *this;
     513                 :            :   }
     514                 :            : }
     515                 :            : 
     516                 :      16506 : String String::substr(std::size_t i) const
     517                 :            : {
     518 [ -  + ][ -  + ]:      16506 :   Assert(i <= size());
                 [ -  - ]
     519                 :      16506 :   std::vector<unsigned> ret_vec;
     520                 :      16506 :   std::vector<unsigned>::const_iterator itr = d_str.begin() + i;
     521                 :      16506 :   ret_vec.insert(ret_vec.end(), itr, d_str.end());
     522                 :      33012 :   return String(ret_vec);
     523                 :      16506 : }
     524                 :            : 
     525                 :     172038 : String String::substr(std::size_t i, std::size_t j) const
     526                 :            : {
     527 [ -  + ][ -  + ]:     172038 :   Assert(i + j <= size());
                 [ -  - ]
     528                 :     172038 :   std::vector<unsigned> ret_vec;
     529                 :     172038 :   std::vector<unsigned>::const_iterator itr = d_str.begin() + i;
     530                 :     172038 :   ret_vec.insert(ret_vec.end(), itr, itr + j);
     531                 :     344076 :   return String(ret_vec);
     532                 :     172038 : }
     533                 :            : 
     534                 :       1563 : bool String::isNumber() const
     535                 :            : {
     536         [ +  + ]:       1563 :   if (d_str.empty())
     537                 :            :   {
     538                 :         95 :     return false;
     539                 :            :   }
     540         [ +  + ]:       3653 :   for (unsigned character : d_str)
     541                 :            :   {
     542         [ +  + ]:       2409 :     if (!isDigit(character))
     543                 :            :     {
     544                 :        224 :       return false;
     545                 :            :     }
     546                 :            :   }
     547                 :       1244 :   return true;
     548                 :            : }
     549                 :            : 
     550                 :       9703 : bool String::isDigit(unsigned character)
     551                 :            : {
     552                 :            :   // '0' to '9'
     553 [ +  + ][ +  + ]:       9703 :   return 48 <= character && character <= 57;
     554                 :            : }
     555                 :            : 
     556                 :       7185 : bool String::isHexDigit(unsigned character)
     557                 :            : {
     558                 :            :   // '0' to '9' or 'A' to 'F' or 'a' to 'f'
     559 [ +  - ][ +  + ]:       8579 :   return isDigit(character) || (65 <= character && character <= 70)
     560 [ +  + ][ +  + ]:       8579 :          || (97 <= character && character <= 102);
                 [ +  + ]
     561                 :            : }
     562                 :            : 
     563                 :     214249 : bool String::isPrintable(unsigned character)
     564                 :            : {
     565                 :            :   // Unicode 0x00020 (' ') to 0x0007E ('~')
     566 [ +  + ][ +  + ]:     214249 :   return 32 <= character && character <= 126;
     567                 :            : }
     568                 :            : 
     569                 :      15861 : size_t String::maxSize() { return std::numeric_limits<uint32_t>::max(); }
     570                 :            : 
     571                 :        252 : Rational String::toNumber() const
     572                 :            : {
     573                 :            :   // when smt2 standard for strings is set, this may change, based on the
     574                 :            :   // semantics of str.from.int for leading zeros
     575                 :        504 :   return Rational(toString());
     576                 :            : }
     577                 :            : 
     578                 :            : namespace strings {
     579                 :            : 
     580                 :    5808186 : size_t StringHashFunction::operator()(const cvc5::internal::String& s) const
     581                 :            : {
     582                 :    5808186 :   uint64_t ret = fnv1a::offsetBasis;
     583         [ +  + ]:    9136337 :   for (unsigned c : s.d_str)
     584                 :            :   {
     585                 :    3328151 :     ret = fnv1a::fnv1a_64(c, ret);
     586                 :            :   }
     587                 :    5808186 :   return static_cast<size_t>(ret);
     588                 :            : }
     589                 :            : 
     590                 :            : }  // namespace strings
     591                 :            : 
     592                 :          0 : std::ostream& operator<<(std::ostream& os, const String& s)
     593                 :            : {
     594                 :          0 :   return os << "\"" << s.toString() << "\"";
     595                 :            : }
     596                 :            : 
     597                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14