From ee5ad96a9b57db93e7540b208b4bad2204af856d Mon Sep 17 00:00:00 2001 From: Arjen Baart Date: Wed, 31 Mar 2021 14:14:20 +0200 Subject: [PATCH] Operators with std::string --- src/String.h | 129 +++++++++++++++++++++++++++++++++++++++++++----- src/string.cpp | 46 ++++++++++++++++- test/string_assign.cpp | 4 +- test/string_assign.exp | 4 +- test/string_cat.cpp | 42 ++++++++++++++++ test/string_cat.exp | 6 +++ test/string_compare.cpp | 33 +++++++++++++ test/string_compare.exp | 11 +++++ 8 files changed, 256 insertions(+), 19 deletions(-) diff --git a/src/String.h b/src/String.h index 1c40f29..74ec3e8 100644 --- a/src/String.h +++ b/src/String.h @@ -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 */ diff --git a/src/string.cpp b/src/string.cpp index 1235d4d..6d0edf5 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -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 */ diff --git a/test/string_assign.cpp b/test/string_assign.cpp index f7f8adc..9e0c45c 100644 --- a/test/string_assign.cpp +++ b/test/string_assign.cpp @@ -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 a 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"); diff --git a/test/string_assign.exp b/test/string_assign.exp index 06140e6..35643cf 100644 --- a/test/string_assign.exp +++ b/test/string_assign.exp @@ -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 a 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) diff --git a/test/string_cat.cpp b/test/string_cat.cpp index 71eff4d..b040171 100644 --- a/test/string_cat.cpp +++ b/test/string_cat.cpp @@ -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; } diff --git a/test/string_cat.exp b/test/string_cat.exp index 69527ea..9833d32 100644 --- a/test/string_cat.exp +++ b/test/string_cat.exp @@ -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) diff --git a/test/string_compare.cpp b/test/string_compare.cpp index 80187ef..44ed139 100644 --- a/test/string_compare.cpp +++ b/test/string_compare.cpp @@ -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 diff --git a/test/string_compare.exp b/test/string_compare.exp index 5d9d03f..68a47c7 100644 --- a/test/string_compare.exp +++ b/test/string_compare.exp @@ -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 -- 2.11.0