Just to throw out here some code to play with strings.
Taking unostrings.cxx there's some template cunning which generates
objects with the same layout as a OString, but without any constructors,
so that the StaticInit_OString macro generates OString-alike objects
which require effectively 0 setup time and can be shoved by the linker
into the rodata section.
16unistrings.cxx then extends this to add support for the "u" 16bit
string literals as found in c++0x (g++ --std=c++0x) and taking advantage
that wchar_t being 16bits in msvc the (though untested) "L" identifier
there. This would have the downside that the string literal storage in
the binary is now double the size it is now, but the upside that we
completely elide ::createFromAscii and/or the OUString constructor and
elide their destructors too of course.
Catch is though, that because OStrings and OUStrings do shallow copies,
copying one of these magic-strings about the place leaves it very
possible that a shallow-copy of the string will outlive the "stack
string" and die horribly. So to be safe the OString/OUString copy
methods would have to be tweaked to do a deep copy when one of these
shows up. But if the stack strings were only passed around by reference,
then they wouldn't need to get copied. A big plus I see here is the
potential to remove the very large number of string constructors which
are run during startup.
As an aside, an easy hack for small optimizations already is to replace
stuff like
rtl::OUString aFoo(rtl::OUString::createFromAscii("foo"));
and
rtl::OUString aFoo = rtl::OUString::createFromAscii("foo");
with
rtl::OUString aFoo(RTL_CONSTASCII_USTRINGPARAM("foo"));
seeing as the final example is a titchy optimization over the other
examples, Added this as an easy hack to
http://wiki.documentfoundation.org/Development/Easy_Hacks#Use_RTL_CONSTASCII_USTRINGPARAM_macro
C.
#include <stdio.h>
//start copy and paste from sal for illustration purpores
#define SAL_STRING_STATIC_FLAG 0x40000000
typedef struct _rtl_String
{
int refCount; /* opaque */
int length;
char buffer[1];
} rtl_String;
class OString
{
public:
rtl_String * pData;
private:
class DO_NOT_ACQUIRE;
/** @internal */
OString( rtl_String * value, DO_NOT_ACQUIRE * )
{
pData = value;
}
private:
OString();
public:
const char * getStr() const
{
return pData->buffer;
}
};
//end copy and paste from sal for illustration purpores
template <size_t len> struct StaticInit__rtl_String__Tmpl
{
const int refCount; /* opaque */
const int length;
const char buffer[len];
};
template <size_t len> struct StaticInit_OString__Tmpl
{
const StaticInit__rtl_String__Tmpl<len> *pData;
operator const OString&() const { return *reinterpret_cast<const OString*>(this); }
};
#define StaticInit_OString(name, str) \
const StaticInit__rtl_String__Tmpl<sizeof(str)> name##_aImpl = {SAL_STRING_STATIC_FLAG|1,
sizeof(str)-1, { str } }; \
const StaticInit_OString__Tmpl<sizeof(str)> name = {&name##_aImpl}
static StaticInit_OString(rodata_example, "hello world");
StaticInit_OString(data_example, "another");
void other (const OString &thing)
{
fprintf(stderr, "result is %s\n", thing.getStr());
}
int main(void)
{
fprintf(stderr, "c: %s %d\n", rodata_example.pData->buffer, rodata_example.pData->length);
other(rodata_example);
other(data_example);
StaticInit_OString(data_foo, "foo");
other(data_foo);
return 0;
}
#include <stdio.h>
#include <exception>
//start copy and paste from sal for illustration purpores
#define SAL_STRING_STATIC_FLAG 0x40000000
#define RTL_CONSTASCII_USTRINGPARAM( constAsciiStr ) constAsciiStr,
((sal_Int32)(sizeof(constAsciiStr)-1)), RTL_TEXTENCODING_ASCII_US
typedef struct _rtl_uString
{
int refCount; /* opaque */
int length;
unsigned short buffer[1];
} rtl_uString;
class OUString
{
public:
rtl_uString * pData;
private:
class DO_NOT_ACQUIRE;
/** @internal */
OUString( rtl_uString * value, DO_NOT_ACQUIRE * )
{
pData = value;
}
private:
OUString();
public:
const unsigned short * getStr() const
{
return pData->buffer;
}
};
//end copy and paste from sal for illustration purpores
#if defined __GXX_EXPERIMENTAL_CXX0X__
# define SAL_DECLARE_UTF16(str) u ## str
typedef char16_t utf16_type;
#elif (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x550)
# define SAL_DECLARE_UTF16(str) U ## str
typedef unsigned short utf16_type;
#elif __SIZEOF_WCHAR_T__ == 2
# define SAL_DECLARE_UTF16(str) L ## str
typedef wchar_t utf16_type;
#else
typedef unsigned short utf16_type;
#endif
#ifdef SAL_DECLARE_UTF16
template <size_t len> struct StaticInit__rtl_uString__Tmpl
{
const int refCount; /* opaque */
const int length;
const utf16_type buffer[len];
};
template <size_t len> struct StaticInit_OUString__Tmpl
{
const StaticInit__rtl_uString__Tmpl<len> *pData;
operator const OUString&() const { return *reinterpret_cast<const OUString*>(this); }
};
# define StaticInit_OUString(name, str) \
const StaticInit__rtl_uString__Tmpl<sizeof(SAL_DECLARE_UTF16(str))/sizeof(unsigned short)>
name##_aImpl = {SAL_STRING_STATIC_FLAG|1, sizeof(SAL_DECLARE_UTF16(str))/sizeof(unsigned short)-1,
{ SAL_DECLARE_UTF16(str) } }; \
const StaticInit_OUString__Tmpl<sizeof(SAL_DECLARE_UTF16(str))/sizeof(unsigned short)> name =
{&name##_aImpl}
#else
# define StaticInit_OUString(name, str) \
const OUString name(RTL_CONSTASCII_USTRINGPARAM(str));
#endif
static StaticInit_OUString(rodata_example, "hello world");
StaticInit_OUString(data_example, "another");
void other (const OUString &thing)
{
fprintf(stderr, "result is %s\n", thing.getStr());
}
int main(void)
{
fprintf(stderr, "c: %p %d\n", rodata_example.pData->buffer, rodata_example.pData->length);
other(rodata_example);
other(data_example);
StaticInit_OUString(data_foo, "foo");
other(data_foo);
return 0;
}
Context
- [Libreoffice] unicode string literals, "stack" strings etc. · Caolán McNamara
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.