// string.C
// ----------------------------------------------------------------
// COMP 290-001: Algorithm Library Design, Lutz Kettner, 02/28/2000
// String example with const-correct use of reference and pointer.

#include <stdlib.h>
#include <assert.h>
#include <string.h>

class string {
    char*           s;
    mutable size_t  l;
    mutable bool    valid;
public:
    string() : s(0), l(0), valid(true) {}
    size_t  length() const;  // const, does not change string conceptually
    char&        operator[]( int idx)       { valid = false; return s[idx];}
    const char&  operator[]( int idx) const { return s[idx];}
    char* &      get_pointer()              { valid = false; return s; }
    const char*  get_pointer()        const { return s; }
    // ... some more functions
};

size_t string::length() const {
    if ( ! valid) {
        l = strlen(s); // violates bitwise constness,
        valid = true;  // but 'mutable' makes it possible.
    }
    return l;
}

int main() {
    char  buf[6] = "Hallo"; // German
    string s;
    s.get_pointer() = buf;
    assert( s[1] == 'a');
    assert( s.length() == 5);
    s[1] = 'e';  // Now it's in English
    assert( s[1] == 'e');

    // get a const reference to the same string:
    const string& r = s;
    assert( r.length() == 5);
    // r.get_pointer() = "Salute"; // does not work with const char *, r-value
    assert( r[1] == 'e');
    // r[1] = 'a'; // no, does not work with const char &
}

// EOF //

