diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2019-09-13 15:13:55 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2019-09-24 12:58:14 +0200 |
commit | 2f5f45921b05904a4be1ff633be09c62cb44ff08 (patch) | |
tree | ddd0cd5ef0349706f935d8360db88343347639a3 /include/rtl/stringconcat.hxx | |
parent | a7d40f575463467698df76f041e558cb3bea7c85 (diff) |
support O(U)String::number() for fast string concatenation
When I did the fast string concatenation, I didn't add any support
for number(), which simply returned a O(U)String, and so it did
the extra allocation/deallocation, although that could be avoided.
In order to support this, number() now returns a special temporary
return type, similarly to O(U)StringConcat, which allows delaying
the concatenation the same way.
Also similarly, the change of the return type in some cases requires
explicit cast to the actual string type. Usage of OString::getStr()
is so extensive in the codebase that I actually added it to the helper
class, after that it's only relatively few cases.
Change-Id: Iba6e158010e1e458089698c426803052b6f46031
Reviewed-on: https://gerrit.libreoffice.org/78873
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'include/rtl/stringconcat.hxx')
-rw-r--r-- | include/rtl/stringconcat.hxx | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/include/rtl/stringconcat.hxx b/include/rtl/stringconcat.hxx index 220d0a2cfc9e..50522636ea3d 100644 --- a/include/rtl/stringconcat.hxx +++ b/include/rtl/stringconcat.hxx @@ -11,6 +11,8 @@ #define INCLUDED_RTL_STRINGCONCAT_HXX #include "rtl/stringutils.hxx" +#include "rtl/string.h" +#include "rtl/ustring.h" #include <cstddef> #include <string.h> @@ -168,6 +170,9 @@ template<> struct ToStringHelper<OUStringLiteral1_> { Objects returned by operator+, instead of OString. These objects (possibly recursively) keep a representation of the whole concatenation operation. + +If you get a build error related to this class, you most probably need to explicitly convert the result of a string +concatenation to OString. */ template< typename T1, typename T2 > struct OStringConcat @@ -189,6 +194,9 @@ struct OStringConcat Objects returned by operator+, instead of OUString. These objects (possibly recursively) keep a representation of the whole concatenation operation. + +If you get a build error related to this class, you most probably need to explicitly convert the result of a string +concatenation to OUString. */ template< typename T1, typename T2 > struct OUStringConcat @@ -302,6 +310,156 @@ int operator+( const StringConcatInvalid&, const T& ) } #endif +/** + @internal + +Objects returned by OString::number(), instead of OString. These objects keep a representation of the number() operation. + +If you get a build error related to this class, you most probably need to explicitly convert the result of calling +OString::number() to OString. +*/ +template< typename T > +struct OStringNumber; + +template<> +struct OStringNumber< int > +{ + OStringNumber( int i, sal_Int16 radix ) + : length( rtl_str_valueOfInt32( buf, i, radix )) + {} + // OString::number(value).getStr() is very common (writing xml code, ...), + // so implement that one also here, to avoid having to explicitly to convert + // to OString in all such places + const char * getStr() const SAL_RETURNS_NONNULL { return buf; } + char buf[RTL_STR_MAX_VALUEOFINT32]; + const sal_Int32 length; +}; + +template<> +struct OStringNumber< long long > +{ + OStringNumber( long long ll, sal_Int16 radix ) + : length( rtl_str_valueOfInt64( buf, ll, radix )) + {} + const char * getStr() const SAL_RETURNS_NONNULL { return buf; } + char buf[RTL_STR_MAX_VALUEOFINT64]; + const sal_Int32 length; +}; + +template<> +struct OStringNumber< unsigned long long > +{ + OStringNumber( unsigned long long ll, sal_Int16 radix ) + : length( rtl_str_valueOfUInt64( buf, ll, radix )) + {} + const char * getStr() const SAL_RETURNS_NONNULL { return buf; } + char buf[RTL_STR_MAX_VALUEOFUINT64]; + const sal_Int32 length; +}; + +template<> +struct OStringNumber< float > +{ + OStringNumber( float f ) + : length( rtl_str_valueOfFloat( buf, f )) + {} + const char * getStr() const SAL_RETURNS_NONNULL { return buf; } + char buf[RTL_STR_MAX_VALUEOFFLOAT]; + const sal_Int32 length; +}; + +template<> +struct OStringNumber< double > +{ + OStringNumber( double d ) + : length( rtl_str_valueOfDouble( buf, d )) + {} + const char * getStr() const SAL_RETURNS_NONNULL { return buf; } + char buf[RTL_STR_MAX_VALUEOFDOUBLE]; + const sal_Int32 length; +}; + +template< typename T > +struct ToStringHelper< OStringNumber< T > > + { + static int length( const OStringNumber< T >& n ) { return n.length; } + static char* addData( char* buffer, const OStringNumber< T >& n ) SAL_RETURNS_NONNULL { return addDataHelper( buffer, n.buf, n.length ); } + static const bool allowOStringConcat = true; + static const bool allowOUStringConcat = false; + }; + + +/** + @internal + +Objects returned by OUString::number(), instead of OUString. These objects keep a representation of the number() operation. + +If you get a build error related to this class, you most probably need to explicitly convert the result of calling +OUString::number() to OUString. +*/ +template< typename T > +struct OUStringNumber; + +template<> +struct OUStringNumber< int > +{ + OUStringNumber( int i, sal_Int16 radix ) + : length( rtl_ustr_valueOfInt32( buf, i, radix )) + {} + sal_Unicode buf[RTL_USTR_MAX_VALUEOFINT32]; + const sal_Int32 length; +}; + +template<> +struct OUStringNumber< long long > +{ + OUStringNumber( long long ll, sal_Int16 radix ) + : length( rtl_ustr_valueOfInt64( buf, ll, radix )) + {} + sal_Unicode buf[RTL_USTR_MAX_VALUEOFINT64]; + const sal_Int32 length; +}; + +template<> +struct OUStringNumber< unsigned long long > +{ + OUStringNumber( unsigned long long ll, sal_Int16 radix ) + : length( rtl_ustr_valueOfUInt64( buf, ll, radix )) + {} + sal_Unicode buf[RTL_USTR_MAX_VALUEOFUINT64]; + const sal_Int32 length; +}; + +template<> +struct OUStringNumber< float > +{ + OUStringNumber( float f ) + : length( rtl_ustr_valueOfFloat( buf, f )) + {} + sal_Unicode buf[RTL_USTR_MAX_VALUEOFFLOAT]; + const sal_Int32 length; +}; + +template<> +struct OUStringNumber< double > +{ + OUStringNumber( double d ) + : length( rtl_ustr_valueOfDouble( buf, d )) + {} + sal_Unicode buf[RTL_USTR_MAX_VALUEOFDOUBLE]; + const sal_Int32 length; +}; + +template< typename T > +struct ToStringHelper< OUStringNumber< T > > + { + static int length( const OUStringNumber< T >& n ) { return n.length; } + static sal_Unicode* addData( sal_Unicode* buffer, const OUStringNumber< T >& n ) SAL_RETURNS_NONNULL { return addDataHelper( buffer, n.buf, n.length ); } + static const bool allowOStringConcat = false; + static const bool allowOUStringConcat = true; + }; + + } // namespace #endif |