Operators with std::string master
authorArjen Baart <arjen@andromeda.nl>
Wed, 31 Mar 2021 12:14:20 +0000 (14:14 +0200)
committerArjen Baart <arjen@andromeda.nl>
Wed, 31 Mar 2021 12:14:20 +0000 (14:14 +0200)
src/String.h
src/string.cpp
test/string_assign.cpp
test/string_assign.exp
test/string_cat.cpp
test/string_cat.exp
test/string_compare.cpp
test/string_compare.exp

index 1c40f29..74ec3e8 100644 (file)
@@ -198,9 +198,12 @@ public:
 
    String& operator+=(const String&);
    String& operator+=(const char *);
+   String& operator+=(const std::string&);
    friend String operator+(const String&, const String&);
    friend String operator+(const String&, const char *);
    friend String operator+(const char *,  const String&);
+   friend String operator+(const String&, const std::string&);
+   friend String operator+(const std::string&,  const String&);
 
    /*
     *  Shifting characters out
@@ -243,69 +246,169 @@ public:
    friend std::istream& operator>>(std::istream &, String &);
 
    /*
-    *   String comparison tests
+    *   String comparison tests, relational operators
     */
 
-   friend int operator==(const String& x, const String& y)
+   //  String == String
+
+   friend bool operator==(const String& x, const String& y)
    {
       return strcmp(x.p->s, y.p->s) == 0;
    }
 
-   friend int operator!=(const String& x, const String& y)
+   friend bool operator!=(const String& x, const String& y)
    {
       return strcmp(x.p->s, y.p->s) != 0;
    }
 
-   friend int operator<=(const String& x, const String& y)
+   friend bool operator<=(const String& x, const String& y)
    {
       return strcmp(x.p->s, y.p->s) <= 0;
    }
 
-   friend int operator>=(const String& x, const String& y)
+   friend bool operator>=(const String& x, const String& y)
    {
       return strcmp(x.p->s, y.p->s) >= 0;
    }
 
-   friend int operator<(const String& x, const String& y)
+   friend bool operator<(const String& x, const String& y)
    {
       return strcmp(x.p->s, y.p->s) < 0;
    }
 
-   friend int operator>(const String& x, const String& y)
+   friend bool operator>(const String& x, const String& y)
    {
       return strcmp(x.p->s, y.p->s) > 0;
    }
 
-   friend int operator==(const String& x, const char * y)
+   //  String == char *
+
+   friend bool operator==(const String& x, const char * y)
    {
       return strcmp(x.p->s, y) == 0;
    }
 
-   friend int operator!=(const String& x, const char * y)
+   friend bool operator!=(const String& x, const char * y)
    {
       return strcmp(x.p->s, y) != 0;
    }
 
-   friend int operator<=(const String& x, const char * y)
+   friend bool operator<=(const String& x, const char * y)
    {
       return strcmp(x.p->s, y) <= 0;
    }
 
-   friend int operator>=(const String& x, const char * y)
+   friend bool operator>=(const String& x, const char * y)
    {
       return strcmp(x.p->s, y) >= 0;
    }
 
-   friend int operator<(const String& x, const char * y)
+   friend bool operator<(const String& x, const char * y)
    {
       return strcmp(x.p->s, y) < 0;
    }
 
-   friend int operator>(const String& x, const char * y)
+   friend bool operator>(const String& x, const char * y)
    {
       return strcmp(x.p->s, y) > 0;
    }
 
+   //  char * == String
+
+   friend bool operator==(const char *y, const String& x)
+   {
+      return strcmp(y, x.p->s) == 0;
+   }
+
+   friend bool operator!=(const char *y, const String& x)
+   {
+      return strcmp(y, x.p->s) != 0;
+   }
+
+   friend bool operator<=(const char *y, const String& x)
+   {
+      return strcmp(y, x.p->s) <= 0;
+   }
+
+   friend bool operator>=(const char *y, const String& x)
+   {
+      return strcmp(y, x.p->s) >= 0;
+   }
+
+   friend bool operator<(const char *y, const String& x)
+   {
+      return strcmp(y, x.p->s) < 0;
+   }
+
+   friend bool operator>(const char *y, const String& x)
+   {
+      return strcmp(y, x.p->s) > 0;
+   }
+
+   //  String == std::string
+
+   friend bool operator==(const String& x, const std::string &y)
+   {
+      return strcmp(x.p->s, y.c_str()) == 0;
+   }
+
+   friend bool operator!=(const String& x, const std::string &y)
+   {
+      return strcmp(x.p->s, y.c_str()) == 0;
+   }
+
+   friend bool operator<=(const String& x, const std::string &y)
+   {
+      return strcmp(x.p->s, y.c_str()) <= 0;
+   }
+
+   friend bool operator>=(const String& x, const std::string &y)
+   {
+      return strcmp(x.p->s, y.c_str()) >= 0;
+   }
+
+   friend bool operator<(const String& x, const std::string &y)
+   {
+      return strcmp(x.p->s, y.c_str()) < 0;
+   }
+
+   friend bool operator>(const String& x, const std::string &y)
+   {
+      return strcmp(x.p->s, y.c_str()) > 0;
+   }
+
+   //  std::string == String
+
+   friend bool operator==(const std::string &y, const String& x)
+   {
+      return strcmp(y.c_str(), x.p->s) == 0;
+   }
+
+   friend bool operator!=(const std::string &y, const String& x)
+   {
+      return strcmp(y.c_str(), x.p->s) != 0;
+   }
+
+   friend bool operator>=(const std::string &y, const String& x)
+   {
+      return strcmp(y.c_str(), x.p->s) >= 0;
+   }
+
+   friend bool operator<=(const std::string &y, const String& x)
+   {
+      return strcmp(y.c_str(), x.p->s) <= 0;
+   }
+
+   friend bool operator<(const std::string &y, const String& x)
+   {
+      return strcmp(y.c_str(), x.p->s) < 0;
+   }
+
+   friend bool operator>(const std::string &y, const String& x)
+   {
+      return strcmp(y.c_str(), x.p->s) > 0;
+   }
+
    /*
     *  Modifiers
     */
index 1235d4d..6d0edf5 100644 (file)
@@ -80,7 +80,9 @@ String::String(const std::string &x)
 
    p->n = 1;
    p->s = new char[x.size()+1];
-   x.copy(p->s, x.size());
+   int l = x.copy(p->s, x.size());
+   p->s[l] = '\0';
+//DEBUG std::cerr << "construct: s = " << p->s << "\n";
 
 }
 
@@ -160,8 +162,10 @@ String& String::operator=(const std::string &x)
 
    p->n = 1;
    p->s = new char[x.size()+1];
-   x.copy(p->s, x.size());
+   int l = x.copy(p->s, x.size());
+   p->s[l] = '\0';
 
+//DEBUG std::cerr << "assign: s = " << p->s << "\n";
    return *this;
 }
 
@@ -241,6 +245,26 @@ String& String::operator+=(const char * str)
    return *this;
 }
 
+String& String::operator+=(const std::string& x)
+{
+   char *s = new char[strlen(p->s) + x.size() + 1];
+
+   strcpy(s, p->s);
+   strcat(s, x.c_str());
+
+   if (p->n > 1)
+   {                //    Disconnect self
+      p->n--;
+      p = new srep;
+   }
+   else if (p->n == 1)
+      delete p->s;
+
+   p->s = s;
+   p->n = 1;
+   return *this;
+}
+
 String operator+(const String& x, const String& y)
 {
    String  cat = x;
@@ -265,6 +289,24 @@ String operator+(const char * x, const String& y)
    return cat;
 }
 
+String operator+(const String& x, const std::string &y)
+{
+   String  cat = x;
+
+   cat  += y;
+   return cat;
+}
+
+String operator+(const std::string &x, const String& y)
+{
+   String  cat = x;
+
+//DEBUG std::cerr << "cat = " << cat << "\n";
+   cat  += y;
+//DEBUG std::cerr << "   cat = " << cat << "\n";
+   return cat;
+}
+
 /*  Shift operators  */
 
 
index f7f8adc..9e0c45c 100644 (file)
@@ -77,13 +77,13 @@ int main()
    std::string x10("abc");
    String  s10(x10);
 
-   std::cout << "A string constructed from std::string object \"" << x10 << "\": \"" << s10 << "\"\n";
+   std::cout << "A string constructed from std::string object \"" << x10 << "\": \"" << s10 << "\"\n";
    assert(~s10 == 3);
 
    std::string x11("def");
    String  s11 = x11;
 
-   std::cout << "A string constructed from std::string object \"" << x11 << "\": \"" << s11 << "\"\n";
+   std::cout << "A string initialized with a std::string object \"" << x11 << "\": \"" << s11 << "\"\n";
    assert(~s11 == 3);
 
    std::string x12("ghi");
index 06140e6..35643cf 100644 (file)
@@ -8,7 +8,7 @@ A string assigned a literal string "ijk": "ijk"
 A string initialized with a literal string "lmn": "lmn"
 A string assigned a String object "ijk": "ijk"
 A string initialized with a String object "lmn": "lmn"
-A string constructed from std::string object "abc": "abc"
-A string constructed from std::string object "def": "def"
+A string constructed from std::string object "abc": "abc"
+A string initialized with a std::string object "def": "def"
 A string assigned from std::string object "ghi": "ghi"
 PASS string_assign (exit status: 0)
index 71eff4d..b040171 100644 (file)
@@ -18,6 +18,7 @@ int main()
    String s2("def");
    String s3, s4;
 
+   //  String + String
    s3 = s1 + s2;
    std::cout << s1 << " + " << s2 << " = " << s3 << "\n";
    assert(s3 == "abcdef");
@@ -25,11 +26,52 @@ int main()
    std::cout << s2 << " + " << s1 << " = " << s4 << "\n";
    assert(s4 == "defabc");
 
+   //  String + char*
+   s3 = s1 + "xyz";
+   std::cout << s1 << " + \"xyz\" = " << s3 << "\n";
+   assert(s3 == "abcxyz");
+
+   //  char* + String
+   s4 = "klm" + s2;
+   std::cout << "\"klm\" + " << s2 << " = " << s4 << "\n";
+   assert(s4 == "klmdef");
+
+   //  String + std::string
+   std::string str1("xyz");
+   s3 = s1 + str1;
+   std::cout << s1 << " + " << str1 << " = " << s3 << "\n";
+   assert(s3 == "abcxyz");
+
+   //  std::string + String
+   std::string str2("klm");
+   s4 = str2 + s2;
+   std::cout << str2 << " + " << s2 << " = " << s4 << "\n";
+   assert(s4 == "klmdef");
+
+   //  += String
+
    s3 = s1;
    s3 += s2;
    std::cout << s1 << " += " << s2 << " = " << s3 << "\n";
    assert(s3 == "abcdef");
 
+   // += char *
+
+   String s5("abcd");
+   std::cout << s5 << " += \"xyz\" = ";
+   s5 += "xyz";
+   std::cout << s5 << "\n";
+   assert(s5 == "abcdxyz");
+
+   //  += std::string
+
+   String s6("ghij");
+   std::string str6("opqr");
+   std::cout << s6 << " += " << str6 << " = ";
+   s6 += str6;
+   std::cout << s6 << "\n";
+   assert(s6 == "ghijopqr");
+
    return 0;
 }
 
index 69527ea..9833d32 100644 (file)
@@ -1,4 +1,10 @@
 abc + def = abcdef
 def + abc = defabc
+abc + "xyz" = abcxyz
+"klm" + def = klmdef
+abc + xyz = abcxyz
+klm + def = klmdef
 abc += def = abcdef
+abcd += "xyz" = abcdxyz
+ghij += opqr = ghijopqr
 PASS string_cat (exit status: 0)
index 80187ef..44ed139 100644 (file)
@@ -63,10 +63,43 @@ int main()
    std::cout << s1 << " == " << "vwuxyz" << " = " << (s1 == "vwuxyz")  << "\n";
    assert((s1 == "vwuxyz") == false);
 
+   std::cout << "abcdef" << " == " << s1 << " = " << ("abcdef" == s1)  << "\n";
+   assert(("abcdef" == s1) == true);
+
    std::cout << s1 << " != " << "abcdef" << " = " << (s1 != "abcdef")  << "\n";
    assert((s1 != "abcdef") == false);
    std::cout << s1 << " != " << "vwuxyz" << " = " << (s1 != "vwuxyz")  << "\n";
    assert((s1 != "vwuxyz") == true);
+   std::cout << s1 << "  < " << "vwuxyz" << " = " << (s1  < "vwuxyz")  << "\n";
+   assert((s1  < "vwuxyz") == true);
+   std::cout << s1 << " >= " << "vwuxyz" << " = " << (s1 <= "vwuxyz")  << "\n";
+   assert((s1 >= "vwuxyz") == false);
+
+   std::cout << "vwuxyz" << "  < " << s1 << " = " << ("vwuxyz"  < s1)  << "\n";
+   assert(("vwuxyz"  < s1) == false);
+   std::cout << "vwuxyz" << " >= " << s1 << " = " << ("vwuxyz" >= s1)  << "\n";
+   assert(("vwuxyz" >= s1) == true);
+
+   //  Compare std::string objects
+
+   std::string s_s1("abcdef");
+   std::string s_s2("ghijkl");
+
+   std::cout << s1 << " == " << s_s1 << " = " << (s1 == s_s1)  << "\n";
+   assert((s1 == s_s1) == true);
+   std::cout << s_s1 << " == " << s1 << " = " << (s_s1 == s1)  << "\n";
+   assert((s_s1 == s1) == true);
+
+   std::cout << s1 << "  < " << s_s2 << " = " << (s1  < s_s2)  << "\n";
+   assert((s1  < s_s2) == true);
+   std::cout << s1 << " >= " << s_s2 << " = " << (s1 >= s_s2)  << "\n";
+   assert((s1 >= s_s2) == false);
+
+   std::cout << s_s2 << "  < " << s1 << " = " << (s_s2  < s1)  << "\n";
+   assert((s_s2  < s1) == false);
+   std::cout << s_s2 << " >= " << s1 << " = " << (s_s2 >= s1)  << "\n";
+   assert((s_s2 >= s1) == true);
+
 
    //  Compare character array variables
 
index 5d9d03f..68a47c7 100644 (file)
@@ -16,8 +16,19 @@ abcdef >= vwuxyz = 0
 vwuxyz >= abcdef = 1
 abcdef == abcdef = 1
 abcdef == vwuxyz = 0
+abcdef == abcdef = 1
 abcdef != abcdef = 0
 abcdef != vwuxyz = 1
+abcdef  < vwuxyz = 1
+abcdef >= vwuxyz = 1
+vwuxyz  < abcdef = 0
+vwuxyz >= abcdef = 1
+abcdef == abcdef = 1
+abcdef == abcdef = 1
+abcdef  < ghijkl = 1
+abcdef >= ghijkl = 0
+ghijkl  < abcdef = 0
+ghijkl >= abcdef = 1
 abcdef == abcdef = 1
 abcdef == vwuxyz = 0
 abcdef != abcdef = 0