ATLAS Offline Software
Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
CxxUtils::ClassName Class Reference

Recursively separate out template arguments in a C++ class name. More...

#include <ClassName.h>

Collaboration diagram for CxxUtils::ClassName:

Classes

class  ExcBadClassName
 Exception to signal a malformed class name. More...
 
class  ExcMissingVariable
 Exception to signal a missing variable. More...
 
class  Rules
 A set of transformation rules to use with ClassName. More...
 

Public Types

typedef std::map< std::string, ClassNamematch_t
 Map used to hold variable assignments from matching. More...
 

Public Member Functions

 ClassName ()
 Default constructor. More...
 
 ClassName (const char *name)
 Parse a class name into component parts. More...
 
 ClassName (const std::string &name)
 Parse a class name into component parts. More...
 
 ClassName (const std::string &name, std::string::size_type &pos)
 Parse a class name into component parts. More...
 
void swap (ClassName &other)
 Swap this expression with another one. More...
 
bool isConst () const
 Get the const flag for this expression. More...
 
void setConst ()
 Set the const flag for this expression. More...
 
const std::string & name () const
 Return the root name of the expression. More...
 
std::string qualifiedName () const
 Return the namespace-qualified name of the expression. More...
 
std::string fullName () const
 Return the full name of the expression. More...
 
size_t ntargs () const
 Return number of template arguments. More...
 
const ClassNametarg (size_t i) const
 Return one template argument. More...
 
bool operator== (const ClassName &other) const
 Test two expressions for equality. More...
 
bool operator!= (const ClassName &other) const
 Test two expressions for inequality. More...
 
bool match (const ClassName &pattern, match_t &matches) const
 Match this expression against a pattern. More...
 
void subst (const match_t &matches)
 Substitute variables into this expression. More...
 
ClassName substCopy (const match_t &matches) const
 Return a copy of this expression with variables substituted. More...
 
void applyRules (const Rules &rules)
 Apply a set of transformation rules to this object. More...
 

Static Public Member Functions

static std::string applyRules (const std::string &name, const Rules &rules)
 Apply a set of transformation rules a class name. More...
 

Private Member Functions

void parse (const std::string &name, std::string::size_type &pos)
 Parse a string into a ClassName. More...
 
std::string parsePrimary (const std::string &name, std::string::size_type &pos)
 Parse a primary part of the class name. More...
 
void parseNamespace (const std::string &name, std::string::size_type &pos)
 Parse a namespace qualification. More...
 
void parseTemplateArgs (const std::string &name, std::string::size_type &pos)
 Parse the template part of a name. More...
 
void skipSpaces (const std::string &name, std::string::size_type &pos)
 Skip past spaces in a string. More...
 
bool match1 (const ClassName &pattern, bool topLevel, match_t &matches) const
 Match this expression against a pattern. More...
 
bool applyRules1 (const Rules &rules)
 Apply a set of transformation rules to this object. More...
 

Private Attributes

bool m_const
 Is this expression const? More...
 
std::vector< ClassNamem_namespace
 The containing namespace. More...
 
std::string m_name
 The primary name part of this expression. More...
 
std::vector< ClassNamem_targs
 The template arguments for this name. More...
 

Detailed Description

Recursively separate out template arguments in a C++ class name.

This class allows making some simple transformations of C++ class names. For example, given these rules:

ClassName::Rules rules;
rules.add ("std::vector<$T, std::allocator<$T> >",
"std::vector<$T>");
rules.add ("std::map<$K,$V, std::less<$K>, std::allocator<std::pair<const $K,$V> > >",
"std::map<$K,$V>");
rules.add ("DataVector<$T, $B>", "DataVector<$T>");
rules.add ("std::__1", "std");

then rules.apply can make transformations like this:

std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >
-> std::vector<std::vector<int> >
std::map<int, float, std::less<int>, std::allocator<std::pair<const int, float> > >
-> std::map<int, float>

In slightly more detail: this class analyzes C++ class names. A name like

A::B<int, double>

is broken down like this:

This is done recursively; both the namespace and template argument pieces can be further broken down like this. A name can also be marked as ‘const’, but no other parsing of C-like declarators is done.

Parsed names can be matched against simple patterns like this:

A::B<$T>

and the variable T gets set to the corresponding piece of the type being matched. For example, given the above pattern,

If the pattern were A::B<const $T>, then A::B<const int> would match with T set to int, but A::B<int> would not match.

However, the root name of a pattern may not be a variable; for example, you can't use A::$T<int> as a pattern.

You can also substitute variables back into a pattern; for example,

Definition at line 100 of file CxxUtils/CxxUtils/ClassName.h.

Member Typedef Documentation

◆ match_t

typedef std::map<std::string, ClassName> CxxUtils::ClassName::match_t

Map used to hold variable assignments from matching.

Definition at line 200 of file CxxUtils/CxxUtils/ClassName.h.

Constructor & Destructor Documentation

◆ ClassName() [1/4]

ClassName< T >::ClassName ( )

Default constructor.

Needed for STL compatibility.

Definition at line 138 of file ClassName.cxx.

139  : m_const(false)
140 {
141 }

◆ ClassName() [2/4]

ClassName< T >::ClassName ( const char *  name)

Parse a class name into component parts.

Parameters
nameThe name to parse.

Raises a BadClassName exception if the name isn't completely parsed.

Parameters
nameThe name to parse.

Raises a ExcBadClassName exception if the name isn't completely parsed.

Definition at line 150 of file ClassName.cxx.

151  : m_const(false)
152 {
153  std::string sname = name;
154  std::string::size_type pos = 0;
155  parse (sname, pos);
156  skipSpaces (sname, pos);
157  if (pos != sname.size())
158  throw ExcBadClassName (sname);
159 }

◆ ClassName() [3/4]

ClassName< T >::ClassName ( const std::string &  name)

Parse a class name into component parts.

Parameters
nameThe name to parse.

Raises a BadClassName exception if the name isn't completely parsed.

Parameters
nameThe name to parse.

Raises a ExcBadClassName exception if the name isn't completely parsed.

Definition at line 168 of file ClassName.cxx.

169  : m_const(false)
170 {
171  std::string::size_type pos = 0;
172  parse (name, pos);
173  skipSpaces (name, pos);
174  if (pos != name.size())
175  throw ExcBadClassName (name);
176 }

◆ ClassName() [4/4]

ClassName< T >::ClassName ( const std::string &  name,
std::string::size_type &  pos 
)

Parse a class name into component parts.

Parameters
nameString containing the name to parse.
posPosition in the string at which parsing should start.

pos is updated to point to past the point where parsing stopped.

Definition at line 186 of file ClassName.cxx.

187  : m_const (false)
188 {
189  parse (name, pos);
190 }

Member Function Documentation

◆ applyRules() [1/2]

void ClassName< T >::applyRules ( const Rules rules)

Apply a set of transformation rules to this object.

Parameters
rulesThe set of rules to apply.

Recursively walk this expression, trying to apply the transformation rules in rules. If any matches are found, this expression is modified in-place and the walk is repeated. This function terminates when no further matches are found.

Warning: An infinite loop is possible if the replacement for a pattern can always be matched by another pattern.

Definition at line 410 of file ClassName.cxx.

411 {
412  while (applyRules1 (rules))
413  ;
414 }

◆ applyRules() [2/2]

std::string ClassName< T >::applyRules ( const std::string &  name,
const Rules rules 
)
static

Apply a set of transformation rules a class name.

param The name of the class to transform.

Parameters
rulesThe set of rules to apply.

This is just shorthand for

cn.applyRules (rules);
return cn.fullName();

Definition at line 430 of file ClassName.cxx.

432 {
433  ClassName cn (name);
434  cn.applyRules (rules);
435  return cn.fullName();
436 }

◆ applyRules1()

bool ClassName< T >::applyRules1 ( const Rules rules)
private

Apply a set of transformation rules to this object.

Parameters
rulesThe set of rules to apply.

Recursively walk this expression, trying to apply the transformation rules in rules. If any matches are found, this expression is modified in-place.

Returns true if any matches were found.

Definition at line 674 of file ClassName.cxx.

675 {
676  bool ret = rules.applyTo (*this);
677 
678  if (m_namespace.size() > 0)
679  ret |= m_namespace[0].applyRules1 (rules);
680 
681  for (size_t i = 0; i < m_targs.size(); i++)
682  ret |= m_targs[i].applyRules1 (rules);
683 
684  return ret;
685 }

◆ fullName()

std::string ClassName< T >::fullName ( ) const

Return the full name of the expression.

Definition at line 252 of file ClassName.cxx.

253 {
254  std::string name = qualifiedName();
255  if (m_const)
256  name = "const " + name;
257  if (m_targs.size() > 0) {
258  name += '<';
259  for (const ClassName& cn : m_targs) {
260  if (name[name.size()-1] != '<')
261  name += ',';
262  name += cn.fullName();
263  }
264  if (name[name.size()-1] == '>')
265  name += ' ';
266  name += '>';
267  }
268  return name;
269 }

◆ isConst()

bool ClassName< T >::isConst ( ) const

Get the const flag for this expression.

Definition at line 209 of file ClassName.cxx.

210 {
211  return m_const;
212 }

◆ match()

bool ClassName< T >::match ( const ClassName pattern,
match_t matches 
) const

Match this expression against a pattern.

Parameters
patternThe pattern to match.
[out]matchesDictionary of pattern substitutions.

Return true if pattern matches the current expression. pattern may contain dummy variables of the form $T. On a successful return, the map matches contains the variable assignments needed for the match.

Definition at line 339 of file ClassName.cxx.

340 {
341  matches.clear();
342  return match1 (pattern, true, matches);
343 }

◆ match1()

bool ClassName< T >::match1 ( const ClassName pattern,
bool  topLevel,
match_t matches 
) const
private

Match this expression against a pattern.

Parameters
patternThe pattern to match.
topLevelTrue if this is the outermost level of matching.
[out]matchesDictionary of pattern substitutions.

Return true if pattern matches the current expression. pattern may contain dummy variables of the form $T. On a successful return, the map matches contains the variable assignments needed for the match.

Definition at line 603 of file ClassName.cxx.

606 {
607  if (pattern.m_name[0] == '$') {
608  std::string var = pattern.m_name.substr (1, std::string::npos);
609  match_t::iterator it = matches.find (var);
610  if (it != matches.end()) {
611  if (pattern.m_const && !it->second.m_const) {
612  ClassName cn (it->second);
613  cn.setConst();
614  return *this == cn;
615  }
616  return *this == it->second;
617  }
618 
619  matches[var] = *this;
620  if (pattern.m_const) {
621  if (m_const)
622  matches[var].m_const = false;
623  else
624  return false;
625  }
626  return true;
627  }
628 
629  // Require that const qualifiers match.
630  // However, if this is the top level, we allow a pattern with no explicit
631  // const to match something that is const. Otherwise, we'd need to repeat
632  // all patterns for the const case.
633  if (topLevel) {
634  if (pattern.m_const && !m_const)
635  return false;
636  }
637  else if (m_const != pattern.m_const) {
638  return false;
639  }
640 
641  if (m_name != pattern.m_name)
642  return false;
643 
644  if (m_namespace.size() != pattern.m_namespace.size())
645  return false;
646 
647  if (m_targs.size() != pattern.m_targs.size())
648  return false;
649 
650  if (m_namespace.size() > 0) {
651  if (!m_namespace[0].match1 (pattern.m_namespace[0], false, matches))
652  return false;
653  }
654 
655  for (size_t i = 0; i < m_targs.size(); i++) {
656  if (!m_targs[i].match1 (pattern.m_targs[i], false, matches))
657  return false;
658  }
659 
660  return true;
661 }

◆ name()

const std::string & ClassName< T >::name ( ) const

Return the root name of the expression.

In A::B<C>, the root name is B.

Definition at line 229 of file ClassName.cxx.

230 {
231  return m_name;
232 }

◆ ntargs()

size_t ClassName< T >::ntargs ( ) const

Return number of template arguments.

Definition at line 275 of file ClassName.cxx.

276 {
277  return m_targs.size();
278 }

◆ operator!=()

bool ClassName< T >::operator!= ( const ClassName other) const

Test two expressions for inequality.

Definition at line 323 of file ClassName.cxx.

324 {
325  return !(*this==other);
326 }

◆ operator==()

bool ClassName< T >::operator== ( const ClassName other) const

Test two expressions for equality.

Definition at line 294 of file ClassName.cxx.

295 {
296  if (m_name != other.m_name)
297  return false;
298 
299  if (m_const != other.m_const)
300  return false;
301 
302  if (m_namespace.size() != other.m_namespace.size())
303  return false;
304 
305  if (m_targs.size() != other.m_targs.size())
306  return false;
307 
308  if (m_namespace.size() > 0 && m_namespace[0] != other.m_namespace[0])
309  return false;
310 
311  for (size_t i = 0; i < m_targs.size(); ++i) {
312  if (m_targs[i] != other.m_targs[i])
313  return false;
314  }
315 
316  return true;
317 }

◆ parse()

void ClassName< T >::parse ( const std::string &  name,
std::string::size_type &  pos 
)
private

Parse a string into a ClassName.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

On return, pos will be updated to point just past the last character consumed.

Definition at line 447 of file ClassName.cxx.

448 {
450  if (m_name.compare (0, 6, "const ") ==0) {
451  m_const = true;
452  m_name.erase (0, 6);
453  }
454  if (m_name.size() >= 6 && m_name.compare (m_name.size()-6, 6, " const") ==0) {
455  m_const = true;
456  m_name.erase (m_name.size()-6, 6);
457  }
458 
459  skipSpaces (name, pos);
460  while (pos < name.size()) {
461  if (name[pos] == '<')
463  else if (name[pos] == ':' && pos+1 < name.size() && name[pos+1] == ':')
465  else
466  break;
467  }
468  skipSpaces (name, pos);
469  if (name.compare (pos, 5, "const")==0) {
470  m_const = true;
471  pos += 5;
472  }
473 }

◆ parseNamespace()

void ClassName< T >::parseNamespace ( const std::string &  name,
std::string::size_type &  pos 
)
private

Parse a namespace qualification.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

When this is called, the namespace part has already been parsed, and the next two characters in name are ::. This reads in the remainder of the string as a ClassName, and then moves it inside the namespace given by the current object.

On return, pos will be updated to point just past the last character consumed.

Definition at line 522 of file ClassName.cxx.

524 {
525  assert (pos+1 < name.size() && name[pos] == ':' && name[pos+1] == ':');
526  pos += 2;
527  skipSpaces (name, pos);
528 
529  ClassName ns (name, pos);
530  ns.swap (*this);
531  if (ns.isConst()) {
532  this->setConst();
533  ns.m_const = false;
534  }
535  ClassName* p = this;
536  while (p->m_namespace.size() > 0)
537  p = &p->m_namespace[0];
538  p->m_namespace.push_back (std::move(ns));
539 }

◆ parsePrimary()

std::string ClassName< T >::parsePrimary ( const std::string &  name,
std::string::size_type &  pos 
)
private

Parse a primary part of the class name.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

The primary part of the class name is a string without namespace and template delimiters.

On return, pos will be updated to point just past the last character consumed.

Definition at line 488 of file ClassName.cxx.

489 {
490  skipSpaces (name, pos);
491  std::string out;
492  size_t nest = 0;
493  while (pos < name.size()) {
494  char c = name[pos];
495  if (c == '(')
496  ++nest;
497  else if (c == ')' && nest > 0)
498  --nest;
499  else if (nest == 0 && (c == '<' || c == '>' || c == ',' || c == ':'))
500  break;
501 
502  out += c;
503  ++pos;
504  }
505  return out;
506 }

◆ parseTemplateArgs()

void ClassName< T >::parseTemplateArgs ( const std::string &  name,
std::string::size_type &  pos 
)
private

Parse the template part of a name.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

When this is called, the qualified name part of the name has already been parsed, and the next character in name is ::. This reads in template arguments from name.

On return, pos will be updated to point just past the last character consumed.

Definition at line 554 of file ClassName.cxx.

556 {
557  assert (pos < name.size() && name[pos] == '<');
558  ++pos;
559  while (true) {
560  skipSpaces (name, pos);
561  m_targs.emplace_back (name, pos);
562  skipSpaces (name, pos);
563  if (pos == name.size()) break;
564  if (name[pos] == '>') {
565  ++pos;
566  break;
567  }
568  else if (name[pos] == ',')
569  ++pos;
570  else
571  break;
572  }
573 }

◆ qualifiedName()

std::string ClassName< T >::qualifiedName ( ) const

Return the namespace-qualified name of the expression.

Return the root name of the expression.

In A::B<C>, this is A::B.

In A::B<C>, the root name is B.

Definition at line 240 of file ClassName.cxx.

241 {
242  std::string nsname;
243  if (m_namespace.size() > 0)
244  nsname = m_namespace[0].fullName() + "::";
245  return nsname + m_name;
246 }

◆ setConst()

void ClassName< T >::setConst ( )

Set the const flag for this expression.

Definition at line 218 of file ClassName.cxx.

219 {
220  m_const = true;
221 }

◆ skipSpaces()

void ClassName< T >::skipSpaces ( const std::string &  name,
std::string::size_type &  pos 
)
private

Skip past spaces in a string.

Parameters
nameThe string containing the name.
posPosition in the string to start skipping.

On return, pos will be updated to point just past the last character consumed.

Definition at line 584 of file ClassName.cxx.

586 {
587  while (pos < name.size() && name[pos] == ' ')
588  ++pos;
589 }

◆ subst()

void ClassName< T >::subst ( const match_t matches)

Substitute variables into this expression.

Parameters
Thedictionary of variables to substitute.

If this expression contains variables like $T, they are replaced with the corresponding values from matches. If a variable is present in the expression but is not in matches, ExcMissingVariable is thrown.

The substitutions are made in-place.

Definition at line 357 of file ClassName.cxx.

358 {
359  if (m_name[0] == '$') {
360  std::string var = m_name.substr (1, std::string::npos);
361  match_t::const_iterator it = matches.find (var);
362  if (it != matches.end()) {
363  bool const_save = m_const;
364  *this = it->second;
365  m_const |= const_save;
366  }
367  else {
368  throw ExcMissingVariable (var);
369  }
370  }
371 
372  for (ClassName& c : m_namespace)
373  c.subst (matches);
374  for (ClassName& c : m_targs)
375  c.subst (matches);
376 }

◆ substCopy()

ClassName ClassName< T >::substCopy ( const match_t matches) const

Return a copy of this expression with variables substituted.

Parameters
Thedictionary of variables to substitute.

If this expression contains variables like $T, they are replaced with the corresponding values from matches. If a variable is present in the expression but is not in matches, ExcMissingVariable is thrown.

The substitutions are made in a copy of the expression, which is returned.

Definition at line 390 of file ClassName.cxx.

391 {
392  ClassName cn (*this);
393  cn.subst (matches);
394  return cn;
395 }

◆ swap()

void ClassName< T >::swap ( ClassName other)

Swap this expression with another one.

Parameters
otherThe other expression with which to swap.

Definition at line 197 of file ClassName.cxx.

198 {
199  std::swap (m_const, other.m_const);
200  std::swap (m_namespace, other.m_namespace);
201  std::swap (m_name, other.m_name);
202  m_targs.swap (other.m_targs);
203 }

◆ targ()

const ClassName & ClassName< T >::targ ( size_t  i) const

Return one template argument.

Parameters
iIndex of the argument to return.

Definition at line 285 of file ClassName.cxx.

286 {
287  return m_targs.at (i);
288 }

Member Data Documentation

◆ m_const

bool CxxUtils::ClassName::m_const
private

Is this expression const?

Definition at line 477 of file CxxUtils/CxxUtils/ClassName.h.

◆ m_name

std::string CxxUtils::ClassName::m_name
private

The primary name part of this expression.

Definition at line 486 of file CxxUtils/CxxUtils/ClassName.h.

◆ m_namespace

std::vector<ClassName> CxxUtils::ClassName::m_namespace
private

The containing namespace.

This vector is always either 0 or 1 elements long; this is a way of getting something sort of like a pointer but with completely automatic management.

Definition at line 483 of file CxxUtils/CxxUtils/ClassName.h.

◆ m_targs

std::vector<ClassName> CxxUtils::ClassName::m_targs
private

The template arguments for this name.

Definition at line 489 of file CxxUtils/CxxUtils/ClassName.h.


The documentation for this class was generated from the following files:
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
CxxUtils::ClassName::name
const std::string & name() const
Return the root name of the expression.
Definition: ClassName.cxx:229
CxxUtils::ClassName::setConst
void setConst()
Set the const flag for this expression.
Definition: ClassName.cxx:218
skel.it
it
Definition: skel.GENtoEVGEN.py:423
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
CxxUtils::ClassName::parse
void parse(const std::string &name, std::string::size_type &pos)
Parse a string into a ClassName.
Definition: ClassName.cxx:447
CxxUtils::ClassName::m_const
bool m_const
Is this expression const?
Definition: CxxUtils/CxxUtils/ClassName.h:477
CxxUtils::ClassName::parseNamespace
void parseNamespace(const std::string &name, std::string::size_type &pos)
Parse a namespace qualification.
Definition: ClassName.cxx:522
CxxUtils::ClassName::skipSpaces
void skipSpaces(const std::string &name, std::string::size_type &pos)
Skip past spaces in a string.
Definition: ClassName.cxx:584
lumiFormat.i
int i
Definition: lumiFormat.py:92
ret
T ret(T t)
Definition: rootspy.cxx:260
CxxUtils::ClassName::m_namespace
std::vector< ClassName > m_namespace
The containing namespace.
Definition: CxxUtils/CxxUtils/ClassName.h:483
CxxUtils::ClassName::m_targs
std::vector< ClassName > m_targs
The template arguments for this name.
Definition: CxxUtils/CxxUtils/ClassName.h:489
ClassName
An interface for getting the name of a class as a string.
Definition: AthenaKernel/AthenaKernel/ClassName.h:33
CxxUtils::ClassName::parseTemplateArgs
void parseTemplateArgs(const std::string &name, std::string::size_type &pos)
Parse the template part of a name.
Definition: ClassName.cxx:554
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
CxxUtils::ClassName::match1
bool match1(const ClassName &pattern, bool topLevel, match_t &matches) const
Match this expression against a pattern.
Definition: ClassName.cxx:603
CxxUtils::ClassName::applyRules1
bool applyRules1(const Rules &rules)
Apply a set of transformation rules to this object.
Definition: ClassName.cxx:674
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
python.SystemOfUnits.ns
int ns
Definition: SystemOfUnits.py:130
CxxUtils::ClassName::parsePrimary
std::string parsePrimary(const std::string &name, std::string::size_type &pos)
Parse a primary part of the class name.
Definition: ClassName.cxx:488
python.compressB64.c
def c
Definition: compressB64.py:93
CxxUtils::ClassName::m_name
std::string m_name
The primary name part of this expression.
Definition: CxxUtils/CxxUtils/ClassName.h:486
CxxUtils::ClassName::qualifiedName
std::string qualifiedName() const
Return the namespace-qualified name of the expression.
Definition: ClassName.cxx:240