// RooNameSet is a utility class that stores the names the objects
// in a RooArget. This allows to preserve the contents of a RooArgSet
// in a specific use contents beyond the lifespan of the object in
// the RooArgSet. A new RooArgSet can be created from a RooNameSet
// by offering it a list of new RooAbsArg objects.
// END_HTML
#include <cstring>
#include <algorithm>
#include <cassert>
#include "RooFit.h"
#include "Riostream.h"
#include "TObjString.h"
#include "TClass.h"
#include "RooNameSet.h"
#include "RooArgSet.h"
#include "RooArgList.h"
ClassImp(RooNameSet)
;
void RooNameSet::strdup(Int_t& dstlen, char* &dstbuf, const char* src)
{
dstlen = src ? std::strlen(src) : 0;
if (dstlen) ++dstlen;
char *buf = dstlen ? new char[dstlen] : 0;
if (buf) std::strcpy(buf, src);
delete[] dstbuf;
dstbuf = buf;
}
RooNameSet::RooNameSet() : _len(0), _nameList(0)
{
}
RooNameSet::RooNameSet(const RooArgSet& argSet) : _len(0), _nameList(0)
{
refill(argSet);
}
RooNameSet::RooNameSet(const RooNameSet& other) :
TObject(other), RooPrintable(other), _len(0), _nameList(0)
{
strdup(_len, _nameList, other._nameList);
}
RooNameSet::~RooNameSet()
{
delete[] _nameList;
}
RooNameSet& RooNameSet::operator=(const RooNameSet& other)
{
if (&other == this || _nameList == other._nameList) return *this;
strdup(_len, _nameList, other._nameList);
return *this;
}
Bool_t RooNameSet::operator==(const RooNameSet& other) const
{
if (&other == this || _nameList == other._nameList) return kTRUE;
return _nameList && other._nameList &&
0 == std::strcmp(_nameList, other._nameList);
}
Bool_t RooNameSet::operator<(const RooNameSet& other) const
{
if (&other == this) return kFALSE;
if (!_nameList) return other._nameList;
if (!other._nameList) return kFALSE;
return std::strcmp(_nameList, other._nameList) < 0;
}
void RooNameSet::extendBuffer(Int_t inc)
{
if (!inc) return;
assert(inc > 0 || _len >= -inc);
int newsz = _len + inc;
if (newsz <= 1 || !_len) newsz = 0;
char* newbuf = newsz ? new char[newsz] : 0;
if (newbuf && _nameList) {
std::strncpy(newbuf, _nameList, std::min(_len, newsz));
newbuf[newsz - 1] = 0;
}
delete[] _nameList;
_nameList = newbuf;
_len = newsz;
}
void RooNameSet::setNameList(const char* givenList)
{
strdup(_len, _nameList, givenList);
}
void RooNameSet::refill(const RooArgSet& argSet)
{
delete[] _nameList;
_nameList = 0;
_len = 0;
if (0 == argSet.getSize()) return;
RooArgList tmp(argSet);
tmp.sort();
RooAbsArg* arg = 0;
for (RooFIter it = tmp.fwdIterator(); 0 != (arg = it.next());
_len += 1 + std::strlen(arg->GetName())) { }
if (_len <= 1) _len = 0;
_nameList = _len ? new char[_len] : 0;
if (_nameList) {
char *p = _nameList;
for (RooFIter it = tmp.fwdIterator(); 0 != (arg = it.next()); ) {
const char *name = arg->GetName();
std::strcpy(p, name);
while (*p) ++p;
*p++ = ':';
}
*--p = 0;
}
}
RooArgSet* RooNameSet::select(const RooArgSet& list) const
{
RooArgSet* output = new RooArgSet;
if (!_nameList || !std::strlen(_nameList)) return output;
char* tmp = 0;
int dummy = 0;
strdup(dummy, tmp, _nameList);
char* token = std::strtok(tmp, ":");
while (token) {
RooAbsArg* arg = list.find(token);
if (arg) output->add(*arg);
token = std::strtok(0, ":");
}
delete[] tmp;
return output;
}
void RooNameSet::printName(std::ostream& os) const
{
os << GetName();
}
void RooNameSet::printTitle(std::ostream& os) const
{
os << GetTitle();
}
void RooNameSet::printClassName(std::ostream& os) const
{
os << IsA()->GetName();
}
void RooNameSet::printValue(std::ostream& os) const
{
os << content();
}