Skip to content

Commit

Permalink
strlen optimization: use constexpr instead of runtime-constant
Browse files Browse the repository at this point in the history
strlen cannot be a constexpr in all platforms otherwise.
  • Loading branch information
ferdymercury authored Dec 9, 2024
1 parent babc8b4 commit 0f89185
Show file tree
Hide file tree
Showing 19 changed files with 82 additions and 72 deletions.
2 changes: 1 addition & 1 deletion core/base/src/TUrl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ void TUrl::SetUrl(const char *url, Bool_t defaultIsFile)
// allow url of form: "proto://"
} else {
if (defaultIsFile) {
const std::size_t bufferSize = strlen("file:") + strlen(u0) + 1;
const std::size_t bufferSize = std::char_traits<char>::length("file:") + strlen(u0) + 1;
char *newu = new char [bufferSize];
snprintf(newu, bufferSize, "file:%s", u0);
delete [] u0;
Expand Down
63 changes: 34 additions & 29 deletions core/foundation/src/TClassEdit.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,8 @@ bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname)
string_view a( allocname );
// In Windows, allocname might be 'class const std::allocator<int>',
// (never 'const class ...'), so we start by stripping the 'class ', if any
constexpr static int clalloclen = std::char_traits<char>::length("class ");
constexpr auto length = std::char_traits<char>::length;
constexpr static int clalloclen = length("class ");
if (a.compare(0,clalloclen,"class ") == 0) {
a.remove_prefix(clalloclen);
}
Expand All @@ -634,7 +635,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname)
if (a=="__default_alloc_template<true,0>") return true;
if (a=="__malloc_alloc_template<0>") return true;

constexpr static int alloclen = std::char_traits<char>::length("allocator<");
constexpr static int alloclen = length("allocator<");
if (a.compare(0,alloclen,"allocator<") != 0) {
return false;
}
Expand Down Expand Up @@ -683,15 +684,16 @@ bool TClassEdit::IsDefAlloc(const char *allocname,
string_view a( allocname );
RemoveStd(a);

constexpr static int alloclen = std::char_traits<char>::length("allocator<");
constexpr auto length = std::char_traits<char>::length;
constexpr static int alloclen = length("allocator<");
if (a.compare(0,alloclen,"allocator<") != 0) {
return false;
}
a.remove_prefix(alloclen);

RemoveStd(a);

constexpr static int pairlen = std::char_traits<char>::length("pair<");
constexpr static int pairlen = length("pair<");
if (a.compare(0,pairlen,"pair<") != 0) {
return false;
}
Expand Down Expand Up @@ -1082,8 +1084,10 @@ int TClassEdit::GetSplit(const char *type, vector<string>& output, int &nestedLo
if (full.compare(offset, 5, "std::") == 0) {
offset += 5;
}
static const char* char_traits_s = "char_traits<char>";
static const unsigned int char_traits_len = strlen(char_traits_s);
constexpr auto char_traits_s = "char_traits<char>";
// or
// static constexpr char const* const char_traits_s = "char_traits<char>";
static constexpr unsigned int char_traits_len = std::char_traits<char>::length(char_traits_s);
if (full.compare(offset, char_traits_len, char_traits_s) == 0) {
offset += char_traits_len;
if ( full[offset] == '>') {
Expand Down Expand Up @@ -1347,7 +1351,7 @@ bool TClassEdit::IsInterpreterDetail(const char *type)
bool TClassEdit::IsSTLBitset(const char *classname)
{
size_t offset = StdLen(classname);
if ( strncmp(classname+offset,"bitset<",strlen("bitset<"))==0) return true;
if ( strncmp(classname+offset,"bitset<",std::char_traits<char>::length("bitset<"))==0) return true;
return false;
}

Expand Down Expand Up @@ -1424,32 +1428,33 @@ int TClassEdit::IsSTLCont(const char *type, int testAlloc)

bool TClassEdit::IsStdClass(const char *classname)
{
constexpr auto length = std::char_traits<char>::length;
classname += StdLen( classname );
if ( strcmp(classname,"string")==0 ) return true;
if ( strncmp(classname,"bitset<",strlen("bitset<"))==0) return true;
if ( strncmp(classname,"bitset<",length("bitset<"))==0) return true;
if ( IsStdPair(classname) ) return true;
if ( strcmp(classname,"allocator")==0) return true;
if ( strncmp(classname,"allocator<",strlen("allocator<"))==0) return true;
if ( strncmp(classname,"greater<",strlen("greater<"))==0) return true;
if ( strncmp(classname,"less<",strlen("less<"))==0) return true;
if ( strncmp(classname,"equal_to<",strlen("equal_to<"))==0) return true;
if ( strncmp(classname,"hash<",strlen("hash<"))==0) return true;
if ( strncmp(classname,"auto_ptr<",strlen("auto_ptr<"))==0) return true;

if ( strncmp(classname,"vector<",strlen("vector<"))==0) return true;
if ( strncmp(classname,"list<",strlen("list<"))==0) return true;
if ( strncmp(classname,"forward_list<",strlen("forward_list<"))==0) return true;
if ( strncmp(classname,"deque<",strlen("deque<"))==0) return true;
if ( strncmp(classname,"map<",strlen("map<"))==0) return true;
if ( strncmp(classname,"multimap<",strlen("multimap<"))==0) return true;
if ( strncmp(classname,"set<",strlen("set<"))==0) return true;
if ( strncmp(classname,"multiset<",strlen("multiset<"))==0) return true;
if ( strncmp(classname,"unordered_set<",strlen("unordered_set<"))==0) return true;
if ( strncmp(classname,"unordered_multiset<",strlen("unordered_multiset<"))==0) return true;
if ( strncmp(classname,"unordered_map<",strlen("unordered_map<"))==0) return true;
if ( strncmp(classname,"unordered_multimap<",strlen("unordered_multimap<"))==0) return true;
if ( strncmp(classname,"bitset<",strlen("bitset<"))==0) return true;
if ( strncmp(classname,"ROOT::VecOps::RVec<",strlen("ROOT::VecOps::RVec<"))==0) return true;
if ( strncmp(classname,"allocator<",length("allocator<"))==0) return true;
if ( strncmp(classname,"greater<",length("greater<"))==0) return true;
if ( strncmp(classname,"less<",length("less<"))==0) return true;
if ( strncmp(classname,"equal_to<",length("equal_to<"))==0) return true;
if ( strncmp(classname,"hash<",length("hash<"))==0) return true;
if ( strncmp(classname,"auto_ptr<",length("auto_ptr<"))==0) return true;

if ( strncmp(classname,"vector<",length("vector<"))==0) return true;
if ( strncmp(classname,"list<",length("list<"))==0) return true;
if ( strncmp(classname,"forward_list<",length("forward_list<"))==0) return true;
if ( strncmp(classname,"deque<",length("deque<"))==0) return true;
if ( strncmp(classname,"map<",length("map<"))==0) return true;
if ( strncmp(classname,"multimap<",length("multimap<"))==0) return true;
if ( strncmp(classname,"set<",length("set<"))==0) return true;
if ( strncmp(classname,"multiset<",length("multiset<"))==0) return true;
if ( strncmp(classname,"unordered_set<",length("unordered_set<"))==0) return true;
if ( strncmp(classname,"unordered_multiset<",length("unordered_multiset<"))==0) return true;
if ( strncmp(classname,"unordered_map<",length("unordered_map<"))==0) return true;
if ( strncmp(classname,"unordered_multimap<",length("unordered_multimap<"))==0) return true;
if ( strncmp(classname,"bitset<",length("bitset<"))==0) return true;
if ( strncmp(classname,"ROOT::VecOps::RVec<",length("ROOT::VecOps::RVec<"))==0) return true;

return false;
}
Expand Down
2 changes: 1 addition & 1 deletion core/meta/src/TClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3220,7 +3220,7 @@ TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent, size_t hi
return pairinfo->GetClass();
} else {
// Check if we have an STL container that might provide it.
static const size_t slen = strlen("pair");
static constexpr size_t slen = std::char_traits<char>::length("pair");
static const char *associativeContainer[] = { "map", "unordered_map", "multimap",
"unordered_multimap", "set", "unordered_set", "multiset", "unordered_multiset" };
for(auto contname : associativeContainer) {
Expand Down
2 changes: 1 addition & 1 deletion core/metacling/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4096,7 +4096,7 @@ void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent)
// Handle the special case of 'tuple' where we ignore the real implementation
// details and just overlay a 'simpler'/'simplistic' version that is easy
// for the I/O to understand and handle.
if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
if (strncmp(cl->GetName(),"tuple<",std::char_traits<char>::length("tuple<"))==0) {
if (!reload)
name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
if (reload || name.empty()) {
Expand Down
7 changes: 4 additions & 3 deletions graf3d/gl/src/gl2ps.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include <stdarg.h>
#include <time.h>
#include <float.h>
#include <string>

#if defined(GL2PS_HAVE_ZLIB)
#include <zlib.h>
Expand Down Expand Up @@ -4428,10 +4429,10 @@ static int gl2psPrintPDFShaderMask(int obj, int childobj)
obj,
(int)gl2ps->viewport[0], (int)gl2ps->viewport[1],
(int)gl2ps->viewport[2], (int)gl2ps->viewport[3]);

constexpr auto length = std::char_traits<char>::length;
len = (childobj>0)
? strlen("/TrSh sh\n") + (int)log10((double)childobj)+1
: strlen("/TrSh0 sh\n");
? length("/TrSh sh\n") + (int)log10((double)childobj)+1
: length("/TrSh0 sh\n");

offs += fprintf(gl2ps->stream,
"/Length %d\n"
Expand Down
5 changes: 3 additions & 2 deletions hist/hist/src/HFitImpl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -760,14 +760,15 @@ void ROOT::Fit::FitOptionsMake(EFitObjectType type, const char *option, Foption_
//for robust fitting, see if # of good points is defined
// decode parameters for robust fitting
Double_t h=0;
constexpr auto length = std::char_traits<char>::length;
if (opt.Contains("H=0.")) {
int start = opt.Index("H=0.");
int numpos = start + strlen("H=0.");
int numpos = start + length("H=0.");
int numlen = 0;
int len = opt.Length();
while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
TString num = opt(numpos,numlen);
opt.Remove(start+strlen("H"),strlen("=0.")+numlen);
opt.Remove(start+length("H"),length("=0.")+numlen);
h = atof(num.Data());
h*=TMath::Power(10, -numlen);
}
Expand Down
2 changes: 1 addition & 1 deletion interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ namespace cling {
// FIXME: Once the C++ modules replaced the forward decls, remove this.
if (D->getASTContext().getLangOpts().Modules &&
llvm::StringRef(includeText).starts_with("include ")) {
includeText += strlen("include ");
includeText += std::char_traits<char>::length("include ");
}

assert((includeText[0] == '<' || includeText[0] == '"') &&
Expand Down
4 changes: 2 additions & 2 deletions io/io/src/TFile.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3086,7 +3086,7 @@ void TFile::MakeProject(const char *dirname, const char * /*classes*/,
if (info->IsA() != TStreamerInfo::Class()) {
continue;
}
if (strncmp(info->GetName(), "auto_ptr<", strlen("auto_ptr<")) == 0) {
if (strncmp(info->GetName(), "auto_ptr<", std::char_traits<char>::length("auto_ptr<")) == 0) {
continue;
}
TClass *cl = TClass::GetClass(info->GetName());
Expand Down Expand Up @@ -4129,7 +4129,7 @@ TFile *TFile::Open(const char *url, Option_t *options, const char *ftitle,
TString opts(options);
Int_t ito = opts.Index("TIMEOUT=");
if (ito != kNPOS) {
TString sto = opts(ito + strlen("TIMEOUT="), opts.Length());
TString sto = opts(ito + std::char_traits<char>::length("TIMEOUT="), opts.Length());
while (!(sto.IsDigit()) && !(sto.IsNull())) { sto.Remove(sto.Length()-1,1); }
if (!(sto.IsNull())) {
// Timeout in millisecs
Expand Down
2 changes: 1 addition & 1 deletion io/io/src/TMakeProject.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ UInt_t TMakeProject::GenerateIncludeForTemplate(FILE *fp, const char *clname, ch
} else if (TClassEdit::IsStdPair(incName)) {
AddInclude(fp, "utility", kTRUE, inclist);
ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
} else if (strncmp(incName.Data(), "auto_ptr<", strlen("auto_ptr<")) == 0) {
} else if (strncmp(incName.Data(), "auto_ptr<", std::char_traits<char>::length("auto_ptr<")) == 0) {
AddInclude(fp, "memory", kTRUE, inclist);
ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
} else if (TClassEdit::IsStdClass(incName)) {
Expand Down
8 changes: 4 additions & 4 deletions io/io/src/TStreamerInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3836,7 +3836,7 @@ void TStreamerInfo::GenerateDeclaration(FILE *fp, FILE *sfp, const TList *subCla
// nothing to do.
break;
}
} else if (strncmp(enamebasic.Data(), "auto_ptr<", strlen("auto_ptr<")) == 0) {
} else if (strncmp(enamebasic.Data(), "auto_ptr<", std::char_traits<char>::length("auto_ptr<")) == 0) {
enamebasic = TMakeProject::UpdateAssociativeToVector(enamebasic);
}

Expand Down Expand Up @@ -3986,7 +3986,7 @@ UInt_t TStreamerInfo::GenerateIncludes(FILE *fp, char *inclist, const TList *ext
}
if (TClassEdit::IsStdPair(element->GetTypeName())) {
TMakeProject::AddInclude( fp, "utility", kTRUE, inclist);
} else if (strncmp(element->GetTypeName(),"auto_ptr<",strlen("auto_ptr<"))==0) {
} else if (strncmp(element->GetTypeName(),"auto_ptr<",std::char_traits<char>::length("auto_ptr<"))==0) {
TMakeProject::AddInclude( fp, "memory", kTRUE, inclist);
} else {
TString incName( include, strlen(include)-1 );
Expand All @@ -4011,7 +4011,7 @@ Int_t TStreamerInfo::GenerateHeaderFile(const char *dirname, const TList *subCla
// if (fClassVersion == -4) return 0;
if ((fClass && fClass->GetCollectionType()) || TClassEdit::IsSTLCont(GetName())) return 0;
if (TClassEdit::IsStdPair(GetName())) return 0;
if (strncmp(GetName(),"auto_ptr<",strlen("auto_ptr<"))==0) return 0;
if (strncmp(GetName(),"auto_ptr<",std::char_traits<char>::length("auto_ptr<"))==0) return 0;

TClass *cl = TClass::GetClass(GetName());
if (cl) {
Expand Down Expand Up @@ -5838,7 +5838,7 @@ TVirtualStreamerInfo *TStreamerInfo::GenerateInfoForPair(const std::string &firs

TVirtualStreamerInfo *TStreamerInfo::GenerateInfoForPair(const std::string &pairclassname, bool silent, size_t hint_pair_offset, size_t hint_pair_size)
{
const static int pairlen = strlen("pair<");
const static int pairlen = std::char_traits<char>::length("pair<");
if (pairclassname.compare(0, pairlen, "pair<") != 0) {
if (!silent)
Error("GenerateInfoForPair", "The class name passed is not a pair: %s", pairclassname.c_str());
Expand Down
2 changes: 1 addition & 1 deletion io/sql/src/TSQLObjectData.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ Bool_t TSQLObjectData::ExtractBlobValues()
fBlobTypeName = name;
} else {
fBlobPrefixName = name;
separ += strlen(":"); // SQLNameSeparator()
separ += std::char_traits<char>::length(":"); // SQLNameSeparator()
fBlobTypeName = separ;
}

Expand Down
2 changes: 1 addition & 1 deletion main/src/h2root.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ int main(int argc, char **argv)
if (argc > 2) {
file_out=argv[2];
} else {
Int_t nchf = strlen(file_in)+strlen(".root")+1;
Int_t nchf = strlen(file_in)+std::char_traits<char>::length(".root")+1;
file_out= new char[nchf];
strlcpy(file_out,file_in,nchf);
char *dot = strrchr(file_out,'.');
Expand Down
2 changes: 1 addition & 1 deletion main/src/hadd.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ int main( int argc, char **argv )
++ffirst;
} else if ( strcmp(argv[a],"-cachesize=") == 0 ) {
int size;
static const size_t arglen = strlen("-cachesize=");
static constexpr size_t arglen = std::char_traits<char>::length("-cachesize=");
auto parseResult = ROOT::FromHumanReadableSize(argv[a]+arglen,size);
if (parseResult == ROOT::EFromHumanReadableSize::kParseFail) {
std::cerr << "Error: could not parse the cache size passed after -cachesize: "
Expand Down
2 changes: 1 addition & 1 deletion tree/tree/src/TBranch.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2425,7 +2425,7 @@ void TBranch::Print(Option_t *option) const
}
Printf("*Baskets :%9d : Basket Size=%11d bytes Compression= %6.2f *",fWriteBasket,fBasketSize,cx);

if (strncmp(option,"basketsInfo",strlen("basketsInfo"))==0) {
if (strncmp(option,"basketsInfo",std::char_traits<char>::length("basketsInfo"))==0) {
Int_t nbaskets = fWriteBasket;
for (Int_t i=0;i<nbaskets;i++) {
Printf("*Basket #%4d entry=%6lld pos=%6lld size=%5d",
Expand Down
9 changes: 5 additions & 4 deletions tree/tree/src/TBranchElement.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3835,9 +3835,10 @@ static void PrintElements(const TStreamerInfo *info, const TStreamerInfoActions:

void TBranchElement::Print(Option_t* option) const
{
constexpr auto length = std::char_traits<char>::length;
Int_t nbranches = fBranches.GetEntriesFast();
if (strncmp(option,"debugAddress",strlen("debugAddress"))==0) {
if (strlen(option)==strlen("debugAddress")) {
if (strncmp(option,"debugAddress",length("debugAddress"))==0) {
if (strlen(option)==length("debugAddress")) {
Printf("%-24s %-16s %2s %4s %-16s %-16s %8s %8s %s %s\n",
"Branch Name", "Streamer Class", "ID", "Type", "Class", "Parent", "pOffset", "fOffset", "fObject", "fOnfileObject");
}
Expand All @@ -3859,7 +3860,7 @@ void TBranchElement::Print(Option_t* option) const
}
return;
}
if (strncmp(option,"debugInfo",strlen("debugInfo"))==0) {
if (strncmp(option,"debugInfo",length("debugInfo"))==0) {
Printf("Branch %s uses:",GetName());
if (fID>=0) {
// GetInfoImp()->GetElement(fID)->ls();
Expand Down Expand Up @@ -3892,7 +3893,7 @@ void TBranchElement::Print(Option_t* option) const
if (fFillActionSequence) fFillActionSequence->Print(option);
}
TString suboption = "debugInfoSub";
suboption += (option+strlen("debugInfo"));
suboption += (option+length("debugInfo"));
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* subbranch = (TBranchElement*)fBranches.At(i);
subbranch->Print(suboption);
Expand Down
7 changes: 4 additions & 3 deletions tree/tree/src/TBranchSTL.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,9 @@ bool TBranchSTL::IsFolder() const

void TBranchSTL::Print(const char *option) const
{
if (strncmp(option,"debugAddress",strlen("debugAddress"))==0) {
if (strlen(GetName())>24) Printf("%-24s\n%-24s ", GetName(),"");
constexpr auto length = std::char_traits<char>::length;
if (strncmp(option,"debugAddress",length("debugAddress"))==0) {
if (length(GetName())>24) Printf("%-24s\n%-24s ", GetName(),"");
else Printf("%-24s ", GetName());

TBranchElement *parent = dynamic_cast<TBranchElement*>(GetMother()->GetSubBranch(this));
Expand All @@ -620,7 +621,7 @@ void TBranchSTL::Print(const char *option) const
TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
br->Print("debugAddressSub");
}
} else if (strncmp(option,"debugInfo",strlen("debugInfo"))==0) {
} else if (strncmp(option,"debugInfo",length("debugInfo"))==0) {
Printf("Branch %s uses:\n",GetName());
if (fID>=0) {
GetInfo()->GetElement(fID)->ls();
Expand Down
2 changes: 1 addition & 1 deletion tree/tree/src/TTree.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7246,7 +7246,7 @@ void TTree::Print(Option_t* option) const
if (!option)
option = "";

if (strncmp(option,"clusters",strlen("clusters"))==0) {
if (strncmp(option,"clusters",std::char_traits<char>::length("clusters"))==0) {
Printf("%-16s %-16s %-16s %8s %20s",
"Cluster Range #", "Entry Start", "Last Entry", "Size", "Number of clusters");
Int_t index= 0;
Expand Down
2 changes: 1 addition & 1 deletion tree/treeplayer/src/TFormLeafInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ TFormLeafInfoNumerical::TFormLeafInfoNumerical(TVirtualCollectionProxy *collecti
if (fKind == TStreamerInfo::kOffsetL + TStreamerInfo::kChar) {
// Could be a bool
if (strcmp( collection->GetCollectionClass()->GetName(), "vector<bool>") == 0
|| strncmp( collection->GetCollectionClass()->GetName(), "bitset<", strlen("bitset<") ) ==0 ) {
|| strncmp( collection->GetCollectionClass()->GetName(), "bitset<", std::char_traits<char>::length("bitset<") ) ==0 ) {
fIsBool = true;
fKind = (EDataType)18;
}
Expand Down
Loading

0 comments on commit 0f89185

Please sign in to comment.