Symbol: rework equality comparisons (#417)
For this task, I've also investigated to use boost::operators This would only incur a negligible penalty on build times and executable sizes, however, I don't consider the boost based solution to improve readability, since many of these comparisons are tricky or subtly different. Moreover, since boost::operators needs to be mixed-in, the initialisation of Symbol objects becomes difficult, not to mention the additional base class information visible in the debugger when inspecting Symbol or Literal objects For that reason, I decided *against* using Boost here and coded up all the operators in all combinations manually
This commit is contained in:
parent
29b8b2b8bc
commit
23c412bc42
2 changed files with 35 additions and 97 deletions
|
|
@ -59,12 +59,12 @@ namespace lib {
|
|||
const size_t STRING_MAX_RELEVANT = LUMIERA_IDSTRING_MAX_RELEVANT;
|
||||
|
||||
|
||||
/** equality on Symbol values is defined
|
||||
/** equality on Literal and Symbol values is defined
|
||||
* based on the content, not the address. */
|
||||
bool
|
||||
operator== (Literal sy1, Literal sy2)
|
||||
Literal::operator== (const char* cString) const
|
||||
{
|
||||
return !lumiera_strncmp (sy1,sy2, STRING_MAX_RELEVANT);
|
||||
return !lumiera_strncmp (this->str_, cString, STRING_MAX_RELEVANT);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ namespace lib {
|
|||
|
||||
/** create Symbol by symbol table lookup.
|
||||
* @note identical strings will be mapped to
|
||||
* the same Literal (embedded pointer)
|
||||
* the same Symbol (embedded pointer)
|
||||
*/
|
||||
Symbol::Symbol (string&& definition)
|
||||
: Literal{symbolTable.insert(forward<string> (definition)).first->c_str()}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ namespace lib {
|
|||
return !str_ || 0 == std::strlen(str_);
|
||||
}
|
||||
|
||||
bool operator== (const char* cString) const;
|
||||
|
||||
protected:
|
||||
/** Assignment prohibited */
|
||||
Literal& operator= (const char* newStr)
|
||||
|
|
@ -131,104 +133,40 @@ namespace lib {
|
|||
|
||||
size_t hash_value (Literal);
|
||||
|
||||
bool operator== (Literal sy1, Literal sy2);
|
||||
|
||||
/* === equality comparisons === */
|
||||
|
||||
inline bool operator== (Literal const& s1, Literal const& s2) { return s1.operator== (s2.c()); }
|
||||
inline bool operator== (Symbol const& s1, Symbol const& s2) { return s1.c() == s2.c(); } ///< @note comparison of symbol table entries
|
||||
|
||||
inline bool
|
||||
operator!= (Literal sy1, Literal sy2)
|
||||
{
|
||||
return not (sy1 == sy2);
|
||||
}
|
||||
/* === mixed comparisons === */
|
||||
|
||||
/** @note two symbols are equal iff
|
||||
* they use the same symbol table entry
|
||||
*/
|
||||
inline bool
|
||||
operator== (Symbol sy1, Symbol sy2)
|
||||
{
|
||||
return sy1.c() == sy2.c();
|
||||
}
|
||||
inline bool operator== (const char* s1, Literal s2) { return s2.operator== (s1); }
|
||||
inline bool operator== (Symbol s1, const char* s2) { return s1.operator== (s2); }
|
||||
inline bool operator== (const char* s1, Symbol s2) { return s2.operator== (s1); }
|
||||
inline bool operator== (Literal s1, Symbol s2) { return s1.operator== (s2.c()); }
|
||||
inline bool operator== (Symbol s1, Literal s2) { return s2.operator== (s1.c()); }
|
||||
inline bool operator== (Literal s1, std::string s2) { return s1.operator== (s2.c_str()); }
|
||||
inline bool operator== (std::string s1, Literal s2) { return s2.operator== (s1.c_str()); }
|
||||
inline bool operator== (Symbol s1, std::string s2) { return s1.operator== (s2.c_str()); }
|
||||
inline bool operator== (std::string s1, Symbol s2) { return s2.operator== (s1.c_str()); }
|
||||
|
||||
inline bool
|
||||
operator!= (Symbol sy1, Symbol sy2)
|
||||
{
|
||||
return not (sy1 == sy2);
|
||||
}
|
||||
/* === negations === */
|
||||
|
||||
inline bool operator!= (Literal const& s1, Literal const& s2) { return not s1.operator== (s2.c()); }
|
||||
inline bool operator!= (Symbol const& s1, Symbol const& s2) { return not (s1.c() == s2.c()); }
|
||||
inline bool operator!= (Literal s1, const char* s2) { return not s1.operator== (s2); }
|
||||
inline bool operator!= (const char* s1, Literal s2) { return not s2.operator== (s1); }
|
||||
inline bool operator!= (Symbol s1, const char* s2) { return not s1.operator== (s2); }
|
||||
inline bool operator!= (const char* s1, Symbol s2) { return not s2.operator== (s1); }
|
||||
inline bool operator!= (Literal s1, Symbol s2) { return not s1.operator== (s2.c()); }
|
||||
inline bool operator!= (Symbol s1, Literal s2) { return not s2.operator== (s1.c()); }
|
||||
inline bool operator!= (Literal s1, std::string s2) { return not s1.operator== (s2.c_str()); }
|
||||
inline bool operator!= (std::string s1, Literal s2) { return not s2.operator== (s1.c_str()); }
|
||||
inline bool operator!= (Symbol s1, std::string s2) { return not s1.operator== (s2.c_str()); }
|
||||
inline bool operator!= (std::string s1, Symbol s2) { return not s2.operator== (s1.c_str()); }
|
||||
|
||||
|
||||
/// mixed comparison based on string equality
|
||||
inline bool
|
||||
operator== (Symbol sy1, Literal sy2)
|
||||
{
|
||||
return Literal(sy1) == sy2;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator== (Literal sy1, Symbol sy2)
|
||||
{
|
||||
return sy1 == Literal(sy2);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (Symbol sy1, Literal sy2)
|
||||
{
|
||||
return not (sy1 == sy2);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (Literal sy1, Symbol sy2)
|
||||
{
|
||||
return not (sy1 == sy2);
|
||||
}
|
||||
|
||||
|
||||
/// comparison with c-strings //////TICKET #417
|
||||
inline bool
|
||||
operator== (Literal sy1, const char* sy2)
|
||||
{
|
||||
return (sy1 == Literal(sy2));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator== (const char* sy1, Literal sy2)
|
||||
{
|
||||
return (Literal(sy1) == sy2);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (Literal sy1, const char* sy2)
|
||||
{
|
||||
return ! (sy1 == Literal(sy2));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (const char* sy1, Literal sy2)
|
||||
{
|
||||
return ! (Literal(sy1) == sy2);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator== (Symbol sy1, const char* sy2)
|
||||
{
|
||||
return (Literal(sy1) == Literal(sy2));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator== (const char* sy1, Symbol sy2)
|
||||
{
|
||||
return (Literal(sy1) == Literal(sy2));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (Symbol sy1, const char* sy2)
|
||||
{
|
||||
return ! (Literal(sy1) == Literal(sy2));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (const char* sy1, Symbol sy2)
|
||||
{
|
||||
return ! (Literal(sy1) == Literal(sy2));
|
||||
}
|
||||
|
||||
/// string concatenation
|
||||
inline std::string
|
||||
|
|
|
|||
Loading…
Reference in a new issue