在词法分析的时候,以下面的代码为例。
class String
{
public:
typedef unsigned char byte_t;
typedef unsigned long size_t;
public:
String()
{
}
};
这里面,每一个Token的长度往往不超过7,所以这个String在处理string length的长度小于7的字符串的时候,不需要在堆上分配内存。
而且整个类的sizeof(String)只有8,远远小于VC实现的std::string的sizeof(std::string)==28。
缺点是,很多关于字符串的操作会判断一个标志位,影响了速度,但是从词法分析的角度考虑,String类的整体表现会很好。
聚合了这个结构。
union string_t
{
struct SP
{
byte_t* ptr;
unsigned short len;
byte_t flag;
byte_t unused;
} s2;
struct SA
{
byte_t arr[8];
} s1;
} s;
整个代码是这样的。
#ifndef __STRING_HPP__
#define __STRING_HPP__
#include "Alloc.hpp"
#define CRITICAL 0x07
class String
{
public:
typedef unsigned char byte_t;
typedef unsigned long size_t;
public:
String()
{
}
String(const char* str)
{
size_t len = strlen(str);
if (len < CRITICAL)
{
_construct1((const byte_t*)str, len);
}
else
{
_construct2((const byte_t*)str, len);
}
}
String(String const& _right)
{
size_t len = _right.length();
if (len < CRITICAL)
{
_construct1((const byte_t*)_right.bytes(), len);
}
else
{
_construct2((const byte_t*)_right.bytes(), len);
}
}
String(const char* str, size_t offset, size_t len)
{
size_t leave = strlen(str + offset);
if (leave < CRITICAL)
{
_construct1((const byte_t*)str + offset, (len < leave) ? len : leave);
}
else
{
_construct2((const byte_t*)str + offset, (len < leave) ? len : leave);
}
}
size_t length() const
{
return (s.SP::flag) ? (size_t)s.SP::len : (size_t)s.SA::arr[7];
}
const byte_t* bytes() const
{
return (s.SP::flag) ? (const byte_t*)s.SP::ptr : (const byte_t*)s.SA::arr;
}
String replace(String const& str1, String const& str2)
{
return String();
}
String substring(size_t offset, size_t count)
{
return String((const char*)bytes(), offset, count);
}
private:
void _construct1(const byte_t* ptr, size_t len)
{
strcpy((char*)s.SA::arr, (char*)ptr);
s.SA::arr[6] = 0;
s.SA::arr[7] = (byte_t)len;
}
void _construct2(const byte_t* ptr, size_t len)
{
byte_t* p = Alloc<byte_t>::alloc(len);
strcpy((char*)p, (const char*)ptr);
s.SP::ptr = p;
s.SP::len = (unsigned short)len;
s.SP::flag = (byte_t)0xff;
s.SP::unused = (byte_t)0x00;
}
private:
union string_t
{
struct SP
{
byte_t* ptr;
unsigned short len;
byte_t flag;
byte_t unused;
} s2;
struct SA
{
byte_t arr[8];
} s1;
} s;
};
#endif
测试一下:
int s = sizeof(String);
String s1("Hello");
String s2("Hello world");
String s3 = s2;
char* p1 = (char*)s1.bytes();
char* p2 = (char*)s2.bytes();
int l1 = s1.length();
int l2 = s2.length();
int l3 = s3.length();
String s4 = s2.substring(6, 5);
int l4 = s4.length();
String s5 = s2.substring(6, 6);
int l5 = s4.length();
String s6 = s1.substring(0, 3);
int l6 = s6.length();