From 23c412bc42c39fb577ea7a072f6fcea09491c28c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 7 Apr 2017 18:04:49 +0200 Subject: [PATCH] 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 --- src/lib/symbol-impl.cpp | 8 +-- src/lib/symbol.hpp | 124 ++++++++++------------------------------ 2 files changed, 35 insertions(+), 97 deletions(-) diff --git a/src/lib/symbol-impl.cpp b/src/lib/symbol-impl.cpp index e677fc7d5..d4852cad8 100644 --- a/src/lib/symbol-impl.cpp +++ b/src/lib/symbol-impl.cpp @@ -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 (definition)).first->c_str()} diff --git a/src/lib/symbol.hpp b/src/lib/symbol.hpp index b6356f322..681ee99f4 100644 --- a/src/lib/symbol.hpp +++ b/src/lib/symbol.hpp @@ -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