Hey ppl,
I came across something weird today, and I was wondering if any of you here could explain what's happening...
Here's a sample:
#include <iostream>
#include <cassert>
using namespace std;
#define REQUIRE_STRING(s) assert(s != 0)
#define REQUIRE_STRING_LEN(s, n) assert(s != 0 || n == 0)
class String {
public:
String(const char *str, size_t len) : __data(__construct(str, len)), __len(len) {}
~String() { __destroy(__data); }
const char *toString() const {
return const_cast<const char *>(__data);
}
String &toUpper() {
REQUIRE_STRING_LEN(__data, __len);
char *it = __data;
while(it < __data + __len) {
if(*it >= 'a' && *it <= 'z')
*it -= 32;
++it;
}
return *this;
}
String &toLower() {
REQUIRE_STRING_LEN(__data, __len);
char *it = __data;
while(it < __data + __len) {
if(*it >= 'A' && *it <= 'Z')
*it += 32;
++it;
}
return *this;
}
private:
char *__data;
size_t __len;
protected:
static char *__construct(const char *str, size_t len) {
REQUIRE_STRING_LEN(str, len);
char *data = new char[len];
std::copy(str, str + len, data);
return data;
}
static void __destroy(char *data) {
REQUIRE_STRING(data);
delete[] data;
}
};
int main() {
String s("Hello world!", __builtin_strlen("Hello world!"));
cout << s.toLower().toString() << endl;
cout << s.toUpper().toString() << endl;
cout << s.toLower().toString() << endl << s.toUpper().toString() << endl;
return 0;
}
Now, I had expected the output to be:
hello world!
HELLO WORLD!
hello world!
HELLO WORLD!
but instead I got this:
hello world!
HELLO WORLD!
hello world!
hello world!
I can't really understand why the second toUpper
didn't have any effect.