23ClassName::ExcBadClassName::ExcBadClassName (
const std::string&
name)
24 : std::runtime_error (
"ExcBadClassName: Malformed class name: `" +
33ClassName::ExcMissingVariable::ExcMissingVariable (
const std::string& var)
35 "' referenced in substitution but not present "
44size_t ClassName::Rules::size()
const
46 return m_rules.size();
60void ClassName::Rules::add (
const ClassName& pattern,
63 m_rules.insert (std::make_pair (
pattern.name(),
64 std::make_pair (pattern, replacement)));
78void ClassName::Rules::add (
ClassName&& pattern,
82 m_rules.insert (std::make_pair (name,
83 std::make_pair (std::move(pattern),
84 std::move(replacement))));
99bool ClassName::Rules::applyTo (
ClassName& cn)
const
102 rulemap_t::const_iterator
it = m_rules.find (cn.
name());
103 while (it != m_rules.end() &&
it->first == cn.
name()) {
104 ClassName::match_t matches;
105 if (cn.match (
it->second.first, matches)) {
106 bool const_save = cn.isConst();
107 cn =
it->second.second.substCopy (matches);
127std::string ClassName::Rules::apply (
const std::string& name)
const
129 return ClassName::applyRules (name, *
this);
138ClassName::ClassName ()
150ClassName::ClassName (
const char*
name)
153 std::string sname =
name;
154 std::string::size_type pos = 0;
157 if (pos != sname.size())
168ClassName::ClassName (
const std::string&
name)
171 std::string::size_type pos = 0;
174 if (pos !=
name.size())
186ClassName::ClassName (
const std::string&
name, std::string::size_type& pos)
200 std::swap (m_namespace, other.m_namespace);
202 m_targs.swap (other.m_targs);
209bool ClassName::isConst()
const
218void ClassName::setConst()
240std::string ClassName::qualifiedName()
const
252std::string ClassName::fullName()
const
257 if (m_targs.size() > 0) {
262 name += cn.fullName();
275size_t ClassName::ntargs()
const
294bool ClassName::operator== (
const ClassName& other)
const
296 if (m_name != other.m_name)
299 if (m_const != other.m_const)
302 if (m_namespace.size() != other.m_namespace.size())
305 if (m_targs.size() != other.m_targs.size())
308 if (m_namespace.size() > 0 && m_namespace[0] != other.m_namespace[0])
311 for (
size_t i = 0; i < m_targs.size(); ++i) {
312 if (m_targs[i] != other.m_targs[i])
323bool ClassName::operator!= (
const ClassName& other)
const
325 return !(*
this==
other);
339bool ClassName::match (
const ClassName& pattern, match_t& matches)
const
342 return match1 (pattern,
true, matches);
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()) {
410void ClassName::applyRules (
const Rules& rules)
430std::string ClassName::applyRules (
const std::string& name,
434 cn.applyRules (rules);
435 return cn.fullName();
447void ClassName::parse (
const std::string& name, std::string::size_type& pos)
450 if (
m_name.compare (0, 6,
"const ") ==0) {
460 while (pos <
name.size()) {
461 if (
name[pos] ==
'<')
463 else if (
name[pos] ==
':' && pos+1 <
name.size() &&
name[pos+1] ==
':')
469 if (
name.compare (pos, 5,
"const")==0) {
488ClassName::parsePrimary (
const std::string&
name, std::string::size_type& pos)
493 while (pos <
name.size()) {
497 else if (c ==
')' && nest > 0)
499 else if (nest == 0 && (c ==
'<' || c ==
'>' || c ==
',' || c ==
':'))
522void ClassName::parseNamespace (
const std::string&
name,
523 std::string::size_type& pos)
525 assert (pos+1 <
name.size() &&
name[pos] ==
':' &&
name[pos+1] ==
':');
536 while (p->m_namespace.size() > 0)
537 p = &p->m_namespace[0];
538 p->m_namespace.push_back (std::move(ns));
554void ClassName::parseTemplateArgs (
const std::string&
name,
555 std::string::size_type& pos)
557 assert (pos <
name.size() &&
name[pos] ==
'<');
563 if (pos ==
name.size())
break;
564 if (
name[pos] ==
'>') {
568 else if (
name[pos] ==
',')
584void ClassName::skipSpaces (
const std::string&
name,
585 std::string::size_type& pos)
587 while (pos <
name.size() &&
name[pos] ==
' ')
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) {
616 return *
this == it->second;
619 matches[var] = *
this;
620 if (pattern.m_const) {
622 matches[var].m_const =
false;
634 if (pattern.m_const && !
m_const)
637 else if (
m_const != pattern.m_const) {
641 if (
m_name != pattern.m_name)
644 if (
m_namespace.size() != pattern.m_namespace.size())
647 if (
m_targs.size() != pattern.m_targs.size())
655 for (
size_t i = 0; i <
m_targs.size(); i++) {
674bool ClassName::applyRules1 (
const Rules& rules)
676 bool ret = rules.
applyTo (*
this);
681 for (
size_t i = 0; i <
m_targs.size(); i++)
Recursively separate out template arguments in a C++ class name.
An interface for getting the name of a class as a string.
static std::string name()
Return the name of class T as a string.
Recursively separate out template arguments in a C++ class name.
Exception to signal a missing variable.
A set of transformation rules to use with ClassName.
bool applyTo(ClassName &cn) const
Add a new transformation rule.
bool match1(const ClassName &pattern, bool topLevel, match_t &matches) const
Match this expression against a pattern.
std::map< std::string, ClassName > match_t
Map used to hold variable assignments from matching.
std::string parsePrimary(const std::string &name, std::string::size_type &pos)
Parse a primary part of the class name.
void skipSpaces(const std::string &name, std::string::size_type &pos)
Skip past spaces in a string.
const std::string & name() const
Return the root name of the expression.
bool m_const
Is this expression const?
std::vector< ClassName > m_targs
The template arguments for this name.
bool applyRules1(const Rules &rules)
Apply a set of transformation rules to this object.
std::vector< ClassName > m_namespace
The containing namespace. This vector is always either 0 or 1 elements long; this is a way of getting...
std::string m_name
The primary name part of this expression.
ClassName()
Default constructor.
std::string qualifiedName() const
Return the namespace-qualified name of the expression.
void parseNamespace(const std::string &name, std::string::size_type &pos)
Parse a namespace qualification.
void setConst()
Set the const flag for this expression.
void parseTemplateArgs(const std::string &name, std::string::size_type &pos)
Parse the template part of a name.
void parse(const std::string &name, std::string::size_type &pos)
Parse a string into a ClassName.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)