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:
Fischlurch 2017-04-07 18:04:49 +02:00
parent 29b8b2b8bc
commit 23c412bc42
2 changed files with 35 additions and 97 deletions

View file

@ -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()}

View file

@ -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