My "lightweight string" class (Was: Lightweight string class?)

My "lightweight string" class (Was: Lightweight string class?)

Post by Alan McKen » Thu, 22 Sep 2005 09:13:48


The responses to my posting "Lightweight string class?"
were interesting, but I didn't see anyone pointing to
an implementation along the lines I was hoping for.


So I wrote one myself (see below.) It compiles on Solaris and seems
to work OK. The only problem is that it isn't at all
standard-conformant.
(And it looks a little funky when you print it out from "dbx".)

Fortunately, it's likely to work on most of the currently popular
architectures and implementations.

(I'll leave counting the ways it violates the standard as an
exercise to the reader.)


1. No "new" or "delete"

2. Assignment and comparison work between strings of differing
lengths.

3. The only code in the LWString<> classes are glue functions
for the constructors (unavoidable) and for the assignment
operators, so you can use LWString<>s with lots of different
lengths without ending up with lots of essentially duplicated
code.

Does anyone have any suggestions for making it more
standard-conformant,
without losing efficiency or introducing a lot of code bloat?


Here is an edited version of what I came up with, with the
code for one of the functions, to illustrate how the data is accessed:

class LWStringBase
{
public:
const char *c_str() const { return data; }
bool operator==( const LWStringBase &rhs ) const;
bool operator==( const char *rhs ) const;

// other std::string-like functions ....

protected:
LWStringBase( int mx );
LWStringBase( int mx, const char *src, int sz = -1 );
LWStringBase( int mx, const LWStringBase &src );
void assign( LWStringBase &lhs, const LWStringBase &rhs );
void assign( LWStringBase &lhs, const char *rhs );

const unsigned char maxSize;
unsigned char len;
char data[1];
};

template<int n> class LWString : public LWStringBase
{
public:
LWString() : LWStringBase( n ) {}
LWString( const LWStringBase &rhs ) : LWStringBase( n, rhs ) {}
LWString( const char *rhs ) : LWStringBase( n, rhs ) {}

// supplied in derived class to get the return type right.

LWString &operator=( const LWStringBase &rhs )
{ assign( *this, rhs ); return *this; }
LWString &operator=( const char *rhs )
{ assign( *this, rhs ); return *this; }

protected:
char more_data[n];
};

// Implementation of one of the constructors, to show how
// we run off the end of "data" into the derived class's memory.

LWStringBase::LWStringBase( int mx, const LWStringBase &src ) :
maxSize( mx ), len( 0 )
{
unsigned char sz_u = src.len;
if ( sz_u > maxSize )
{
sz_u = maxSize;
}
len = sz_u;
for ( int i = 0; i < sz_u ; ++i )
{
data[i] = src.data[i];
}
data[sz_u] = 0;
}


-- Alan McKenney
XXXX@XXXXX.COM
<line-eater fodder>


[ See http://www.yqcomputer.com/ ]
[ comp.lang.c++.moderated. First time posters: Do this! ]