[Libreoffice-commits] .: 8 commits - sal/inc sal/Package_inc.mk sal/qa
Lubos Lunak
llunak at kemper.freedesktop.org
Wed Mar 28 14:01:24 PDT 2012
sal/Package_inc.mk | 1
sal/inc/rtl/oustringostreaminserter.hxx | 13
sal/inc/rtl/strbuf.hxx | 70 +++
sal/inc/rtl/string.hxx | 81 ----
sal/inc/rtl/stringutils.hxx | 133 +++++++
sal/inc/rtl/ustrbuf.hxx | 66 ++-
sal/inc/rtl/ustring.hxx | 354 +++++++-------------
sal/qa/rtl/strings/test_ostring_stringliterals.cxx | 32 +
sal/qa/rtl/strings/test_oustring_stringliterals.cxx | 43 +-
9 files changed, 461 insertions(+), 332 deletions(-)
New commits:
commit ef87e804ec80451ff1517482c1b70e7dccb961ce
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 22:58:11 2012 +0200
string literal overloads for OStringBuffer
diff --git a/sal/inc/rtl/strbuf.hxx b/sal/inc/rtl/strbuf.hxx
index 62250f3..54428d3 100644
--- a/sal/inc/rtl/strbuf.hxx
+++ b/sal/inc/rtl/strbuf.hxx
@@ -373,11 +373,31 @@ public:
@param str the characters to be appended.
@return this string buffer.
*/
- OStringBuffer & append( const sal_Char * str )
+ template< typename T >
+ typename internal::CharPtrDetector< T, OStringBuffer& >::Type append( const T& str )
{
return append( str, rtl_str_getLength( str ) );
}
+ template< typename T >
+ typename internal::NonConstCharArrayDetector< T, OStringBuffer& >::Type append( T& str )
+ {
+ return append( str, rtl_str_getLength( str ) );
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OStringBuffer& >::Type append( T& literal )
+ {
+ RTL_STRING_CONST_FUNCTION
+ rtl_stringbuffer_insert( &pData, &nCapacity, getLength(), literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
+ return *this;
+ }
+
/**
Appends the string representation of the <code>char</code> array
argument to this string buffer.
@@ -535,11 +555,31 @@ public:
@param str a character array.
@return this string buffer.
*/
- OStringBuffer & insert( sal_Int32 offset, const sal_Char * str )
+ template< typename T >
+ typename internal::CharPtrDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, const T& str )
{
return insert( offset, str, rtl_str_getLength( str ) );
}
+ template< typename T >
+ typename internal::NonConstCharArrayDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, T& str )
+ {
+ return insert( offset, str, rtl_str_getLength( str ) );
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
+ {
+ RTL_STRING_CONST_FUNCTION
+ rtl_stringbuffer_insert( &pData, &nCapacity, offset, literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
+ return *this;
+ }
+
/**
Inserts the string representation of the <code>char</code> array
argument into this string buffer.
diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
index 462385e..3f2ed84 100644
--- a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
@@ -40,6 +40,7 @@ bool rtl_string_unittest_non_const_literal_function;
#include <cppunit/extensions/HelperMacros.h>
#include "rtl/string.h"
#include "rtl/string.hxx"
+#include "rtl/strbuf.hxx"
namespace rtlunittest {
@@ -61,6 +62,7 @@ private:
void checkCtors();
void checkUsage();
void checkNonConstUsage();
+ void checkBuffer();
void testcall( const char str[] );
@@ -68,6 +70,7 @@ CPPUNIT_TEST_SUITE(StringLiterals);
CPPUNIT_TEST(checkCtors);
CPPUNIT_TEST(checkUsage);
CPPUNIT_TEST(checkNonConstUsage);
+CPPUNIT_TEST(checkBuffer);
CPPUNIT_TEST_SUITE_END();
};
@@ -247,6 +250,34 @@ void test::ostring::StringLiterals::checkNonConstUsage()
// CPPUNIT_ASSERT( foobarfoo.lastIndexOf( (const char*)foo_c ) == 6 );
// CPPUNIT_ASSERT( foobarfoo.lastIndexOf( foo_c ) == 6 );
// if this is not true, some of the calls above used const variants
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal == false );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == false );
+}
+
+void test::ostring::StringLiterals::checkBuffer()
+{
+ rtl::OStringBuffer buf;
+ rtl_string_unittest_const_literal_function = false;
+ buf.append( "foo" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
+ CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OString( "foo" ));
+ rtl_string_unittest_const_literal_function = false;
+ buf.append( "bar" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
+ CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OString( "foobar" ));
+ rtl_string_unittest_const_literal_function = false;
+ buf.insert( 3, "baz" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
+ CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OString( "foobazbar" ));
+
+ rtl::OString foobazbard( "foobazbard" );
+ rtl::OString foodbazbard( "foodbazbard" );
+ rtl_string_unittest_const_literal = false; // start checking for OString conversions
+ rtl_string_unittest_const_literal_function = false; // and check for const variants
+ char d[] = "d";
+ CPPUNIT_ASSERT_EQUAL( buf.append( d ).toString(), foobazbard );
+ CPPUNIT_ASSERT_EQUAL( buf.insert( 3, d ).toString(), foodbazbard );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal == false );
CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == false );
}
commit b741f7fb1ea7b62c9cf2988a64e07cbbb8db904a
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 22:52:37 2012 +0200
make unittest check also for invalid conversions with OUStringBuffer
diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
index ddac4d6..2070698 100644
--- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
@@ -180,6 +180,9 @@ void test::oustring::StringLiterals::checkBuffer()
CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OUString( "foobar" ));
buf.insert( 3, "baz" );
CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OUString( "foobazbar" ));
+ char d[] = "d";
+ CPPUNIT_ASSERT( !VALID_CONVERSION( buf.append( d )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( buf.insert( 0, d )));
}
}} // namespace
commit bd577aa7f8252f3f95276cd17c93beae1902fd96
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 22:31:25 2012 +0200
string literal overload for OUStringBuffer::insert()
diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx
index ee17f77..99afe44 100644
--- a/sal/inc/rtl/ustrbuf.hxx
+++ b/sal/inc/rtl/ustrbuf.hxx
@@ -635,6 +635,19 @@ public:
}
/**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
+ {
+ rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, offset, literal,
+ internal::ConstCharArrayDetector< T, void >::size - 1 );
+ return *this;
+ }
+
+ /**
Inserts the string representation of the <code>sal_Bool</code>
argument into this string buffer.
diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
index 2783571..ddac4d6 100644
--- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
@@ -178,6 +178,8 @@ void test::oustring::StringLiterals::checkBuffer()
CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OUString( "foo" ));
buf.append( "bar" );
CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OUString( "foobar" ));
+ buf.insert( 3, "baz" );
+ CPPUNIT_ASSERT_EQUAL( buf.toString(), rtl::OUString( "foobazbar" ));
}
}} // namespace
commit bf68985627a7e0520674a8eb0d0f037e71f432fe
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 22:27:53 2012 +0200
string literal overload in the right place
diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx
index a89d877..ee17f77 100644
--- a/sal/inc/rtl/ustrbuf.hxx
+++ b/sal/inc/rtl/ustrbuf.hxx
@@ -375,6 +375,19 @@ public:
}
/**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
+ {
+ rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), literal,
+ internal::ConstCharArrayDetector< T, void >::size - 1 );
+ return *this;
+ }
+
+ /**
Appends a 8-Bit ASCII character string to this string buffer.
Since this method is optimized for performance. the ASCII
@@ -420,19 +433,6 @@ public:
}
/**
- @overload
- This function accepts an ASCII string literal as its argument.
- @since LibreOffice 3.6
- */
- template< typename T >
- typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
- {
- rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), literal,
- internal::ConstCharArrayDetector< T, void >::size - 1 );
- return *this;
- }
-
- /**
Appends the string representation of the <code>sal_Bool</code>
argument to the string buffer.
commit 60573363d87bb1335ff8ac0c0623f0ec3e0dc319
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 22:24:48 2012 +0200
clean up string literal overloads in OUStringBuffer
diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx
index 15bbe67..a89d877 100644
--- a/sal/inc/rtl/ustrbuf.hxx
+++ b/sal/inc/rtl/ustrbuf.hxx
@@ -52,10 +52,6 @@ namespace rtl
#ifdef RTL_STRING_UNITTEST
#undef rtl
-// helper macro to make functions appear more readable
-#define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
-#else
-#define RTL_STRING_CONST_FUNCTION
#endif
/** A string buffer implements a mutable sequence of characters.
@@ -428,21 +424,15 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- OUStringBuffer& append( const char (&literal)[ N ] )
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
{
- rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), literal, N - 1 );
+ rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), literal,
+ internal::ConstCharArrayDetector< T, void >::size - 1 );
return *this;
}
/**
- It is an error to call this overload. Strings cannot directly use non-const char[].
- @internal
- */
- template< int N >
- OUStringBuffer& append( char (&literal)[ N ] );
-
- /**
Appends the string representation of the <code>sal_Bool</code>
argument to the string buffer.
@@ -889,7 +879,6 @@ namespace rtl
{
typedef rtlunittest::OUStringBuffer OUStringBuffer;
}
-#undef RTL_STRING_CONST_FUNCTION
#endif
#endif /* _RTL_USTRBUF_HXX_ */
commit 8594c4c52a38f34d1ccb4541dae2e29f08546151
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 22:22:39 2012 +0200
OUString does not have any non-const char functions, no need to check for it
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index a95abd1..ad6fad2 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -60,10 +60,6 @@ namespace rtl
#ifdef RTL_STRING_UNITTEST
#undef rtl
-// helper macro to make functions appear more readable
-#define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
-#else
-#define RTL_STRING_CONST_FUNCTION
#endif
/* ======================================================================= */
@@ -2028,7 +2024,6 @@ namespace rtl
{
typedef rtlunittest::OUString OUString;
}
-#undef RTL_STRING_CONST_FUNCTION
#endif
namespace rtl
commit 8a654fe9a5efc609bcbbfe8864a0748687798930
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 22:21:03 2012 +0200
use SFINAE to remove non-const char[N] OUString overloads
diff --git a/sal/inc/rtl/stringutils.hxx b/sal/inc/rtl/stringutils.hxx
index 866bf23..55326ce 100644
--- a/sal/inc/rtl/stringutils.hxx
+++ b/sal/inc/rtl/stringutils.hxx
@@ -101,7 +101,30 @@ struct ConstCharArrayDetector< const char[ N ], T >
typedef T Type;
static const int size = N;
};
-}
+
+// this one is used to rule out only const char[N]
+template< typename T >
+struct ExceptConstCharArrayDetector
+{
+ typedef Dummy Type;
+};
+template< int N >
+struct ExceptConstCharArrayDetector< const char[ N ] >
+{
+};
+// this one is used to rule out only const char[N]
+// (const will be brought in by 'const T&' in the function call)
+template< typename T >
+struct ExceptCharArrayDetector
+{
+ typedef Dummy Type;
+};
+template< int N >
+struct ExceptCharArrayDetector< char[ N ] >
+{
+};
+
+} /* Namespace */
} /* Namespace */
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index dadef0f..a95abd1 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -199,6 +199,9 @@ public:
@exception std::bad_alloc is thrown if an out-of-memory condition occurs
@since LibreOffice 3.6
*/
+#ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
+ // Old gcc can try to convert anonymous enums to OUString and give compile error.
+ // So instead have a variant for const and non-const char[].
template< int N >
OUString( const char (&literal)[ N ] )
{
@@ -217,15 +220,8 @@ public:
}
/**
- * This overload exists only to avoid creating instances directly from (non-const) char[],
- * which would otherwise be picked up by the optimized const char[] constructor.
- * Since the non-const array cannot be guaranteed to contain characters in the expected
- * ASCII encoding, this needs to be prevented.
- *
- * It is an error to try to call this overload.
- *
+ * It is an error to call this overload. Strings cannot directly use non-const char[].
* @internal
- * @since LibreOffice 3.6
*/
template< int N >
OUString( char (&value)[ N ] )
@@ -236,8 +232,29 @@ public:
(void) value; // unused
pData = 0;
rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10 ); // set to garbage
+ rtl_string_unittest_invalid_conversion = true;
}
#endif
+#else // HAVE_SFINAE_ANONYMOUS_BROKEN
+ template< typename T >
+ OUString( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() )
+ {
+ pData = 0;
+ rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
+ if (pData == 0) {
+#if defined EXCEPTIONS_OFF
+ SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
+#else
+ throw std::bad_alloc();
+#endif
+ }
+#ifdef RTL_STRING_UNITTEST
+ rtl_string_unittest_const_literal = true;
+#endif
+ }
+
+#endif // HAVE_SFINAE_ANONYMOUS_BROKEN
+
#ifdef RTL_STRING_UNITTEST
/**
@@ -245,10 +262,22 @@ public:
* @internal
*/
template< typename T >
- OUString( T )
+ OUString( T&, typename internal::ExceptConstCharArrayDetector< T >::Type = internal::Dummy() )
+ {
+ pData = 0;
+ rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10 ); // set to garbage
+ rtl_string_unittest_invalid_conversion = true;
+ }
+ /**
+ * Only used by unittests to detect incorrect conversions.
+ * @internal
+ */
+ template< typename T >
+ OUString( const T&, typename internal::ExceptCharArrayDetector< T >::Type = internal::Dummy() )
{
pData = 0;
rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10 ); // set to garbage
+ rtl_string_unittest_invalid_conversion = true;
}
#endif
@@ -357,10 +386,10 @@ public:
@exception std::bad_alloc is thrown if an out-of-memory condition occurs
@since LibreOffice 3.6
*/
- template< int N >
- OUString& operator=( const char (&literal)[ N ] )
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal )
{
- rtl_uString_newFromLiteral( &pData, literal, N - 1 );
+ rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
if (pData == 0) {
#if defined EXCEPTIONS_OFF
SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
@@ -372,13 +401,6 @@ public:
}
/**
- * It is an error to call this overload. Strings cannot be directly assigned non-const char[].
- * @internal
- */
- template< int N >
- OUString& operator=( char (&value)[ N ] ); // intentionally not implemented
-
- /**
Append a string to this string.
@param str a OUString.
@@ -542,22 +564,15 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- sal_Bool equalsIgnoreAsciiCase( const char (&literal)[ N ] ) const SAL_THROW(())
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(())
{
- if ( pData->length != N - 1 )
+ if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 )
return sal_False;
return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, literal ) == 0;
}
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- sal_Bool equalsIgnoreAsciiCase( char (&literal)[ N ] ) const SAL_THROW(());
-
/**
Match against a substring appearing in this string.
@@ -584,21 +599,14 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- sal_Bool match( const char (&literal)[ N ], sal_Int32 fromIndex = 0 ) const SAL_THROW(())
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
{
return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
- literal, N - 1 ) == 0;
+ literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- sal_Bool match( char (&literal)[ N ], sal_Int32 fromIndex = 0 ) const SAL_THROW(());
-
- /**
Match against a substring appearing in this string, ignoring the case of
ASCII letters.
@@ -628,21 +636,14 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- sal_Bool matchIgnoreAsciiCase( const char (&literal)[ N ], sal_Int32 fromIndex = 0 ) const SAL_THROW(())
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
{
return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
- literal, N - 1 ) == 0;
+ literal, internal::ConstCharArrayDetector< T, void >::size - 1 ) == 0;
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- sal_Bool matchIgnoreAsciiCase( char (&literal)[ N ], sal_Int32 fromIndex = 0 ) const SAL_THROW(());
-
- /**
Compares two strings.
The comparison is based on the numeric value of each character in
@@ -926,23 +927,16 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- bool endsWith( const char (&literal)[ N ] ) const
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const
{
- return N - 1 <= pData->length
+ return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
&& rtl_ustr_asciil_reverseEquals_WithLength(
- pData->buffer + pData->length - ( N - 1 ), literal,
- N - 1);
+ pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ), literal,
+ internal::ConstCharArrayDetector< T, void >::size - 1);
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- bool endsWith( char (&literal)[ N ] ) const;
-
- /**
Check whether this string ends with a given ASCII string.
@param asciiStr a sequence of at least asciiStrLength ASCII characters
@@ -986,23 +980,18 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- sal_Bool endsWithIgnoreAsciiCase( const char (&literal)[ N ] ) const SAL_THROW(())
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, bool >::Type endsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(())
{
- return N - 1 <= pData->length
+ return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
&& (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
- pData->buffer + pData->length - ( N - 1 ),
- N - 1, literal, N - 1)
+ pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ),
+ internal::ConstCharArrayDetector< T, void >::size - 1, literal,
+ internal::ConstCharArrayDetector< T, void >::size - 1)
== 0);
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- sal_Bool endsWithIgnoreAsciiCase( char (&literal)[ N ] ) const SAL_THROW(());
- /**
Check whether this string ends with a given ASCII string, ignoring the
case of ASCII letters.
@@ -1052,10 +1041,10 @@ public:
*
* @since LibreOffice 3.6
*/
- template< int N >
- friend inline bool operator==( const OUString& string, const char (&literal)[ N ] )
+ template< typename T >
+ friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& string, T& literal )
{
- return string.equalsAsciiL( literal, N - 1 );
+ return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
}
/**
* Compare string to an ASCII string literal.
@@ -1064,10 +1053,10 @@ public:
*
* @since LibreOffice 3.6
*/
- template< int N >
- friend inline bool operator==( const char (&literal)[ N ], const OUString& string )
+ template< typename T >
+ friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& string )
{
- return string.equalsAsciiL( literal, N - 1 );
+ return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
}
/**
* Compare string to an ASCII string literal.
@@ -1076,10 +1065,10 @@ public:
*
* @since LibreOffice 3.6
*/
- template< int N >
- friend inline bool operator!=( const OUString& string, const char (&literal)[ N ] )
+ template< typename T >
+ friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& string, T& literal )
{
- return !string.equalsAsciiL( literal, N - 1 );
+ return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
}
/**
* Compare string to an ASCII string literal.
@@ -1088,35 +1077,11 @@ public:
*
* @since LibreOffice 3.6
*/
- template< int N >
- friend inline bool operator!=( const char (&literal)[ N ], const OUString& string )
+ template< typename T >
+ friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& string )
{
- return !string.equalsAsciiL( literal, N - 1 );
+ return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
}
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- friend inline bool operator==( const OUString& string, char (&literal)[ N ] ); // not implemented
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- friend inline bool operator==( char (&literal)[ N ], const OUString& string ); // not implemented
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- friend inline bool operator!=( const OUString& string, char (&literal)[ N ] ); // not implemented
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- friend inline bool operator!=( char (&literal)[ N ], const OUString& string ); // not implemented
/**
Returns a hashcode for this string.
@@ -1207,22 +1172,16 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- sal_Int32 indexOf( const char (&literal)[ N ], sal_Int32 fromIndex = 0 ) const SAL_THROW(())
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
{
sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
- pData->buffer + fromIndex, pData->length - fromIndex, literal, N - 1);
+ pData->buffer + fromIndex, pData->length - fromIndex, literal,
+ internal::ConstCharArrayDetector< T, void >::size - 1);
return ret < 0 ? ret : ret + fromIndex;
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- sal_Int32 indexOf( char (&literal)[ N ], sal_Int32 fromIndex = 0 ) const SAL_THROW(());
-
- /**
Returns the index within this string of the first occurrence of the
specified ASCII substring, starting at the specified index.
@@ -1311,21 +1270,14 @@ public:
This function accepts an ASCII string literal as its argument.
@since LibreOffice 3.6
*/
- template< int N >
- sal_Int32 lastIndexOf( const char (&literal)[ N ] ) const SAL_THROW(())
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(())
{
return rtl_ustr_lastIndexOfAscii_WithLength(
- pData->buffer, pData->length, literal, N - 1);
+ pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- sal_Int32 lastIndexOf( char (&literal)[ N ] ) const SAL_THROW(());
-
- /**
Returns the index within this string of the last occurrence of the
specified ASCII substring.
@@ -1503,26 +1455,18 @@ public:
@since LibreOffice 3.6
*/
- template< int N >
- OUString replaceFirst( const char (&from)[ N ], OUString const & to,
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( T& from, OUString const & to,
sal_Int32 * index = 0) const
{
rtl_uString * s = 0;
sal_Int32 i = 0;
rtl_uString_newReplaceFirstAsciiL(
- &s, pData, from, N - 1, to.pData, index == 0 ? &i : index);
+ &s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData, index == 0 ? &i : index);
return OUString(s, SAL_NO_ACQUIRE);
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- OUString replaceFirst( char (&literal)[ N ], OUString const & to,
- sal_Int32 * index = 0) const;
-
- /**
Returns a new string resulting from replacing the first occurrence of a
given substring with another substring.
@@ -1540,40 +1484,19 @@ public:
@since LibreOffice 3.6
*/
- template< int N1, int N2 >
- OUString replaceFirst( const char (&from)[ N1 ], const char (&to)[ N2 ],
- sal_Int32 * index = 0) const
+ template< typename T1, typename T2 >
+ typename internal::ConstCharArrayDetector< T1, typename internal::ConstCharArrayDetector< T2, OUString >::Type >::Type
+ replaceFirst( T1& from, T2& to, sal_Int32 * index = 0) const
{
rtl_uString * s = 0;
sal_Int32 i = 0;
rtl_uString_newReplaceFirstAsciiLAsciiL(
- &s, pData, from, N1 - 1, to, N2 - 1, index == 0 ? &i : index);
+ &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1, to,
+ internal::ConstCharArrayDetector< T2, void >::size - 1, index == 0 ? &i : index);
return OUString(s, SAL_NO_ACQUIRE);
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N1, int N2 >
- OUString replaceFirst( char (&from)[ N1 ], char (&to)[ N2 ],
- sal_Int32 * index = 0) const;
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N1, int N2 >
- OUString replaceFirst( const char (&from)[ N1 ], char (&to)[ N2 ],
- sal_Int32 * index = 0) const;
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N1, int N2 >
- OUString replaceFirst( char (&from)[ N1 ], const char (&to)[ N2 ],
- sal_Int32 * index = 0) const;
-
- /**
Returns a new string resulting from replacing all occurrences of a given
substring with another substring.
@@ -1605,22 +1528,15 @@ public:
@since LibreOffice 3.6
*/
- template< int N >
- OUString replaceAll( const char (&from)[ N ], OUString const & to) const
+ template< typename T >
+ typename internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const
{
rtl_uString * s = 0;
- rtl_uString_newReplaceAllAsciiL(&s, pData, from, N - 1, to.pData);
+ rtl_uString_newReplaceAllAsciiL(&s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData);
return OUString(s, SAL_NO_ACQUIRE);
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N >
- OUString replaceAll( char (&literal)[ N ], OUString const & to) const;
-
- /**
Returns a new string resulting from replacing all occurrences of a given
substring with another substring.
@@ -1633,65 +1549,18 @@ public:
@since LibreOffice 3.6
*/
- template< int N1, int N2 >
- OUString replaceAll( const char (&from)[ N1 ], const char (&to)[ N2 ] ) const
+ template< typename T1, typename T2 >
+ typename internal::ConstCharArrayDetector< T1, typename internal::ConstCharArrayDetector< T2, OUString >::Type >::Type
+ replaceAll( T1& from, T2& to ) const
{
rtl_uString * s = 0;
rtl_uString_newReplaceAllAsciiLAsciiL(
- &s, pData, from, N1 - 1, to, N2 - 1);
+ &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1,
+ to, internal::ConstCharArrayDetector< T2, void >::size - 1);
return OUString(s, SAL_NO_ACQUIRE);
}
/**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N1, int N2 >
- OUString replaceAll( char (&from)[ N1 ], char (&to)[ N2 ] ) const
-#ifndef RTL_STRING_UNITTEST
- ; // intentionally not implemented
-#else
- {
- (void) from; // unused
- (void) to; // unused
- rtl_uString_newFromLiteral( &const_cast<OUString*>(this)->pData, "!!br0ken!!", 10 ); // set to garbage
- return *this;
- }
-#endif
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N1, int N2 >
- OUString replaceAll( char (&from)[ N1 ], const char (&to)[ N2 ] ) const
-#ifndef RTL_STRING_UNITTEST
- ; // intentionally not implemented
-#else
- {
- (void) from; // unused
- (void) to; // unused
- rtl_uString_newFromLiteral( &const_cast<OUString*>(this)->pData, "!!br0ken!!", 10 ); // set to garbage
- return *this;
- }
-#endif
- /**
- * It is an error to call this overload. Strings cannot directly use non-const char[].
- * @internal
- */
- template< int N1, int N2 >
- OUString replaceAll( const char (&from)[ N1 ], char (&to)[ N2 ] ) const
-#ifndef RTL_STRING_UNITTEST
- ; // intentionally not implemented
-#else
- {
- (void) from; // unused
- (void) to; // unused
- rtl_uString_newFromLiteral( &const_cast<OUString*>(this)->pData, "!!br0ken!!", 10 ); // set to garbage
- return *this;
- }
-#endif
-
- /**
Converts from this string all ASCII uppercase characters (65-90)
to ASCII lowercase characters (97-122).
diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
index 930b038..462385e 100644
--- a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
@@ -29,6 +29,7 @@
// activate the extra needed ctor
#define RTL_STRING_UNITTEST
bool rtl_string_unittest_const_literal;
+bool rtl_string_unittest_invalid_conversion;
bool rtl_string_unittest_const_literal_function;
bool rtl_string_unittest_non_const_literal_function;
diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
index fb0e21e..2783571 100644
--- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
@@ -29,6 +29,7 @@
// activate the extra needed ctor
#define RTL_STRING_UNITTEST
extern bool rtl_string_unittest_const_literal;
+extern bool rtl_string_unittest_invalid_conversion;
extern bool rtl_string_unittest_const_literal_function;
extern bool rtl_string_unittest_non_const_literal_function;
@@ -54,9 +55,6 @@ private:
void checkBuffer();
void testcall( const char str[] );
- // invalid conversions will trigger templated OUString ctor that creates an empty string
- // (see RTL_STRING_UNITTEST)
- bool validConversion( const rtl::OUString& str ) { return str != "!!br0ken!!"; }
CPPUNIT_TEST_SUITE(StringLiterals);
CPPUNIT_TEST(checkCtors);
@@ -67,29 +65,37 @@ CPPUNIT_TEST(checkBuffer);
CPPUNIT_TEST_SUITE_END();
};
+// reset the flag, evaluate the expression and return
+// whether the string literal ctor was used (i.e. whether the conversion was valid)
+#define VALID_CONVERSION( expression ) \
+ ( \
+ rtl_string_unittest_invalid_conversion = false, \
+ ( void ) ( expression ), \
+ !rtl_string_unittest_invalid_conversion )
+
void test::oustring::StringLiterals::checkCtors()
{
- CPPUNIT_ASSERT( validConversion( rtl::OUString( "test" )));
+ CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( "test" )));
const char good1[] = "test";
- CPPUNIT_ASSERT( validConversion( rtl::OUString( good1 )));
+ CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( good1 )));
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( (const char*) "test" )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( (const char*) "test" )));
const char* bad1 = good1;
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( bad1 )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad1 )));
char bad2[] = "test";
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( bad2 )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad2 )));
char* bad3 = bad2;
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( bad3 )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad3 )));
const char* bad4[] = { "test1" };
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( bad4[ 0 ] )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( bad4[ 0 ] )));
testcall( good1 );
// This one is technically broken, since the first element is 6 characters test\0\0,
// but there does not appear a way to detect this by compile time (runtime will complain).
// RTL_CONSTASCII_USTRINGPARAM() has the same flaw.
const char bad5[][ 6 ] = { "test", "test2" };
-// CPPUNIT_ASSERT( validConversion( rtl::OUString( bad5[ 0 ] )));
- CPPUNIT_ASSERT( validConversion( rtl::OUString( bad5[ 1 ] )));
+// CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( bad5[ 0 ] )));
+ CPPUNIT_ASSERT( VALID_CONVERSION( rtl::OUString( bad5[ 1 ] )));
// Check that contents are correct and equal to the case when RTL_CONSTASCII_USTRINGPARAM is used.
// Also check that embedded \0 is included.
@@ -101,7 +107,7 @@ void test::oustring::StringLiterals::checkCtors()
void test::oustring::StringLiterals::testcall( const char str[] )
{
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( str )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( str )));
}
void test::oustring::StringLiterals::checkUsage()
@@ -159,9 +165,9 @@ void test::oustring::StringLiterals::checkNonconstChar()
char bar[] = "bar";
const char consttest[] = "test";
const char constbar[] = "bar";
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( "footest" ).replaceAll( test, bar )));
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( "footest" ).replaceAll( consttest, bar )));
- CPPUNIT_ASSERT( !validConversion( rtl::OUString( "footest" ).replaceAll( test, constbar )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( "footest" ).replaceAll( test, bar )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( "footest" ).replaceAll( consttest, bar )));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( "footest" ).replaceAll( test, constbar )));
CPPUNIT_ASSERT( rtl::OUString( "foobar" ) == rtl::OUString( "footest" ).replaceAll( consttest, constbar ));
}
commit 81e7364f52b6135776d4999be287524d508a7d08
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Mar 28 21:33:11 2012 +0200
move string helper types to stringutils.hxx
diff --git a/sal/Package_inc.mk b/sal/Package_inc.mk
index 3ac23bc..5350faf 100644
--- a/sal/Package_inc.mk
+++ b/sal/Package_inc.mk
@@ -92,6 +92,7 @@ $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/strbuf.h,rtl/strbuf.h))
$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/strbuf.hxx,rtl/strbuf.hxx))
$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/string.h,rtl/string.h))
$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/string.hxx,rtl/string.hxx))
+$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/stringutils.hxx,rtl/stringutils.hxx))
$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/tencinfo.h,rtl/tencinfo.h))
$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/textcvt.h,rtl/textcvt.h))
$(eval $(call gb_Package_add_file,sal_inc,inc/rtl/textenc.h,rtl/textenc.h))
diff --git a/sal/inc/rtl/oustringostreaminserter.hxx b/sal/inc/rtl/oustringostreaminserter.hxx
index 579ffa0..632bc23 100644
--- a/sal/inc/rtl/oustringostreaminserter.hxx
+++ b/sal/inc/rtl/oustringostreaminserter.hxx
@@ -42,8 +42,21 @@
@since LibreOffice 3.5.
*/
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
namespace rtl {
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+#endif
+
template< typename charT, typename traits > std::basic_ostream<charT, traits> &
operator <<(
std::basic_ostream<charT, traits> & stream, rtl::OUString const & string)
diff --git a/sal/inc/rtl/strbuf.hxx b/sal/inc/rtl/strbuf.hxx
index a92ea1d..62250f3 100644
--- a/sal/inc/rtl/strbuf.hxx
+++ b/sal/inc/rtl/strbuf.hxx
@@ -35,12 +35,30 @@
#include <rtl/strbuf.h>
#include <rtl/string.hxx>
+#include <rtl/stringutils.hxx>
#ifdef __cplusplus
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
namespace rtl
{
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+// helper macro to make functions appear more readable
+#define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
+#else
+#define RTL_STRING_CONST_FUNCTION
+#endif
+
/** A string buffer implements a mutable sequence of characters.
<p>
String buffers are safe for use by multiple threads. The methods
@@ -715,6 +733,14 @@ private:
}
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OStringBuffer OStringBuffer;
+}
+#undef RTL_STRING_CONST_FUNCTION
+#endif
+
#endif /* __cplusplus */
#endif /* _RTL_STRBUF_HXX_ */
diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx
index 68f41bd..72af04e 100644
--- a/sal/inc/rtl/string.hxx
+++ b/sal/inc/rtl/string.hxx
@@ -37,6 +37,8 @@
#include <rtl/memory.h>
#include <rtl/textenc.h>
#include <rtl/string.h>
+#include <rtl/stringutils.hxx>
+
#include "sal/log.hxx"
#if !defined EXCEPTIONS_OFF
@@ -89,65 +91,6 @@ namespace rtl
use this class.
*/
-namespace internal
-{
-/*
-These templates use SFINAE (Substitution failure is not an error) to help distinguish the various
-plain C string types: char*, const char*, char[N] and const char[N]. There are 2 cases:
-1) Only string literal (i.e. const char[N]) is wanted, not any of the others.
- In this case it is necessary to distinguish between const char[N] and char[N], as the latter
- would be automatically converted to the const variant, which is not wanted (not a string literal
- with known size of the content). In this case ConstCharArrayDetector is used to ensure the function
- is called only with const char[N] arguments. There's no other plain C string type overload.
-2) All plain C string types are wanted, and const char[N] needs to be handled differently.
- In this case const char[N] would match const char* argument type (not exactly sure why, but it's
- consistent in all of gcc, clang and msvc). Using a template with a reference to const of the type
- avoids this problem, and CharPtrDetector ensures that the function is called only with char pointer
- arguments. The const in the argument is necessary to handle the case when something is explicitly
- cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference
- being const, it would also match const char[N], so another overload with a reference to non-const
- and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N].
-*/
-struct Dummy {};
-template< typename T1, typename T2 >
-struct CharPtrDetector
-{
-};
-template< typename T >
-struct CharPtrDetector< const char*, T >
-{
- typedef T Type;
-};
-template< typename T >
-struct CharPtrDetector< char*, T >
-{
- typedef T Type;
-};
-
-template< typename T1, typename T2 >
-struct NonConstCharArrayDetector
-{
-};
-template< typename T, int N >
-struct NonConstCharArrayDetector< char[ N ], T >
-{
- typedef T Type;
-};
-// This is similar, only it helps to detect const char[]. Without using a template,
-// (non-const) char[] would be automatically converted to const char[], which is unwanted
-// here (size of the content is not known).
-template< typename T1, typename T2 >
-struct ConstCharArrayDetector
-{
-};
-template< int N, typename T >
-struct ConstCharArrayDetector< const char[ N ], T >
-{
- typedef T Type;
- static const int size = N;
-};
-}
-
class OString
{
public:
@@ -1486,6 +1429,19 @@ public:
/* ======================================================================= */
+} /* Namespace */
+
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OString OString;
+}
+#undef RTL_STRING_CONST_FUNCTION
+#endif
+
+namespace rtl
+{
+
/** A helper to use OStrings with hash maps.
Instances of this class are unary function objects that can be used as
@@ -1510,13 +1466,6 @@ struct OStringHash
} /* Namespace */
-#ifdef RTL_STRING_UNITTEST
-namespace rtl
-{
-typedef rtlunittest::OString OString;
-}
-#endif
-
#endif /* _RTL_STRING_HXX_ */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/inc/rtl/stringutils.hxx b/sal/inc/rtl/stringutils.hxx
new file mode 100644
index 0000000..866bf23
--- /dev/null
+++ b/sal/inc/rtl/stringutils.hxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * [ Copyright (C) 2012 Lubos Lunak <l.lunak at suse.cz> (initial developer) ]
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef _RTL_STRINGUTILS_HXX_
+#define _RTL_STRINGUTILS_HXX_
+
+#include "sal/config.h"
+
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
+namespace rtl
+{
+
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+#endif
+namespace internal
+{
+/*
+These templates use SFINAE (Substitution failure is not an error) to help distinguish the various
+plain C string types: char*, const char*, char[N] and const char[N]. There are 2 cases:
+1) Only string literal (i.e. const char[N]) is wanted, not any of the others.
+ In this case it is necessary to distinguish between const char[N] and char[N], as the latter
+ would be automatically converted to the const variant, which is not wanted (not a string literal
+ with known size of the content). In this case ConstCharArrayDetector is used to ensure the function
+ is called only with const char[N] arguments. There's no other plain C string type overload.
+2) All plain C string types are wanted, and const char[N] needs to be handled differently.
+ In this case const char[N] would match const char* argument type (not exactly sure why, but it's
+ consistent in all of gcc, clang and msvc). Using a template with a reference to const of the type
+ avoids this problem, and CharPtrDetector ensures that the function is called only with char pointer
+ arguments. The const in the argument is necessary to handle the case when something is explicitly
+ cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference
+ being const, it would also match const char[N], so another overload with a reference to non-const
+ and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N].
+*/
+struct Dummy {};
+template< typename T1, typename T2 >
+struct CharPtrDetector
+{
+};
+template< typename T >
+struct CharPtrDetector< const char*, T >
+{
+ typedef T Type;
+};
+template< typename T >
+struct CharPtrDetector< char*, T >
+{
+ typedef T Type;
+};
+
+template< typename T1, typename T2 >
+struct NonConstCharArrayDetector
+{
+};
+template< typename T, int N >
+struct NonConstCharArrayDetector< char[ N ], T >
+{
+ typedef T Type;
+};
+
+template< typename T1, typename T2 >
+struct ConstCharArrayDetector
+{
+};
+template< int N, typename T >
+struct ConstCharArrayDetector< const char[ N ], T >
+{
+ typedef T Type;
+ static const int size = N;
+};
+}
+
+} /* Namespace */
+
+#endif /* _RTL_STRINGUTILS_HXX_ */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/inc/rtl/ustrbuf.hxx b/sal/inc/rtl/ustrbuf.hxx
index adb1761..15bbe67 100644
--- a/sal/inc/rtl/ustrbuf.hxx
+++ b/sal/inc/rtl/ustrbuf.hxx
@@ -36,10 +36,28 @@
#include <osl/diagnose.h>
#include <rtl/ustrbuf.h>
#include <rtl/ustring.hxx>
+#include <rtl/stringutils.hxx>
+
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
namespace rtl
{
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+// helper macro to make functions appear more readable
+#define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
+#else
+#define RTL_STRING_CONST_FUNCTION
+#endif
+
/** A string buffer implements a mutable sequence of characters.
<p>
String buffers are safe for use by multiple threads. The methods
@@ -866,6 +884,14 @@ private:
}
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OUStringBuffer OUStringBuffer;
+}
+#undef RTL_STRING_CONST_FUNCTION
+#endif
+
#endif /* _RTL_USTRBUF_HXX_ */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index ef47be6..dadef0f 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -36,6 +36,7 @@
#include "osl/diagnose.h"
#include <rtl/ustring.h>
#include <rtl/string.hxx>
+#include <rtl/stringutils.hxx>
#include <rtl/memory.h>
#include "sal/log.hxx"
@@ -45,8 +46,26 @@
#include <new>
#endif
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
namespace rtl
{
+
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+// helper macro to make functions appear more readable
+#define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
+#else
+#define RTL_STRING_CONST_FUNCTION
+#endif
+
/* ======================================================================= */
/**
@@ -897,7 +916,7 @@ public:
@since LibreOffice 3.6
*/
- bool endsWith(rtl::OUString const & str) const {
+ bool endsWith(OUString const & str) const {
return str.getLength() <= getLength()
&& match(str, getLength() - str.getLength());
}
@@ -1485,7 +1504,7 @@ public:
@since LibreOffice 3.6
*/
template< int N >
- OUString replaceFirst( const char (&from)[ N ], rtl::OUString const & to,
+ OUString replaceFirst( const char (&from)[ N ], OUString const & to,
sal_Int32 * index = 0) const
{
rtl_uString * s = 0;
@@ -1500,7 +1519,7 @@ public:
* @internal
*/
template< int N >
- OUString replaceFirst( char (&literal)[ N ], rtl::OUString const & to,
+ OUString replaceFirst( char (&literal)[ N ], OUString const & to,
sal_Int32 * index = 0) const;
/**
@@ -2133,6 +2152,19 @@ public:
/* ======================================================================= */
+} /* Namespace */
+
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OUString OUString;
+}
+#undef RTL_STRING_CONST_FUNCTION
+#endif
+
+namespace rtl
+{
+
/** A helper to use OUStrings with hash maps.
Instances of this class are unary function objects that can be used as
@@ -2149,7 +2181,7 @@ struct OUStringHash
a hash code for the string. This hash code should not be stored
persistently, as its computation may change in later revisions.
*/
- size_t operator()(const rtl::OUString& rString) const
+ size_t operator()(const OUString& rString) const
{ return (size_t)rString.hashCode(); }
};
More information about the Libreoffice-commits
mailing list