Bug 1393230 - Part 3: Convert the xpcom string classes to be templated on char type. r=njn, r=fitzgen, r=sfink

This removes the double-include macro hackery that we use to define two
separate string types (nsAString and nsACString) in favor of a templated
solution.

Annotations for Valgrind and the JS hazard analysis are updated as well as
the rust binding generations for string code.

--HG--
extra : rebase_source : 63ab2c4620cfcd4b764d42d654c82f30f984d016
extra : source : 9115364cd4aa078c49bba7911069f8178e55166f
This commit is contained in:
Eric Rahm 2017-08-14 14:22:50 -07:00
Родитель 0617c21c24
Коммит 030b39d813
42 изменённых файлов: 1915 добавлений и 1474 удалений

Просмотреть файл

@ -15,7 +15,7 @@
PR_SetEnv requires its argument to be leaked, but does not appear on stacks. (See bug 793549.)
Memcheck:Leak
...
fun:_ZL13SaveWordToEnvPKcRK10nsACString
fun:_ZL13SaveWordToEnvPKcRK12nsTSubstringIcE
...
}
{

Просмотреть файл

@ -445,17 +445,17 @@ function ignoreContents(entry)
/nsTArray_base.*?::EnsureCapacity/,
/nsTArray_base.*?::ShiftData/,
/AutoTArray.*?::Init/,
/nsAC?String::SetCapacity/,
/nsAC?String::SetLength/,
/nsAC?String::Assign/,
/nsAC?String::Append/,
/nsAC?String::Replace/,
/nsAC?String::Trim/,
/nsAC?String::Truncate/,
/nsAString::StripTaggedASCII/,
/nsAC?String::operator=/,
/nsAutoString::nsAutoString/,
/nsFixedCString::nsFixedCString/,
/nsTSubstring<T>::SetCapacity/,
/nsTSubstring<T>::SetLength/,
/nsTSubstring<T>::Assign/,
/nsTSubstring<T>::Append/,
/nsTSubstring<T>::Replace/,
/nsTSubstring<T>::Trim/,
/nsTSubstring<T>::Truncate/,
/nsTSubstring<T>::StripTaggedASCII/,
/nsTSubstring<T>::operator=/,
/nsTAutoStringN<T, N>::nsTAutoStringN/,
/nsTFixedString<T>::nsTFixedString/,
// Similar for some other data structures
/nsCOMArray_base::SetCapacity/,

Просмотреть файл

@ -343,7 +343,8 @@ mapped-generic-types = [
{ generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>" },
]
fixups = [
{ pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
{ pat = "\\broot::nsString\\b", rep = "::nsstring::nsStringRepr" },
{ pat = "\\broot::nsTString<u16>", rep = "::nsstring::nsStringRepr" },
]
[bindings]
@ -541,6 +542,8 @@ servo-borrow-types = [
"RawGeckoStyleChildrenIterator",
]
fixups = [
# Remap the templated string type to the helper type
{ pat = "\\bnsTString<u16>", rep = "nsString" },
# hack for gecko-owned string
{ pat = "<nsString", rep = "<nsStringRepr" },
{ pat = "\\b<nsString\\b", rep = "<nsStringRepr" },
]

Просмотреть файл

@ -19,6 +19,7 @@ EXPORTS += [
'nsReadableUtils.h',
'nsString.h',
'nsStringBuffer.h',
'nsStringFlags.h',
'nsStringFwd.h',
'nsStringIterator.h',
'nsSubstring.h',
@ -29,12 +30,10 @@ EXPORTS += [
'nsTLiteralString.h',
'nsTPromiseFlatString.h',
'nsTString.h',
'nsTStringRepr.h',
'nsTSubstring.h',
'nsTSubstringTuple.h',
'nsUTF8Utils.h',
'string-template-def-char.h',
'string-template-def-unichar.h',
'string-template-undef.h',
]
UNIFIED_SOURCES += [
@ -49,6 +48,7 @@ UNIFIED_SOURCES += [
'nsSubstring.cpp',
'nsSubstringTuple.cpp',
'nsTextFormatter.cpp',
'precompiled_templates.cpp',
]
# Are we targeting x86 or x86-64? If so, compile the SSE2 functions for

Просмотреть файл

@ -17,79 +17,9 @@
#define kNotFound -1
namespace mozilla {
namespace detail {
// NOTE: these flags are declared public _only_ for convenience inside
// the string implementation. And they are outside of the string
// class so that the type is the same for both narrow and wide
// strings.
// bits for mDataFlags
enum class StringDataFlags : uint16_t
{
// Some terminology:
//
// "dependent buffer" A dependent buffer is one that the string class
// does not own. The string class relies on some
// external code to ensure the lifetime of the
// dependent buffer.
//
// "shared buffer" A shared buffer is one that the string class
// allocates. When it allocates a shared string
// buffer, it allocates some additional space at
// the beginning of the buffer for additional
// fields, including a reference count and a
// buffer length. See nsStringHeader.
//
// "adopted buffer" An adopted buffer is a raw string buffer
// allocated on the heap (using moz_xmalloc)
// of which the string class subsumes ownership.
//
// Some comments about the string data flags:
//
// SHARED, OWNED, and FIXED are all mutually exlusive. They
// indicate the allocation type of mData. If none of these flags
// are set, then the string buffer is dependent.
//
// SHARED, OWNED, or FIXED imply TERMINATED. This is because
// the string classes always allocate null-terminated buffers, and
// non-terminated substrings are always dependent.
//
// VOIDED implies TERMINATED, and moreover it implies that mData
// points to char_traits::sEmptyBuffer. Therefore, VOIDED is
// mutually exclusive with SHARED, OWNED, and FIXED.
TERMINATED = 1 << 0, // IsTerminated returns true
VOIDED = 1 << 1, // IsVoid returns true
SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
LITERAL = 1 << 5 // mData points to a string literal; DataFlags::TERMINATED will also be set
};
// bits for mClassFlags
enum class StringClassFlags : uint16_t
{
FIXED = 1 << 0, // |this| is of type nsTFixedString
NULL_TERMINATED = 1 << 1 // |this| requires its buffer is null-terminated
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringDataFlags)
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringClassFlags)
} // namespace detail
} // namespace mozilla
// declare nsAString
#include "string-template-def-unichar.h"
#include "nsStringFlags.h"
#include "nsTStringRepr.h"
#include "nsTSubstring.h"
#include "string-template-undef.h"
// declare nsACString
#include "string-template-def-char.h"
#include "nsTSubstring.h"
#include "string-template-undef.h"
/**
* ASCII case-insensitive comparator. (for Unicode case-insensitive

Просмотреть файл

@ -7,12 +7,4 @@
#include "nsDependentString.h"
#include "nsAlgorithm.h"
// define nsDependentString
#include "string-template-def-unichar.h"
#include "nsTDependentString.cpp"
#include "string-template-undef.h"
// define nsDependentCString
#include "string-template-def-char.h"
#include "nsTDependentString.cpp"
#include "string-template-undef.h"

Просмотреть файл

@ -10,14 +10,7 @@
#include "nsString.h"
#include "nsDebug.h"
// declare nsDependentString
#include "string-template-def-unichar.h"
#include "nsTDependentString.h"
#include "string-template-undef.h"
// declare nsDependentCString
#include "string-template-def-char.h"
#include "nsTDependentString.h"
#include "string-template-undef.h"
#endif /* !defined(nsDependentString_h___) */

Просмотреть файл

@ -7,12 +7,4 @@
#include "nsDependentSubstring.h"
#include "nsAlgorithm.h"
// define nsDependentSubstring
#include "string-template-def-unichar.h"
#include "nsTDependentSubstring.cpp"
#include "string-template-undef.h"
// define nsDependentCSubstring
#include "string-template-def-char.h"
#include "nsTDependentSubstring.cpp"
#include "string-template-undef.h"

Просмотреть файл

@ -8,15 +8,6 @@
#define nsDependentSubstring_h___
#include "nsSubstring.h"
// declare nsDependentSubstring
#include "string-template-def-unichar.h"
#include "nsTDependentSubstring.h"
#include "string-template-undef.h"
// declare nsDependentCSubstring
#include "string-template-def-char.h"
#include "nsTDependentSubstring.h"
#include "string-template-undef.h"
#endif /* !defined(nsDependentSubstring_h___) */

Просмотреть файл

@ -10,15 +10,7 @@
#include "nscore.h"
#include "nsString.h"
// declare nsLiteralString
#include "string-template-def-unichar.h"
#include "nsTLiteralString.h"
#include "string-template-undef.h"
// declare nsLiteralCString
#include "string-template-def-char.h"
#include "nsTLiteralString.h"
#include "string-template-undef.h"
#include "mozilla/Char16.h"

Просмотреть файл

@ -6,12 +6,4 @@
#include "nsPromiseFlatString.h"
// define nsPromiseFlatString
#include "string-template-def-unichar.h"
#include "nsTPromiseFlatString.cpp"
#include "string-template-undef.h"
// define nsPromiseFlatCString
#include "string-template-def-char.h"
#include "nsTPromiseFlatString.cpp"
#include "string-template-undef.h"

Просмотреть файл

@ -9,14 +9,6 @@
#include "nsString.h"
// declare nsPromiseFlatString
#include "string-template-def-unichar.h"
#include "nsTPromiseFlatString.h"
#include "string-template-undef.h"
// declare nsPromiseFlatCString
#include "string-template-def-char.h"
#include "nsTPromiseFlatString.h"
#include "string-template-undef.h"
#endif /* !defined(nsPromiseFlatString_h___) */

Просмотреть файл

@ -6,12 +6,4 @@
#include "nsString.h"
// define nsString
#include "string-template-def-unichar.h"
#include "nsTString.cpp"
#include "string-template-undef.h"
// define nsCString
#include "string-template-def-char.h"
#include "nsTString.cpp"
#include "string-template-undef.h"

Просмотреть файл

@ -9,6 +9,8 @@
#include "mozilla/Attributes.h"
#include "nsStringFwd.h"
#include "nsSubstring.h"
#include "nsDependentSubstring.h"
#include "nsReadableUtils.h"
@ -27,16 +29,7 @@
#define kAutoDetect (100)
#endif
// declare nsString, et. al.
#include "string-template-def-unichar.h"
#include "nsTString.h"
#include "string-template-undef.h"
// declare nsCString, et. al.
#include "string-template-def-char.h"
#include "nsTString.h"
#include "string-template-undef.h"
static_assert(sizeof(char16_t) == 2, "size of char16_t must be 2");
static_assert(sizeof(nsString::char_type) == 2,
@ -46,6 +39,14 @@ static_assert(nsString::char_type(-1) > nsString::char_type(0),
static_assert(sizeof(nsCString::char_type) == 1,
"size of nsCString::char_type must be 1");
static_assert(sizeof(nsTLiteralString<char>) == sizeof(nsTString<char>),
"nsLiteralCString can masquerade as nsCString, "
"so they must have identical layout");
static_assert(sizeof(nsTLiteralString<char16_t>) == sizeof(nsTString<char16_t>),
"nsTLiteralString can masquerade as nsString, "
"so they must have identical layout");
/**
* A helper class that converts a UTF-16 string to ASCII in a lossy manner
@ -60,7 +61,7 @@ public:
NS_LossyConvertUTF16toASCII(const char16ptr_t aString, uint32_t aLength)
{
LossyAppendUTF16toASCII(Substring(aString, aLength), *this);
LossyAppendUTF16toASCII(Substring(static_cast<const char16_t*>(aString), aLength), *this);
}
explicit NS_LossyConvertUTF16toASCII(const nsAString& aString)
@ -111,7 +112,7 @@ public:
NS_ConvertUTF16toUTF8(const char16ptr_t aString, uint32_t aLength)
{
AppendUTF16toUTF8(Substring(aString, aLength), *this);
AppendUTF16toUTF8(Substring(static_cast<const char16_t*>(aString), aLength), *this);
}
explicit NS_ConvertUTF16toUTF8(const nsAString& aString)

Просмотреть файл

@ -8,16 +8,7 @@
#include "nsAString.h"
#include "plstr.h"
// define nsStringComparator
#include "string-template-def-unichar.h"
#include "nsTStringComparator.cpp"
#include "string-template-undef.h"
// define nsCStringComparator
#include "string-template-def-char.h"
#include "nsTStringComparator.cpp"
#include "string-template-undef.h"
int

Просмотреть файл

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsStringFlags_h
#define nsStringFlags_h
#include <stdint.h>
#include "mozilla/TypedEnumBits.h"
namespace mozilla {
namespace detail {
// NOTE: these flags are declared public _only_ for convenience inside
// the string implementation. And they are outside of the string
// class so that the type is the same for both narrow and wide
// strings.
// bits for mDataFlags
enum class StringDataFlags : uint16_t
{
// Some terminology:
//
// "dependent buffer" A dependent buffer is one that the string class
// does not own. The string class relies on some
// external code to ensure the lifetime of the
// dependent buffer.
//
// "shared buffer" A shared buffer is one that the string class
// allocates. When it allocates a shared string
// buffer, it allocates some additional space at
// the beginning of the buffer for additional
// fields, including a reference count and a
// buffer length. See nsStringHeader.
//
// "adopted buffer" An adopted buffer is a raw string buffer
// allocated on the heap (using moz_xmalloc)
// of which the string class subsumes ownership.
//
// Some comments about the string data flags:
//
// SHARED, OWNED, and FIXED are all mutually exlusive. They
// indicate the allocation type of mData. If none of these flags
// are set, then the string buffer is dependent.
//
// SHARED, OWNED, or FIXED imply TERMINATED. This is because
// the string classes always allocate null-terminated buffers, and
// non-terminated substrings are always dependent.
//
// VOIDED implies TERMINATED, and moreover it implies that mData
// points to char_traits::sEmptyBuffer. Therefore, VOIDED is
// mutually exclusive with SHARED, OWNED, and FIXED.
TERMINATED = 1 << 0, // IsTerminated returns true
VOIDED = 1 << 1, // IsVoid returns true
SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
LITERAL = 1 << 5 // mData points to a string literal; DataFlags::TERMINATED will also be set
};
// bits for mClassFlags
enum class StringClassFlags : uint16_t
{
FIXED = 1 << 0, // |this| is of type nsTFixedString
NULL_TERMINATED = 1 << 1 // |this| requires its buffer is null-terminated
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringDataFlags)
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringClassFlags)
} // namespace detail
} // namespace mozilla
#endif

Просмотреть файл

@ -14,36 +14,62 @@
namespace mozilla {
namespace detail {
class nsStringRepr;
class nsCStringRepr;
template <typename T> class nsTStringRepr;
using nsStringRepr = nsTStringRepr<char16_t>;
using nsCStringRepr = nsTStringRepr<char>;
} // namespace detail
} // namespace mozilla
static const size_t AutoStringDefaultStorageSize = 64;
template <typename T> class nsTSubstring;
template <typename T> class nsTSubstringTuple;
template <typename T> class nsTString;
template <typename T, size_t N> class nsTAutoStringN;
template <typename T> class nsTDependentString;
template <typename T> class nsTDependentSubstring;
template <typename T> class nsTPromiseFlatString;
template <typename T> class nsTStringComparator;
template <typename T> class nsTDefaultStringComparator;
template <typename T> class nsTLiteralString;
template <typename T> class nsTFixedString;
// We define this version without a size param instead of providing a
// default value for N so that so there is a default typename that doesn't
// require angle brackets.
template <typename T> using nsTAutoString = nsTAutoStringN<T, AutoStringDefaultStorageSize>;
// Double-byte (char16_t) string types.
class nsAString;
class nsSubstringTuple;
class nsString;
template<size_t N> class nsAutoStringN;
using nsAutoString = nsAutoStringN<AutoStringDefaultStorageSize>;
class nsDependentString;
class nsDependentSubstring;
class nsPromiseFlatString;
class nsStringComparator;
class nsDefaultStringComparator;
using nsAString = nsTSubstring<char16_t>;
using nsSubstringTuple = nsTSubstringTuple<char16_t>;
using nsString = nsTString<char16_t>;
using nsAutoString = nsTAutoString<char16_t>;
template <size_t N> using nsAutoStringN = nsTAutoStringN<char16_t, N>;
using nsDependentString = nsTDependentString<char16_t>;
using nsDependentSubstring = nsTDependentSubstring<char16_t>;
using nsPromiseFlatString = nsTPromiseFlatString<char16_t>;
using nsStringComparator = nsTStringComparator<char16_t>;
using nsDefaultStringComparator = nsTDefaultStringComparator<char16_t>;
using nsLiteralString = nsTLiteralString<char16_t>;
using nsFixedString = nsTFixedString<char16_t>;
// Single-byte (char) string types.
class nsACString;
class nsCSubstringTuple;
class nsCString;
template<size_t N> class nsAutoCStringN;
using nsAutoCString = nsAutoCStringN<AutoStringDefaultStorageSize>;
class nsDependentCString;
class nsDependentCSubstring;
class nsPromiseFlatCString;
class nsCStringComparator;
class nsDefaultCStringComparator;
using nsACString = nsTSubstring<char>;
using nsCSubstringTuple = nsTSubstringTuple<char>;
using nsCString = nsTString<char>;
using nsAutoCString = nsTAutoString<char>;
template <size_t N> using nsAutoCStringN = nsTAutoStringN<char, N>;
using nsDependentCString = nsTDependentString<char>;
using nsDependentCSubstring = nsTDependentSubstring<char>;
using nsPromiseFlatCString = nsTPromiseFlatString<char>;
using nsCStringComparator = nsTStringComparator<char>;
using nsDefaultCStringComparator = nsTDefaultStringComparator<char>;
using nsLiteralCString = nsTLiteralString<char>;
using nsFixedCString = nsTFixedString<char>;
#endif /* !defined(nsStringFwd_h) */

Просмотреть файл

@ -27,8 +27,7 @@ public:
typedef const CharT& reference;
private:
friend class mozilla::detail::nsStringRepr;
friend class mozilla::detail::nsCStringRepr;
friend class mozilla::detail::nsTStringRepr<CharT>;
// unfortunately, the API for nsReadingIterator requires that the
// iterator know its start and end positions. this was needed when
@ -130,8 +129,7 @@ public:
typedef CharT& reference;
private:
friend class nsAString;
friend class nsACString;
friend class nsTSubstring<CharT>;
// unfortunately, the API for nsWritingIterator requires that the
// iterator know its start and end positions. this was needed when

Просмотреть файл

@ -849,78 +849,86 @@ RFind_ComputeSearchRange( uint32_t bigLen, uint32_t littleLen, int32_t& offset,
//-----------------------------------------------------------------------------
// define nsString obsolete methods
#include "string-template-def-unichar.h"
#include "nsTStringObsolete.cpp"
#include "string-template-undef.h"
// define nsCString obsolete methods
#include "string-template-def-char.h"
#include "nsTStringObsolete.cpp"
#include "string-template-undef.h"
//-----------------------------------------------------------------------------
// specialized methods:
template <typename T>
template <typename EnableIfChar16>
int32_t
nsString::Find( const nsString& aString, int32_t aOffset, int32_t aCount ) const
nsTString<T>::Find(const self_type& aString, int32_t aOffset, int32_t aCount) const
{
// this method changes the meaning of aOffset and aCount:
Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
int32_t result = FindSubstring(mData + aOffset, aCount, static_cast<const char16_t*>(aString.get()), aString.Length(), false);
// Capture the raw buffer locally to help msvc deduce the type.
const char_type* str = aString.get();
int32_t result = FindSubstring(this->mData + aOffset, aCount, str, aString.Length(), false);
if (result != kNotFound)
result += aOffset;
return result;
}
template <typename T>
template <typename EnableIfChar16>
int32_t
nsString::Find( const char16_t* aString, int32_t aOffset, int32_t aCount ) const
nsTString<T>::Find(const char_type* aString, int32_t aOffset, int32_t aCount) const
{
return Find(nsDependentString(aString), aOffset, aCount);
return Find(nsTDependentString<T>(aString), aOffset, aCount);
}
template <typename T>
template <typename EnableIfChar16>
int32_t
nsString::RFind( const nsString& aString, int32_t aOffset, int32_t aCount ) const
nsTString<T>::RFind(const self_type& aString, int32_t aOffset, int32_t aCount) const
{
// this method changes the meaning of aOffset and aCount:
RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
RFind_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
int32_t result = RFindSubstring(mData + aOffset, aCount, static_cast<const char16_t*>(aString.get()), aString.Length(), false);
// Capture the raw buffer locally to help msvc deduce the type.
const char_type* str = aString.get();
int32_t result = RFindSubstring(this->mData + aOffset, aCount, str, aString.Length(), false);
if (result != kNotFound)
result += aOffset;
return result;
}
template <typename T>
template <typename EnableIfChar16>
int32_t
nsString::RFind( const char16_t* aString, int32_t aOffset, int32_t aCount ) const
nsTString<T>::RFind(const char_type* aString, int32_t aOffset, int32_t aCount) const
{
return RFind(nsDependentString(aString), aOffset, aCount);
return RFind(nsTDependentString<T>(aString), aOffset, aCount);
}
template <typename T>
template <typename EnableIfChar16>
int32_t
nsString::FindCharInSet( const char16_t* aSet, int32_t aOffset ) const
nsTString<T>::FindCharInSet(const char* aSet, int32_t aOffset) const
{
if (aOffset < 0)
aOffset = 0;
else if (aOffset >= int32_t(mLength))
else if (aOffset >= int32_t(this->mLength))
return kNotFound;
int32_t result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet);
if (result != kNotFound)
result += aOffset;
return result;
}
template <typename T>
template <typename EnableIfChar16>
void
nsString::ReplaceChar( const char16_t* aSet, char16_t aNewChar )
nsTString<T>::ReplaceChar(const char* aSet, char16_t aNewChar)
{
if (!EnsureMutable()) // XXX do this lazily?
AllocFailed(mLength);
if (!this->EnsureMutable()) // XXX do this lazily?
this->AllocFailed(this->mLength);
char16_t* data = mData;
uint32_t lenRemaining = mLength;
char16_t* data = this->mData;
uint32_t lenRemaining = this->mLength;
while (lenRemaining)
{
@ -939,12 +947,14 @@ nsString::ReplaceChar( const char16_t* aSet, char16_t aNewChar )
* nsTString::Compare,CompareWithConversion,etc.
*/
template <typename T>
template <typename EnableIfChar>
int32_t
nsCString::Compare( const char* aString, bool aIgnoreCase, int32_t aCount ) const
nsTString<T>::Compare(const char_type* aString, bool aIgnoreCase, int32_t aCount) const
{
uint32_t strLen = char_traits::length(aString);
int32_t maxCount = int32_t(XPCOM_MIN(mLength, strLen));
int32_t maxCount = int32_t(XPCOM_MIN(this->mLength, strLen));
int32_t compareCount;
if (aCount < 0 || aCount > maxCount)
@ -953,27 +963,29 @@ nsCString::Compare( const char* aString, bool aIgnoreCase, int32_t aCount ) cons
compareCount = aCount;
int32_t result =
nsBufferRoutines<char>::compare(mData, aString, compareCount, aIgnoreCase);
nsBufferRoutines<T>::compare(this->mData, aString, compareCount, aIgnoreCase);
if (result == 0 &&
(aCount < 0 || strLen < uint32_t(aCount) || mLength < uint32_t(aCount)))
(aCount < 0 || strLen < uint32_t(aCount) || this->mLength < uint32_t(aCount)))
{
// Since the caller didn't give us a length to test, or strings shorter
// than aCount, and compareCount characters matched, we have to assume
// that the longer string is greater.
if (mLength != strLen)
result = (mLength < strLen) ? -1 : 1;
if (this->mLength != strLen)
result = (this->mLength < strLen) ? -1 : 1;
}
return result;
}
template <typename T>
template <typename EnableIfChar16>
bool
nsString::EqualsIgnoreCase( const char* aString, int32_t aCount ) const
nsTString<T>::EqualsIgnoreCase(const incompatible_char_type* aString, int32_t aCount) const
{
uint32_t strLen = nsCharTraits<char>::length(aString);
int32_t maxCount = int32_t(XPCOM_MIN(mLength, strLen));
int32_t maxCount = int32_t(XPCOM_MIN(this->mLength, strLen));
int32_t compareCount;
if (aCount < 0 || aCount > maxCount)
@ -982,16 +994,16 @@ nsString::EqualsIgnoreCase( const char* aString, int32_t aCount ) const
compareCount = aCount;
int32_t result =
nsBufferRoutines<char16_t>::compare(mData, aString, compareCount, true);
nsBufferRoutines<T>::compare(this->mData, aString, compareCount, true);
if (result == 0 &&
(aCount < 0 || strLen < uint32_t(aCount) || mLength < uint32_t(aCount)))
(aCount < 0 || strLen < uint32_t(aCount) || this->mLength < uint32_t(aCount)))
{
// Since the caller didn't give us a length to test, or strings shorter
// than aCount, and compareCount characters matched, we have to assume
// that the longer string is greater.
if (mLength != strLen)
if (this->mLength != strLen)
result = 1; // Arbitrarily using any number != 0
}
return result == 0;
@ -1002,17 +1014,18 @@ nsString::EqualsIgnoreCase( const char* aString, int32_t aCount ) const
* nsTString::ToDouble
*/
template <>
double
nsCString::ToDouble(nsresult* aErrorCode) const
nsTString<char>::ToDouble(nsresult* aErrorCode) const
{
double res = 0.0;
if (mLength > 0)
if (this->mLength > 0)
{
char *conv_stopped;
const char *str = mData;
const char *str = this->mData;
// Use PR_strtod, not strtod, since we don't want locale involved.
res = PR_strtod(str, &conv_stopped);
if (conv_stopped == str+mLength)
if (conv_stopped == str+this->mLength)
*aErrorCode = NS_OK;
else // Not all the string was scanned
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
@ -1025,10 +1038,21 @@ nsCString::ToDouble(nsresult* aErrorCode) const
return res;
}
template <>
double
nsString::ToDouble(nsresult* aErrorCode) const
nsTString<char16_t>::ToDouble(nsresult* aErrorCode) const
{
return NS_LossyConvertUTF16toASCII(*this).ToDouble(aErrorCode);
}
template <typename T>
float
nsTString<T>::ToFloat(nsresult* aErrorCode) const
{
return (float)ToDouble(aErrorCode);
}
template class nsTString<char>;
template class nsTString<char16_t>;
#endif // !MOZ_STRING_WITH_OBSOLETE_API

Просмотреть файл

@ -352,14 +352,7 @@ nsStringBuffer::SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSiz
// ---------------------------------------------------------------------------
// define nsAString
#include "string-template-def-unichar.h"
#include "nsTSubstring.cpp"
#include "string-template-undef.h"
// define nsACString
#include "string-template-def-char.h"
#include "nsTSubstring.cpp"
#include "string-template-undef.h"
// Provide rust bindings to the nsA[C]String types
extern "C" {

Просмотреть файл

@ -6,12 +6,4 @@
#include "nsSubstringTuple.h"
// define nsSubstringTuple
#include "string-template-def-unichar.h"
#include "nsTSubstringTuple.cpp"
#include "string-template-undef.h"
// define nsCSubstringTuple
#include "string-template-def-char.h"
#include "nsTSubstringTuple.cpp"
#include "string-template-undef.h"

Просмотреть файл

@ -9,14 +9,6 @@
#include "nsSubstring.h"
// declare nsSubstringTuple
#include "string-template-def-unichar.h"
#include "nsTSubstringTuple.h"
#include "string-template-undef.h"
// declare nsCSubstringTuple
#include "string-template-def-char.h"
#include "nsTSubstringTuple.h"
#include "string-template-undef.h"
#endif // !defined(nsSubstringTuple_h___)

Просмотреть файл

@ -4,22 +4,24 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
nsTDependentString_CharT::nsTDependentString_CharT(const char_type* aStart,
const char_type* aEnd)
template <typename T>
nsTDependentString<T>::nsTDependentString(const char_type* aStart,
const char_type* aEnd)
: string_type(const_cast<char_type*>(aStart), uint32_t(aEnd - aStart),
DataFlags::TERMINATED, ClassFlags(0))
{
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
AssertValidDependentString();
this->AssertValidDependentString();
}
template <typename T>
void
nsTDependentString_CharT::Rebind(const string_type& str, uint32_t startPos)
nsTDependentString<T>::Rebind(const string_type& str, uint32_t startPos)
{
MOZ_ASSERT(str.GetDataFlags() & DataFlags::TERMINATED, "Unterminated flat string");
// If we currently own a buffer, release it.
Finalize();
this->Finalize();
size_type strLength = str.Length();
@ -31,12 +33,13 @@ nsTDependentString_CharT::Rebind(const string_type& str, uint32_t startPos)
const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
size_type newLen = strLength - startPos;
DataFlags newDataFlags = str.GetDataFlags() & (DataFlags::TERMINATED | DataFlags::LITERAL);
SetData(newData, newLen, newDataFlags);
this->SetData(newData, newLen, newDataFlags);
}
template <typename T>
void
nsTDependentString_CharT::Rebind(const char_type* aStart, const char_type* aEnd)
nsTDependentString<T>::Rebind(const char_type* aStart, const char_type* aEnd)
{
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
Rebind(aStart, uint32_t(aEnd - aStart));
this->Rebind(aStart, uint32_t(aEnd - aStart));
}

Просмотреть файл

@ -4,9 +4,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsTDependentString_h
#define nsTDependentString_h
#include "nsTString.h"
/**
* nsTDependentString_CharT
* nsTDependentString
*
* Stores a null-terminated, immutable sequence of characters.
*
@ -16,11 +20,41 @@
* nsTDependentString continues to reference valid memory for the
* duration of its use.
*/
class nsTDependentString_CharT : public nsTString_CharT
template <typename T>
class nsTDependentString : public nsTString<T>
{
public:
typedef nsTDependentString_CharT self_type;
typedef nsTDependentString<T> self_type;
typedef nsTString<T> base_string_type;
typedef typename base_string_type::string_type string_type;
typedef typename base_string_type::fallible_t fallible_t;
typedef typename base_string_type::char_type char_type;
typedef typename base_string_type::char_traits char_traits;
typedef typename base_string_type::incompatible_char_type incompatible_char_type;
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
typedef typename base_string_type::const_iterator const_iterator;
typedef typename base_string_type::iterator iterator;
typedef typename base_string_type::comparator_type comparator_type;
typedef typename base_string_type::char_iterator char_iterator;
typedef typename base_string_type::const_char_iterator const_char_iterator;
typedef typename base_string_type::index_type index_type;
typedef typename base_string_type::size_type size_type;
// These are only for internal use within the string classes:
typedef typename base_string_type::DataFlags DataFlags;
typedef typename base_string_type::ClassFlags ClassFlags;
using typename base_string_type::IsChar;
using typename base_string_type::IsChar16;
public:
@ -28,47 +62,49 @@ public:
* constructors
*/
nsTDependentString_CharT(const char_type* aStart, const char_type* aEnd);
nsTDependentString(const char_type* aStart, const char_type* aEnd);
nsTDependentString_CharT(const char_type* aData, uint32_t aLength)
nsTDependentString(const char_type* aData, uint32_t aLength)
: string_type(const_cast<char_type*>(aData), aLength,
DataFlags::TERMINATED, ClassFlags(0))
{
AssertValidDependentString();
this->AssertValidDependentString();
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
nsTDependentString_CharT(char16ptr_t aData, uint32_t aLength)
: nsTDependentString_CharT(static_cast<const char16_t*>(aData), aLength)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
nsTDependentString(char16ptr_t aData, uint32_t aLength)
: nsTDependentString(static_cast<const char16_t*>(aData), aLength)
{
}
#endif
explicit
nsTDependentString_CharT(const char_type* aData)
nsTDependentString(const char_type* aData)
: string_type(const_cast<char_type*>(aData),
uint32_t(char_traits::length(aData)),
DataFlags::TERMINATED, ClassFlags(0))
{
AssertValidDependentString();
string_type::AssertValidDependentString();
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
explicit
nsTDependentString_CharT(char16ptr_t aData)
: nsTDependentString_CharT(static_cast<const char16_t*>(aData))
nsTDependentString(char16ptr_t aData)
: nsTDependentString(static_cast<const char16_t*>(aData))
{
}
#endif
nsTDependentString_CharT(const string_type& aStr, uint32_t aStartPos)
nsTDependentString(const string_type& aStr, uint32_t aStartPos)
: string_type()
{
Rebind(aStr, aStartPos);
}
// Create a nsTDependentSubstring to be bound later
nsTDependentString_CharT()
nsTDependentString()
: string_type()
{
}
@ -83,7 +119,7 @@ public:
* allow this class to be bound to a different string...
*/
using nsTString_CharT::Rebind;
using nsTString<T>::Rebind;
void Rebind(const char_type* aData)
{
Rebind(aData, uint32_t(char_traits::length(aData)));
@ -95,5 +131,10 @@ public:
private:
// NOT USED
nsTDependentString_CharT(const substring_tuple_type&) = delete;
nsTDependentString(const substring_tuple_type&) = delete;
};
extern template class nsTDependentString<char>;
extern template class nsTDependentString<char16_t>;
#endif

Просмотреть файл

@ -4,12 +4,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
template <typename T>
void
nsTDependentSubstring_CharT::Rebind(const substring_type& str,
nsTDependentSubstring<T>::Rebind(const substring_type& str,
uint32_t startPos, uint32_t length)
{
// If we currently own a buffer, release it.
Finalize();
this->Finalize();
size_type strLength = str.Length();
@ -21,44 +22,49 @@ nsTDependentSubstring_CharT::Rebind(const substring_type& str,
const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
size_type newLength = XPCOM_MIN(length, strLength - startPos);
DataFlags newDataFlags = DataFlags(0);
SetData(newData, newLength, newDataFlags);
this->SetData(newData, newLength, newDataFlags);
}
template <typename T>
void
nsTDependentSubstring_CharT::Rebind(const char_type* data, size_type length)
nsTDependentSubstring<T>::Rebind(const char_type* data, size_type length)
{
NS_ASSERTION(data, "nsTDependentSubstring must wrap a non-NULL buffer");
// If we currently own a buffer, release it.
Finalize();
this->Finalize();
char_type* newData =
const_cast<char_type*>(static_cast<const char_type*>(data));
size_type newLength = length;
DataFlags newDataFlags = DataFlags(0);
SetData(newData, newLength, newDataFlags);
this->SetData(newData, newLength, newDataFlags);
}
template <typename T>
void
nsTDependentSubstring_CharT::Rebind(const char_type* aStart, const char_type* aEnd)
nsTDependentSubstring<T>::Rebind(const char_type* aStart, const char_type* aEnd)
{
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
Rebind(aStart, size_type(aEnd - aStart));
this->Rebind(aStart, size_type(aEnd - aStart));
}
nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(const char_type* aStart,
const char_type* aEnd)
template <typename T>
nsTDependentSubstring<T>::nsTDependentSubstring(const char_type* aStart,
const char_type* aEnd)
: substring_type(const_cast<char_type*>(aStart), uint32_t(aEnd - aStart),
DataFlags(0), ClassFlags(0))
{
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(char16ptr_t aStart,
char16ptr_t aEnd)
: nsTDependentSubstring_CharT(static_cast<const char16_t*>(aStart),
static_cast<const char16_t*>(aEnd))
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename T>
template <typename EnableIfChar16>
nsTDependentSubstring<T>::nsTDependentSubstring(char16ptr_t aStart,
char16ptr_t aEnd)
: substring_type(static_cast<const char16_t*>(aStart),
static_cast<const char16_t*>(aEnd))
{
MOZ_RELEASE_ASSERT(static_cast<const char16_t*>(aStart) <=
static_cast<const char16_t*>(aEnd),
@ -66,8 +72,9 @@ nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(char16ptr_t aStart,
}
#endif
nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(const const_iterator& aStart,
const const_iterator& aEnd)
template <typename T>
nsTDependentSubstring<T>::nsTDependentSubstring(const const_iterator& aStart,
const const_iterator& aEnd)
: substring_type(const_cast<char_type*>(aStart.get()),
uint32_t(aEnd.get() - aStart.get()),
DataFlags(0), ClassFlags(0))
@ -75,9 +82,25 @@ nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(const const_iterator& a
MOZ_RELEASE_ASSERT(aStart.get() <= aEnd.get(), "Overflow!");
}
const nsTDependentSubstring_CharT
Substring(const CharT* aStart, const CharT* aEnd)
template <typename T>
const nsTDependentSubstring<T>
Substring(const T* aStart, const T* aEnd)
{
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
return nsTDependentSubstring_CharT(aStart, aEnd);
return nsTDependentSubstring<T>(aStart, aEnd);
}
#if defined(MOZ_USE_CHAR16_WRAPPER)
const nsTDependentSubstring<char16_t>
Substring(char16ptr_t aData, uint32_t aLength)
{
return nsTDependentSubstring<char16_t>(aData, aLength);
}
const nsTDependentSubstring<char16_t>
Substring(char16ptr_t aStart, char16ptr_t aEnd)
{
return Substring(static_cast<const char16_t*>(aStart),
static_cast<const char16_t*>(aEnd));
}
#endif

Просмотреть файл

@ -5,6 +5,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#ifndef nsTDependentSubstring_h
#define nsTDependentSubstring_h
#include "nsTSubstring.h"
#include "nsTLiteralString.h"
/**
* nsTDependentSubstring_CharT
*
@ -16,11 +22,38 @@
* nsDependentSubstring for wide characters
* nsDependentCSubstring for narrow characters
*/
class nsTDependentSubstring_CharT : public nsTSubstring_CharT
template <typename T>
class nsTDependentSubstring : public nsTSubstring<T>
{
public:
typedef nsTDependentSubstring_CharT self_type;
typedef nsTDependentSubstring<T> self_type;
typedef nsTSubstring<T> substring_type;
typedef typename substring_type::fallible_t fallible_t;
typedef typename substring_type::char_type char_type;
typedef typename substring_type::char_traits char_traits;
typedef typename substring_type::incompatible_char_type incompatible_char_type;
typedef typename substring_type::substring_tuple_type substring_tuple_type;
typedef typename substring_type::const_iterator const_iterator;
typedef typename substring_type::iterator iterator;
typedef typename substring_type::comparator_type comparator_type;
typedef typename substring_type::char_iterator char_iterator;
typedef typename substring_type::const_char_iterator const_char_iterator;
typedef typename substring_type::index_type index_type;
typedef typename substring_type::size_type size_type;
// These are only for internal use within the string classes:
typedef typename substring_type::DataFlags DataFlags;
typedef typename substring_type::ClassFlags ClassFlags;
using typename substring_type::IsChar;
using typename substring_type::IsChar16;
public:
@ -31,35 +64,37 @@ public:
void Rebind(const char_type* aStart, const char_type* aEnd);
nsTDependentSubstring_CharT(const substring_type& aStr, uint32_t aStartPos,
uint32_t aLength = size_type(-1))
nsTDependentSubstring(const substring_type& aStr, uint32_t aStartPos,
uint32_t aLength = size_type(-1))
: substring_type()
{
Rebind(aStr, aStartPos, aLength);
}
nsTDependentSubstring_CharT(const char_type* aData, size_type aLength)
nsTDependentSubstring(const char_type* aData, size_type aLength)
: substring_type(const_cast<char_type*>(aData), aLength,
DataFlags(0), ClassFlags(0))
{
}
nsTDependentSubstring_CharT(const char_type* aStart, const char_type* aEnd);
nsTDependentSubstring(const char_type* aStart, const char_type* aEnd);
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
nsTDependentSubstring_CharT(char16ptr_t aData, size_type aLength)
: nsTDependentSubstring_CharT(static_cast<const char16_t*>(aData), aLength)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
nsTDependentSubstring(char16ptr_t aData, size_type aLength)
: nsTDependentSubstring(static_cast<const char16_t*>(aData), aLength)
{
}
nsTDependentSubstring_CharT(char16ptr_t aStart, char16ptr_t aEnd);
template <typename EnableIfChar16 = IsChar16>
nsTDependentSubstring(char16ptr_t aStart, char16ptr_t aEnd);
#endif
nsTDependentSubstring_CharT(const const_iterator& aStart,
const const_iterator& aEnd);
nsTDependentSubstring(const const_iterator& aStart,
const const_iterator& aEnd);
// Create a nsTDependentSubstring to be bound later
nsTDependentSubstring_CharT()
nsTDependentSubstring()
: substring_type()
{
}
@ -71,37 +106,64 @@ private:
void operator=(const self_type&); // we're immutable, you can't assign into a substring
};
inline const nsTDependentSubstring_CharT
Substring(const nsTSubstring_CharT& aStr, uint32_t aStartPos,
extern template class nsTDependentSubstring<char>;
extern template class nsTDependentSubstring<char16_t>;
template <typename T>
inline const nsTDependentSubstring<T>
Substring(const nsTSubstring<T>& aStr, uint32_t aStartPos,
uint32_t aLength = uint32_t(-1))
{
return nsTDependentSubstring_CharT(aStr, aStartPos, aLength);
return nsTDependentSubstring<T>(aStr, aStartPos, aLength);
}
inline const nsTDependentSubstring_CharT
Substring(const nsReadingIterator<CharT>& aStart,
const nsReadingIterator<CharT>& aEnd)
template <typename T>
inline const nsTDependentSubstring<T>
Substring(const nsTLiteralString<T>& aStr, uint32_t aStartPos,
uint32_t aLength = uint32_t(-1))
{
return nsTDependentSubstring_CharT(aStart.get(), aEnd.get());
return nsTDependentSubstring<T>(aStr, aStartPos, aLength);
}
inline const nsTDependentSubstring_CharT
Substring(const CharT* aData, uint32_t aLength)
template <typename T>
inline const nsTDependentSubstring<T>
Substring(const nsReadingIterator<T>& aStart,
const nsReadingIterator<T>& aEnd)
{
return nsTDependentSubstring_CharT(aData, aLength);
return nsTDependentSubstring<T>(aStart.get(), aEnd.get());
}
const nsTDependentSubstring_CharT
Substring(const CharT* aStart, const CharT* aEnd);
inline const nsTDependentSubstring_CharT
StringHead(const nsTSubstring_CharT& aStr, uint32_t aCount)
template <typename T>
inline const nsTDependentSubstring<T>
Substring(const T* aData, uint32_t aLength)
{
return nsTDependentSubstring_CharT(aStr, 0, aCount);
return nsTDependentSubstring<T>(aData, aLength);
}
inline const nsTDependentSubstring_CharT
StringTail(const nsTSubstring_CharT& aStr, uint32_t aCount)
template <typename T>
const nsTDependentSubstring<T>
Substring(const T* aStart, const T* aEnd);
#if defined(MOZ_USE_CHAR16_WRAPPER)
inline const nsTDependentSubstring<char16_t>
Substring(char16ptr_t aData, uint32_t aLength);
const nsTDependentSubstring<char16_t>
Substring(char16ptr_t aStart, char16ptr_t aEnd);
#endif
template <typename T>
inline const nsTDependentSubstring<T>
StringHead(const nsTSubstring<T>& aStr, uint32_t aCount)
{
return nsTDependentSubstring_CharT(aStr, aStr.Length() - aCount, aCount);
return nsTDependentSubstring<T>(aStr, 0, aCount);
}
template <typename T>
inline const nsTDependentSubstring<T>
StringTail(const nsTSubstring<T>& aStr, uint32_t aCount)
{
return nsTDependentSubstring<T>(aStr, aStr.Length() - aCount, aCount);
}
#endif

Просмотреть файл

@ -4,6 +4,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsTLiteralString_h
#define nsTLiteralString_h
#include "nsTStringRepr.h"
/**
* nsTLiteralString_CharT
*
@ -15,11 +20,17 @@
* to be static (permanent) and therefore, as an optimization, this class
* does not have a destructor.
*/
class nsTLiteralString_CharT : public mozilla::detail::nsTStringRepr_CharT
template<typename T>
class nsTLiteralString : public mozilla::detail::nsTStringRepr<T>
{
public:
typedef nsTLiteralString_CharT self_type;
typedef nsTLiteralString<T> self_type;
typedef typename mozilla::detail::nsTStringRepr<T>::base_string_type base_string_type;
typedef typename base_string_type::char_type char_type;
typedef typename base_string_type::size_type size_type;
typedef typename base_string_type::DataFlags DataFlags;
typedef typename base_string_type::ClassFlags ClassFlags;
public:
@ -28,7 +39,7 @@ public:
*/
template<size_type N>
explicit constexpr nsTLiteralString_CharT(const char_type (&aStr)[N])
explicit constexpr nsTLiteralString(const char_type (&aStr)[N])
: base_string_type(const_cast<char_type*>(aStr), N - 1,
DataFlags::TERMINATED | DataFlags::LITERAL,
ClassFlags::NULL_TERMINATED)
@ -40,40 +51,42 @@ public:
* Use sparingly. If possible, rewrite code to use const ns[C]String&
* and the implicit cast will just work.
*/
const nsTString_CharT& AsString() const
const nsTString<T>& AsString() const
{
return *reinterpret_cast<const nsTString_CharT*>(this);
return *reinterpret_cast<const nsTString<T>*>(this);
}
operator const nsTString_CharT&() const
operator const nsTString<T>&() const
{
return AsString();
}
template<typename N> struct raw_type { typedef N* type; };
#ifdef MOZ_USE_CHAR16_WRAPPER
template<> struct raw_type<char16_t> { typedef char16ptr_t type; };
#endif
/**
* Prohibit get() on temporaries as in nsLiteralCString("x").get().
* These should be written as just "x", using a string literal directly.
*/
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
char16ptr_t get() const && = delete;
char16ptr_t get() const &
#else
const char_type* get() const && = delete;
const char_type* get() const &
#endif
const typename raw_type<T>::type get() const && = delete;
const typename raw_type<T>::type get() const &
{
return mData;
return this->mData;
}
private:
// NOT TO BE IMPLEMENTED
template<size_type N>
nsTLiteralString_CharT(char_type (&aStr)[N]) = delete;
nsTLiteralString(char_type (&aStr)[N]) = delete;
self_type& operator=(const self_type&) = delete;
};
static_assert(sizeof(nsTLiteralString_CharT) == sizeof(nsTString_CharT),
"nsTLiteralString_CharT can masquerade as nsTString_CharT, "
"so they must have identical layout");
extern template class nsTLiteralString<char>;
extern template class nsTLiteralString<char16_t>;
#endif

Просмотреть файл

@ -4,8 +4,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
template <typename T>
void
nsTPromiseFlatString_CharT::Init(const substring_type& str)
nsTPromiseFlatString<T>::Init(const substring_type& str)
{
if (str.IsTerminated()) {
char_type* newData =
@ -15,8 +16,8 @@ nsTPromiseFlatString_CharT::Init(const substring_type& str)
str.GetDataFlags() & (DataFlags::TERMINATED | DataFlags::LITERAL);
// does not promote DataFlags::VOIDED
SetData(newData, newLength, newDataFlags);
this->SetData(newData, newLength, newDataFlags);
} else {
Assign(str);
this->Assign(str);
}
}

Просмотреть файл

@ -4,6 +4,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsTPromiseFlatString_h
#define nsTPromiseFlatString_h
#include "nsTString.h"
/**
* NOTE:
@ -64,11 +68,22 @@
* string (e.g., |nsTString|), the right thing happens.
*/
class nsTPromiseFlatString_CharT : public nsTString_CharT
template <typename T>
class nsTPromiseFlatString : public nsTString<T>
{
public:
typedef nsTPromiseFlatString_CharT self_type;
typedef nsTPromiseFlatString<T> self_type;
typedef nsTString<T> base_string_type;
typedef typename base_string_type::substring_type substring_type;
typedef typename base_string_type::string_type string_type;
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
typedef typename base_string_type::char_type char_type;
typedef typename base_string_type::size_type size_type;
// These are only for internal use within the string classes:
typedef typename base_string_type::DataFlags DataFlags;
typedef typename base_string_type::ClassFlags ClassFlags;
private:
@ -78,35 +93,55 @@ private:
void operator=(const self_type&) = delete;
// NOT TO BE IMPLEMENTED
nsTPromiseFlatString_CharT() = delete;
nsTPromiseFlatString() = delete;
// NOT TO BE IMPLEMENTED
nsTPromiseFlatString_CharT(const string_type& aStr) = delete;
nsTPromiseFlatString(const string_type& aStr) = delete;
public:
explicit
nsTPromiseFlatString_CharT(const substring_type& aStr)
nsTPromiseFlatString(const substring_type& aStr)
: string_type()
{
Init(aStr);
}
explicit
nsTPromiseFlatString_CharT(const substring_tuple_type& aTuple)
nsTPromiseFlatString(const substring_tuple_type& aTuple)
: string_type()
{
// nothing else to do here except assign the value of the tuple
// into ourselves.
Assign(aTuple);
this->Assign(aTuple);
}
};
extern template class nsTPromiseFlatString<char>;
extern template class nsTPromiseFlatString<char16_t>;
// We template this so that the constructor is chosen based on the type of the
// parameter. This allows us to reject attempts to promise a flat flat string.
template<class T>
const nsTPromiseFlatString_CharT
TPromiseFlatString_CharT(const T& aString)
const nsTPromiseFlatString<T>
TPromiseFlatString(const typename nsTPromiseFlatString<T>::substring_type& aString)
{
return nsTPromiseFlatString_CharT(aString);
return nsTPromiseFlatString<T>(aString);
}
template<class T>
const nsTPromiseFlatString<T>
TPromiseFlatString(const typename nsTPromiseFlatString<T>::substring_tuple_type& aString)
{
return nsTPromiseFlatString<T>(aString);
}
#ifndef PromiseFlatCString
#define PromiseFlatCString TPromiseFlatString<char>
#endif
#ifndef PromiseFlatString
#define PromiseFlatString TPromiseFlatString<char16_t>
#endif
#endif

Просмотреть файл

@ -4,13 +4,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
template <typename T>
void
nsTString_CharT::Rebind(const char_type* data, size_type length)
nsTString<T>::Rebind(const char_type* data, size_type length)
{
// If we currently own a buffer, release it.
Finalize();
this->Finalize();
SetData(const_cast<char_type*>(data), length, DataFlags::TERMINATED);
AssertValidDependentString();
this->SetData(const_cast<char_type*>(data), length, DataFlags::TERMINATED);
this->AssertValidDependentString();
}

Просмотреть файл

@ -5,6 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#ifndef nsTString_h
#define nsTString_h
#include "nsTSubstring.h"
/**
* This is the canonical null-terminated string class. All subclasses
* promise null-terminated storage. Instances of this class allocate
@ -17,11 +22,47 @@
* This class is also known as nsAFlat[C]String, where "flat" is used
* to denote a null-terminated string.
*/
class nsTString_CharT : public nsTSubstring_CharT
template <typename T>
class nsTString : public nsTSubstring<T>
{
public:
typedef nsTString_CharT self_type;
typedef nsTString<T> self_type;
#ifdef __clang__
// bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
using typename nsTSubstring<T>::substring_type;
#else
// On the other hand msvc chokes on the using statement. It seems others
// don't care either way so we lump them in here.
typedef typename nsTSubstring<T>::substring_type substring_type;
#endif
typedef typename substring_type::fallible_t fallible_t;
typedef typename substring_type::char_type char_type;
typedef typename substring_type::char_traits char_traits;
typedef typename substring_type::incompatible_char_type incompatible_char_type;
typedef typename substring_type::substring_tuple_type substring_tuple_type;
typedef typename substring_type::const_iterator const_iterator;
typedef typename substring_type::iterator iterator;
typedef typename substring_type::comparator_type comparator_type;
typedef typename substring_type::char_iterator char_iterator;
typedef typename substring_type::const_char_iterator const_char_iterator;
typedef typename substring_type::index_type index_type;
typedef typename substring_type::size_type size_type;
// These are only for internal use within the string classes:
typedef typename substring_type::DataFlags DataFlags;
typedef typename substring_type::ClassFlags ClassFlags;
using typename substring_type::IsChar;
using typename substring_type::IsChar16;
public:
@ -29,78 +70,80 @@ public:
* constructors
*/
nsTString_CharT()
nsTString()
: substring_type(ClassFlags::NULL_TERMINATED)
{
}
explicit
nsTString_CharT(const char_type* aData, size_type aLength = size_type(-1))
nsTString(const char_type* aData, size_type aLength = size_type(-1))
: substring_type(ClassFlags::NULL_TERMINATED)
{
Assign(aData, aLength);
this->Assign(aData, aLength);
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
explicit
nsTString_CharT(char16ptr_t aStr, size_type aLength = size_type(-1))
nsTString(char16ptr_t aStr, size_type aLength = size_type(-1))
: substring_type(ClassFlags::NULL_TERMINATED)
{
Assign(static_cast<const char16_t*>(aStr), aLength);
this->Assign(static_cast<const char16_t*>(aStr), aLength);
}
#endif
nsTString_CharT(const self_type& aStr)
nsTString(const self_type& aStr)
: substring_type(ClassFlags::NULL_TERMINATED)
{
Assign(aStr);
this->Assign(aStr);
}
MOZ_IMPLICIT nsTString_CharT(const substring_tuple_type& aTuple)
MOZ_IMPLICIT nsTString(const substring_tuple_type& aTuple)
: substring_type(ClassFlags::NULL_TERMINATED)
{
Assign(aTuple);
this->Assign(aTuple);
}
explicit
nsTString_CharT(const substring_type& aReadable)
nsTString(const substring_type& aReadable)
: substring_type(ClassFlags::NULL_TERMINATED)
{
Assign(aReadable);
this->Assign(aReadable);
}
// |operator=| does not inherit, so we must define our own
self_type& operator=(char_type aChar)
{
Assign(aChar);
this->Assign(aChar);
return *this;
}
self_type& operator=(const char_type* aData)
{
Assign(aData);
this->Assign(aData);
return *this;
}
self_type& operator=(const self_type& aStr)
{
Assign(aStr);
this->Assign(aStr);
return *this;
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
self_type& operator=(const char16ptr_t aStr)
{
Assign(static_cast<const char16_t*>(aStr));
this->Assign(static_cast<const char16_t*>(aStr));
return *this;
}
#endif
self_type& operator=(const substring_type& aStr)
{
Assign(aStr);
this->Assign(aStr);
return *this;
}
self_type& operator=(const substring_tuple_type& aTuple)
{
Assign(aTuple);
this->Assign(aTuple);
return *this;
}
@ -108,13 +151,14 @@ public:
* returns the null-terminated string
*/
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
MOZ_NO_DANGLING_ON_TEMPORARIES char16ptr_t get() const
#else
MOZ_NO_DANGLING_ON_TEMPORARIES const char_type* get() const
template <typename U> struct raw_type { typedef const U* type; };
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <> struct raw_type<char16_t> { typedef char16ptr_t type; };
#endif
MOZ_NO_DANGLING_ON_TEMPORARIES typename raw_type<T>::type get() const
{
return mData;
return this->mData;
}
@ -127,8 +171,8 @@ public:
char_type CharAt(index_type aIndex) const
{
NS_ASSERTION(aIndex <= mLength, "index exceeds allowable range");
return mData[aIndex];
NS_ASSERTION(aIndex <= this->mLength, "index exceeds allowable range");
return this->mData[aIndex];
}
char_type operator[](index_type aIndex) const
@ -151,24 +195,25 @@ public:
* @return offset in string, or kNotFound
*/
int32_t Find(const nsCString& aString, bool aIgnoreCase = false,
int32_t Find(const nsTString<char>& aString, bool aIgnoreCase = false,
int32_t aOffset = 0, int32_t aCount = -1) const;
int32_t Find(const char* aString, bool aIgnoreCase = false,
int32_t aOffset = 0, int32_t aCount = -1) const;
#ifdef CharT_is_PRUnichar
int32_t Find(const nsString& aString, int32_t aOffset = 0,
template <typename EnableIfChar16 = IsChar16>
int32_t Find(const self_type& aString, int32_t aOffset = 0,
int32_t aCount = -1) const;
int32_t Find(const char16_t* aString, int32_t aOffset = 0,
template <typename EnableIfChar16 = IsChar16>
int32_t Find(const char_type* aString, int32_t aOffset = 0,
int32_t aCount = -1) const;
#ifdef MOZ_USE_CHAR16_WRAPPER
template <typename EnableIfChar16 = IsChar16>
int32_t Find(char16ptr_t aString, int32_t aOffset = 0,
int32_t aCount = -1) const
{
return Find(static_cast<const char16_t*>(aString), aOffset, aCount);
}
#endif
#endif
/**
@ -183,17 +228,18 @@ public:
* @return offset in string, or kNotFound
*/
int32_t RFind(const nsCString& aString, bool aIgnoreCase = false,
// Case aIgnoreCase option only with char versions
int32_t RFind(const nsTString<char>& aString, bool aIgnoreCase = false,
int32_t aOffset = -1, int32_t aCount = -1) const;
int32_t RFind(const char* aCString, bool aIgnoreCase = false,
int32_t aOffset = -1, int32_t aCount = -1) const;
#ifdef CharT_is_PRUnichar
int32_t RFind(const nsString& aString, int32_t aOffset = -1,
template <typename EnableIfChar16 = IsChar16>
int32_t RFind(const self_type& aString, int32_t aOffset = -1,
int32_t aCount = -1) const;
int32_t RFind(const char16_t* aString, int32_t aOffset = -1,
template <typename EnableIfChar16 = IsChar16>
int32_t RFind(const char_type* aString, int32_t aOffset = -1,
int32_t aCount = -1) const;
#endif
/**
@ -221,15 +267,14 @@ public:
* @return offset in string, or kNotFound
*/
int32_t FindCharInSet(const char* aString, int32_t aOffset = 0) const;
int32_t FindCharInSet(const char_type* aString, int32_t aOffset = 0) const;
int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const
{
return FindCharInSet(aString.get(), aOffset);
}
#ifdef CharT_is_PRUnichar
int32_t FindCharInSet(const char16_t* aString, int32_t aOffset = 0) const;
#endif
template <typename EnableIfChar16 = IsChar16>
int32_t FindCharInSet(const char* aSet, int32_t aOffset = 0) const;
/**
@ -257,11 +302,9 @@ public:
* @param aCount tells us how many chars to compare
* @return -1,0,1
*/
#ifdef CharT_is_char
int32_t Compare(const char* aString, bool aIgnoreCase = false,
template <typename EnableIfChar = IsChar>
int32_t Compare(const char_type* aString, bool aIgnoreCase = false,
int32_t aCount = -1) const;
#endif
/**
@ -272,16 +315,14 @@ public:
* @param aCount tells us how many chars to compare
* @return boolean
*/
#ifdef CharT_is_char
bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const
template <typename EnableIfChar = IsChar>
bool EqualsIgnoreCase(const char_type* aString, int32_t aCount = -1) const
{
return Compare(aString, true, aCount) == 0;
}
#else
bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const;
#endif // !CharT_is_PRUnichar
template <typename EnableIfChar16 = IsChar16>
bool EqualsIgnoreCase(const incompatible_char_type* aString, int32_t aCount = -1) const;
/**
* Perform string to double-precision float conversion.
@ -297,11 +338,7 @@ public:
* @param aErrorCode will contain error if one occurs
* @return single-precision float rep of string value
*/
float ToFloat(nsresult* aErrorCode) const
{
return (float)ToDouble(aErrorCode);
}
float ToFloat(nsresult* aErrorCode) const;
/**
* Perform string to int conversion.
@ -337,7 +374,7 @@ public:
* aWritable = Substring(aReadable, 0, 17);
*/
size_type Mid(self_type& aResult, uint32_t aStartPos, uint32_t aCount) const;
size_type Mid(self_type& aResult, index_type aStartPos, size_type aCount) const;
size_type Left(self_type& aResult, size_type aCount) const
{
@ -346,8 +383,8 @@ public:
size_type Right(self_type& aResult, size_type aCount) const
{
aCount = XPCOM_MIN(mLength, aCount);
return Mid(aResult, mLength - aCount, aCount);
aCount = XPCOM_MIN(this->mLength, aCount);
return Mid(aResult, this->mLength - aCount, aCount);
}
@ -368,12 +405,13 @@ public:
*
* @param aSet -- characters to be cut from this
*/
#ifdef CharT_is_PRUnichar
using nsTSubstring_CharT::StripChars;
#endif
void StripChars(const char* aSet);
bool StripChars(const char* aSet, const fallible_t&);
void StripChars(const char_type* aSet);
template<typename EnableIfChar16 = IsChar16>
bool StripChars(const incompatible_char_type* aSet, const fallible_t&);
template<typename EnableIfChar16 = IsChar16>
void StripChars(const incompatible_char_type* aSet);
/**
* This method strips whitespace throughout the string.
@ -387,10 +425,11 @@ public:
*/
void ReplaceChar(char_type aOldChar, char_type aNewChar);
void ReplaceChar(const char* aSet, char_type aNewChar);
#ifdef CharT_is_PRUnichar
void ReplaceChar(const char16_t* aSet, char16_t aNewChar);
#endif
void ReplaceChar(const char_type* aSet, char_type aNewChar);
template<typename EnableIfChar16 = IsChar16>
void ReplaceChar(const char* aSet, char16_t aNewChar);
/**
* Replace all occurrences of aTarget with aNewValue.
* The complexity of this function is O(n+m), n being the length of the string
@ -444,9 +483,9 @@ public:
*/
void AssertValidDependentString()
{
NS_ASSERTION(mData, "nsTDependentString must wrap a non-NULL buffer");
NS_ASSERTION(mLength != size_type(-1), "nsTDependentString has bogus length");
NS_ASSERTION(mData[mLength] == 0,
NS_ASSERTION(this->mData, "nsTDependentString must wrap a non-NULL buffer");
NS_ASSERTION(this->mLength != size_type(-1), "nsTDependentString has bogus length");
NS_ASSERTION(this->mData[substring_type::mLength] == 0,
"nsTDependentString must wrap only null-terminated strings. "
"You are probably looking for nsTDependentSubstring.");
}
@ -455,17 +494,18 @@ public:
protected:
// allow subclasses to initialize fields directly
nsTString_CharT(char_type* aData, size_type aLength, DataFlags aDataFlags,
ClassFlags aClassFlags)
nsTString(char_type* aData, size_type aLength, DataFlags aDataFlags,
ClassFlags aClassFlags)
: substring_type(aData, aLength, aDataFlags,
aClassFlags | ClassFlags::NULL_TERMINATED)
{
}
friend const nsTString_CharT& TNullString_CharT();
friend const nsTString<char>& NullCString();
friend const nsTString<char16_t>& NullString();
// Used by Null[C]String.
explicit nsTString_CharT(DataFlags aDataFlags)
explicit nsTString(DataFlags aDataFlags)
: substring_type(char_traits::sEmptyBuffer, 0,
aDataFlags | DataFlags::TERMINATED,
ClassFlags::NULL_TERMINATED)
@ -480,13 +520,33 @@ protected:
};
};
// TODO(erahm): Do something with ToDouble so that we can extern the
// nsTString templates.
//extern template class nsTString<char>;
//extern template class nsTString<char16_t>;
class nsTFixedString_CharT : public nsTString_CharT
template <typename T>
class nsTFixedString : public nsTString<T>
{
public:
typedef nsTFixedString_CharT self_type;
typedef nsTFixedString_CharT fixed_string_type;
typedef nsTFixedString<T> self_type;
typedef nsTFixedString<T> fixed_string_type;
typedef nsTString<T> base_string_type;
typedef typename base_string_type::string_type string_type;
typedef typename base_string_type::char_type char_type;
typedef typename base_string_type::char_traits char_traits;
typedef typename base_string_type::substring_type substring_type;
typedef typename base_string_type::size_type size_type;
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
// These are only for internal use within the string classes:
typedef typename base_string_type::DataFlags DataFlags;
typedef typename base_string_type::ClassFlags ClassFlags;
using typename base_string_type::IsChar;
using typename base_string_type::IsChar16;
public:
@ -500,7 +560,7 @@ public:
* the length of the string already contained in the buffer
*/
nsTFixedString_CharT(char_type* aData, size_type aStorageSize)
nsTFixedString(char_type* aData, size_type aStorageSize)
: string_type(aData, uint32_t(char_traits::length(aData)),
DataFlags::TERMINATED | DataFlags::FIXED,
ClassFlags::FIXED)
@ -509,8 +569,8 @@ public:
{
}
nsTFixedString_CharT(char_type* aData, size_type aStorageSize,
size_type aLength)
nsTFixedString(char_type* aData, size_type aStorageSize,
size_type aLength)
: string_type(aData, aLength, DataFlags::TERMINATED | DataFlags::FIXED,
ClassFlags::FIXED)
, mFixedCapacity(aStorageSize - 1)
@ -523,52 +583,72 @@ public:
// |operator=| does not inherit, so we must define our own
self_type& operator=(char_type aChar)
{
Assign(aChar);
this->Assign(aChar);
return *this;
}
self_type& operator=(const char_type* aData)
{
Assign(aData);
this->Assign(aData);
return *this;
}
self_type& operator=(const substring_type& aStr)
{
Assign(aStr);
this->Assign(aStr);
return *this;
}
self_type& operator=(const substring_tuple_type& aTuple)
{
Assign(aTuple);
this->Assign(aTuple);
return *this;
}
protected:
friend class nsTSubstring_CharT;
friend class nsTSubstring<T>;
size_type mFixedCapacity;
char_type* mFixedBuf;
};
extern template class nsTFixedString<char>;
extern template class nsTFixedString<char>;
/**
* nsTAutoString_CharT
* nsTAutoStringN
*
* Subclass of nsTString_CharT that adds support for stack-based string
* Subclass of nsTString that adds support for stack-based string
* allocation. It is normally not a good idea to use this class on the
* heap, because it will allocate space which may be wasted if the string
* it contains is significantly smaller or any larger than 64 characters.
*
* NAMES:
* nsAutoStringN / nsAutoString for wide characters
* nsAutoCStringN / nsAutoCString for narrow characters
* nsAutoStringN / nsTAutoString for wide characters
* nsAutoCStringN / nsTAutoCString for narrow characters
*/
template<size_t N>
class MOZ_NON_MEMMOVABLE nsTAutoStringN_CharT : public nsTFixedString_CharT
template<typename T, size_t N>
class MOZ_NON_MEMMOVABLE nsTAutoStringN : public nsTFixedString<T>
{
public:
typedef nsTAutoStringN_CharT<N> self_type;
typedef nsTAutoStringN<T, N> self_type;
#ifdef __clang__
// bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
using typename nsTFixedString<T>::fixed_string_type;
#else
// On the other hand msvc chokes on the using statement. It seems others
// don't care either way so we lump them in here.
typedef typename nsTFixedString<T>::fixed_string_type fixed_string_type;
#endif
typedef typename fixed_string_type::char_type char_type;
typedef typename fixed_string_type::char_traits char_traits;
typedef typename fixed_string_type::substring_type substring_type;
typedef typename fixed_string_type::size_type size_type;
typedef typename fixed_string_type::substring_tuple_type substring_tuple_type;
using typename fixed_string_type::IsChar;
using typename fixed_string_type::IsChar16;
public:
@ -576,84 +656,85 @@ public:
* constructors
*/
nsTAutoStringN_CharT()
nsTAutoStringN()
: fixed_string_type(mStorage, N, 0)
{
}
explicit
nsTAutoStringN_CharT(char_type aChar)
nsTAutoStringN(char_type aChar)
: fixed_string_type(mStorage, N, 0)
{
Assign(aChar);
this->Assign(aChar);
}
explicit
nsTAutoStringN_CharT(const char_type* aData,
size_type aLength = size_type(-1))
nsTAutoStringN(const char_type* aData, size_type aLength = size_type(-1))
: fixed_string_type(mStorage, N, 0)
{
Assign(aData, aLength);
this->Assign(aData, aLength);
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
explicit
nsTAutoStringN_CharT(char16ptr_t aData, size_type aLength = size_type(-1))
: nsTAutoStringN_CharT(static_cast<const char16_t*>(aData), aLength)
nsTAutoStringN(char16ptr_t aData, size_type aLength = size_type(-1))
: nsTAutoStringN(static_cast<const char16_t*>(aData), aLength)
{
}
#endif
nsTAutoStringN_CharT(const self_type& aStr)
nsTAutoStringN(const self_type& aStr)
: fixed_string_type(mStorage, N, 0)
{
Assign(aStr);
this->Assign(aStr);
}
explicit
nsTAutoStringN_CharT(const substring_type& aStr)
nsTAutoStringN(const substring_type& aStr)
: fixed_string_type(mStorage, N, 0)
{
Assign(aStr);
this->Assign(aStr);
}
MOZ_IMPLICIT nsTAutoStringN_CharT(const substring_tuple_type& aTuple)
MOZ_IMPLICIT nsTAutoStringN(const substring_tuple_type& aTuple)
: fixed_string_type(mStorage, N, 0)
{
Assign(aTuple);
this->Assign(aTuple);
}
// |operator=| does not inherit, so we must define our own
self_type& operator=(char_type aChar)
{
Assign(aChar);
this->Assign(aChar);
return *this;
}
self_type& operator=(const char_type* aData)
{
Assign(aData);
this->Assign(aData);
return *this;
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
self_type& operator=(char16ptr_t aStr)
{
Assign(aStr);
this->Assign(aStr);
return *this;
}
#endif
self_type& operator=(const self_type& aStr)
{
Assign(aStr);
this->Assign(aStr);
return *this;
}
self_type& operator=(const substring_type& aStr)
{
Assign(aStr);
this->Assign(aStr);
return *this;
}
self_type& operator=(const substring_tuple_type& aTuple)
{
Assign(aTuple);
this->Assign(aTuple);
return *this;
}
@ -664,9 +745,9 @@ private:
char_type mStorage[N];
};
// We define this typedef instead of providing a default value for N so that so
// there is a default typename that doesn't require angle brackets.
using nsTAutoString_CharT = nsTAutoStringN_CharT<AutoStringDefaultStorageSize>;
// Externs for the most common nsTAutoStringN variations.
extern template class nsTAutoStringN<char, 64>;
extern template class nsTAutoStringN<char16_t, 64>;
//
// nsAutoString stores pointers into itself which are invalidated when an
@ -674,26 +755,26 @@ using nsTAutoString_CharT = nsTAutoStringN_CharT<AutoStringDefaultStorageSize>;
// elements!
//
template<class E> class nsTArrayElementTraits;
template<>
class nsTArrayElementTraits<nsTAutoString_CharT>
template<typename T>
class nsTArrayElementTraits<nsTAutoString<T>>
{
public:
template<class A> struct Dont_Instantiate_nsTArray_of;
template<class A> struct Instead_Use_nsTArray_of;
static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE)
static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE)
{
return 0;
}
template<class A>
static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE, const A& aArg)
static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE, const A& aArg)
{
return 0;
}
static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
Destruct(Instead_Use_nsTArray_of<nsTString_CharT>* aE)
static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
Destruct(Instead_Use_nsTArray_of<nsTString<T>>* aE)
{
return 0;
}
@ -727,18 +808,19 @@ public:
* // ...
* }
*/
class MOZ_STACK_CLASS nsTGetterCopies_CharT
template <typename T>
class MOZ_STACK_CLASS nsTGetterCopies
{
public:
typedef CharT char_type;
typedef T char_type;
explicit nsTGetterCopies_CharT(nsTSubstring_CharT& aStr)
explicit nsTGetterCopies(nsTSubstring<T>& aStr)
: mString(aStr)
, mData(nullptr)
{
}
~nsTGetterCopies_CharT()
~nsTGetterCopies()
{
mString.Adopt(mData); // OK if mData is null
}
@ -749,14 +831,16 @@ public:
}
private:
nsTSubstring_CharT& mString;
nsTSubstring<T>& mString;
char_type* mData;
};
// See the comment above nsTGetterCopies_CharT for how to use this.
inline nsTGetterCopies_CharT
getter_Copies(nsTSubstring_CharT& aString)
template <typename T>
inline nsTGetterCopies<T>
getter_Copies(nsTSubstring<T>& aString)
{
return nsTGetterCopies_CharT(aString);
return nsTGetterCopies<T>(aString);
}
#endif

Просмотреть файл

@ -4,18 +4,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
template <typename T>
int NS_FASTCALL
Compare(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs,
const nsTStringComparator_CharT& comp)
Compare(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs,
const nsTStringComparator<T>& comp)
{
typedef nsTSubstring_CharT::size_type size_type;
typedef typename nsTSubstring<T>::size_type size_type;
typedef typename nsTSubstring<T>::const_iterator const_iterator;
if (&aLhs == &aRhs) {
return 0;
}
nsTSubstring_CharT::const_iterator leftIter, rightIter;
const_iterator leftIter, rightIter;
aLhs.BeginReading(leftIter);
aRhs.BeginReading(rightIter);
@ -38,13 +40,14 @@ Compare(const nsTSubstring_CharT::base_string_type& aLhs,
return result;
}
template <typename T>
int
nsTDefaultStringComparator_CharT::operator()(const char_type* aLhs,
const char_type* aRhs,
uint32_t aLLength,
uint32_t aRLength) const
nsTDefaultStringComparator<T>::operator()(const char_type* aLhs,
const char_type* aRhs,
uint32_t aLLength,
uint32_t aRLength) const
{
return
aLLength == aRLength ? nsCharTraits<CharT>::compare(aLhs, aRhs, aLLength) :
aLLength == aRLength ? nsCharTraits<T>::compare(aLhs, aRhs, aLLength) :
(aLLength > aRLength) ? 1 : -1;
}

Просмотреть файл

@ -14,23 +14,24 @@
* aOffset specifies starting index
* aCount specifies number of string compares (iterations)
*/
template <typename T>
int32_t
nsTString_CharT::Find( const nsCString& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
nsTString<T>::Find(const nsTString<char>& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
{
// this method changes the meaning of aOffset and aCount:
Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
int32_t result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
int32_t result = FindSubstring(this->mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
if (result != kNotFound)
result += aOffset;
return result;
}
template <typename T>
int32_t
nsTString_CharT::Find( const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
nsTString<T>::Find(const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
{
return Find(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
return Find(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
}
@ -40,34 +41,35 @@ nsTString_CharT::Find( const char* aString, bool aIgnoreCase, int32_t aOffset, i
* aOffset specifies starting index
* aCount specifies number of string compares (iterations)
*/
template <typename T>
int32_t
nsTString_CharT::RFind( const nsCString& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
nsTString<T>::RFind(const nsTString<char>& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
{
// this method changes the meaning of aOffset and aCount:
RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
RFind_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
int32_t result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
int32_t result = RFindSubstring(this->mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
if (result != kNotFound)
result += aOffset;
return result;
}
template <typename T>
int32_t
nsTString_CharT::RFind( const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
nsTString<T>::RFind(const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
{
return RFind(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
return RFind(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
}
/**
* nsTString::RFindChar
*/
template <typename T>
int32_t
nsTString_CharT::RFindChar( char16_t aChar, int32_t aOffset, int32_t aCount) const
nsTString<T>::RFindChar(char16_t aChar, int32_t aOffset, int32_t aCount) const
{
return nsBufferRoutines<CharT>::rfind_char(mData, mLength, aOffset, aChar, aCount);
return nsBufferRoutines<T>::rfind_char(this->mData, this->mLength, aOffset, aChar, aCount);
}
@ -75,15 +77,16 @@ nsTString_CharT::RFindChar( char16_t aChar, int32_t aOffset, int32_t aCount) con
* nsTString::FindCharInSet
*/
template <typename T>
int32_t
nsTString_CharT::FindCharInSet( const char* aSet, int32_t aOffset ) const
nsTString<T>::FindCharInSet(const char_type* aSet, int32_t aOffset) const
{
if (aOffset < 0)
aOffset = 0;
else if (aOffset >= int32_t(mLength))
else if (aOffset >= int32_t(this->mLength))
return kNotFound;
int32_t result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet);
if (result != kNotFound)
result += aOffset;
return result;
@ -94,30 +97,32 @@ nsTString_CharT::FindCharInSet( const char* aSet, int32_t aOffset ) const
* nsTString::RFindCharInSet
*/
template <typename T>
int32_t
nsTString_CharT::RFindCharInSet( const CharT* aSet, int32_t aOffset ) const
nsTString<T>::RFindCharInSet(const char_type* aSet, int32_t aOffset) const
{
// We want to pass a "data length" to ::RFindCharInSet
if (aOffset < 0 || aOffset > int32_t(mLength))
aOffset = mLength;
if (aOffset < 0 || aOffset > int32_t(this->mLength))
aOffset = this->mLength;
else
++aOffset;
return ::RFindCharInSet(mData, aOffset, aSet);
return ::RFindCharInSet(this->mData, aOffset, aSet);
}
// it's a shame to replicate this code. it was done this way in the past
// to help performance. this function also gets to keep the rickg style
// indentation :-/
template <typename T>
int32_t
nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
nsTString<T>::ToInteger(nsresult* aErrorCode, uint32_t aRadix) const
{
CharT* cp=mData;
int32_t theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
int32_t result=0;
bool negate=false;
CharT theChar=0;
char_type* cp = this->mData;
int32_t theRadix = 10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
int32_t result = 0;
bool negate = false;
char_type theChar = 0;
//initial value, override if we find an integer
*aErrorCode=NS_ERROR_ILLEGAL_VALUE;
@ -126,8 +131,8 @@ nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
//begin by skipping over leading chars that shouldn't be part of the number...
CharT* endcp=cp+mLength;
bool done=false;
char_type* endcp=cp+this->mLength;
bool done=false;
while((cp<endcp) && (!done)){
switch(*cp++) {
@ -159,7 +164,7 @@ nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
if (aRadix!=kAutoDetect) theRadix = aRadix; // override
//now iterate the numeric chars and build our result
CharT* first=--cp; //in case we have to back up.
char_type* first=--cp; //in case we have to back up.
bool haveValue = false;
while(cp<endcp){
@ -237,14 +242,15 @@ nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
/**
* nsTString::ToInteger64
*/
template <typename T>
int64_t
nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
nsTString<T>::ToInteger64(nsresult* aErrorCode, uint32_t aRadix) const
{
CharT* cp=mData;
char_type* cp=this->mData;
int32_t theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
int64_t result=0;
bool negate=false;
CharT theChar=0;
bool negate=false;
char_type theChar=0;
//initial value, override if we find an integer
*aErrorCode=NS_ERROR_ILLEGAL_VALUE;
@ -253,8 +259,8 @@ nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
//begin by skipping over leading chars that shouldn't be part of the number...
CharT* endcp=cp+mLength;
bool done=false;
char_type* endcp=cp+this->mLength;
bool done=false;
while((cp<endcp) && (!done)){
switch(*cp++) {
@ -286,7 +292,7 @@ nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
if (aRadix!=kAutoDetect) theRadix = aRadix; // override
//now iterate the numeric chars and build our result
CharT* first=--cp; //in case we have to back up.
char_type* first=--cp; //in case we have to back up.
bool haveValue = false;
while(cp<endcp){
@ -365,10 +371,11 @@ nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
* nsTString::Mid
*/
uint32_t
nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
template <typename T>
typename nsTString<T>::size_type
nsTString<T>::Mid(self_type& aResult, index_type aStartPos, size_type aLengthToCopy) const
{
if (aStartPos == 0 && aLengthToCopy >= mLength)
if (aStartPos == 0 && aLengthToCopy >= this->mLength)
aResult = *this;
else
aResult = Substring(*this, aStartPos, aLengthToCopy);
@ -381,16 +388,17 @@ nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengt
* nsTString::SetCharAt
*/
template <typename T>
bool
nsTString_CharT::SetCharAt( char16_t aChar, uint32_t aIndex )
nsTString<T>::SetCharAt(char16_t aChar, uint32_t aIndex)
{
if (aIndex >= mLength)
if (aIndex >= this->mLength)
return false;
if (!EnsureMutable())
AllocFailed(mLength);
if (!this->EnsureMutable())
this->AllocFailed(this->mLength);
mData[aIndex] = CharT(aChar);
this->mData[aIndex] = char_type(aChar);
return true;
}
@ -399,41 +407,54 @@ nsTString_CharT::SetCharAt( char16_t aChar, uint32_t aIndex )
* nsTString::StripChars,StripChar,StripWhitespace
*/
template<typename T>
template<typename EnableIfChar16>
void
nsTString_CharT::StripChars( const char* aSet )
nsTString<T>::StripChars(const incompatible_char_type* aSet)
{
if (!StripChars(aSet, mozilla::fallible)) {
AllocFailed(mLength);
this->AllocFailed(this->mLength);
}
}
template<typename T>
template<typename EnableIfChar16>
bool
nsTString_CharT::StripChars( const char* aSet, const fallible_t& )
nsTString<T>::StripChars(const incompatible_char_type* aSet, const fallible_t&)
{
if (!EnsureMutable()) {
if (!this->EnsureMutable()) {
return false;
}
mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
this->mLength = nsBufferRoutines<T>::strip_chars(this->mData, this->mLength, aSet);
return true;
}
template<typename T>
void
nsTString_CharT::StripWhitespace()
nsTString<T>::StripChars(const char_type* aSet)
{
nsTSubstring<T>::StripChars(aSet);
}
template <typename T>
void
nsTString<T>::StripWhitespace()
{
if (!StripWhitespace(mozilla::fallible)) {
AllocFailed(mLength);
this->AllocFailed(this->mLength);
}
}
template <typename T>
bool
nsTString_CharT::StripWhitespace( const fallible_t& )
nsTString<T>::StripWhitespace(const fallible_t&)
{
if (!EnsureMutable()) {
if (!this->EnsureMutable()) {
return false;
}
StripTaggedASCII(mozilla::ASCIIMask::MaskWhitespace());
this->StripTaggedASCII(mozilla::ASCIIMask::MaskWhitespace());
return true;
}
@ -441,27 +462,29 @@ nsTString_CharT::StripWhitespace( const fallible_t& )
* nsTString::ReplaceChar,ReplaceSubstring
*/
template <typename T>
void
nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
nsTString<T>::ReplaceChar(char_type aOldChar, char_type aNewChar)
{
if (!EnsureMutable()) // XXX do this lazily?
AllocFailed(mLength);
if (!this->EnsureMutable()) // XXX do this lazily?
this->AllocFailed(this->mLength);
for (uint32_t i=0; i<mLength; ++i)
for (uint32_t i=0; i<this->mLength; ++i)
{
if (mData[i] == aOldChar)
mData[i] = aNewChar;
if (this->mData[i] == aOldChar)
this->mData[i] = aNewChar;
}
}
template <typename T>
void
nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
nsTString<T>::ReplaceChar(const char_type* aSet, char_type aNewChar)
{
if (!EnsureMutable()) // XXX do this lazily?
AllocFailed(mLength);
if (!this->EnsureMutable()) // XXX do this lazily?
this->AllocFailed(this->mLength);
char_type* data = mData;
uint32_t lenRemaining = mLength;
char_type* data = this->mData;
uint32_t lenRemaining = this->mLength;
while (lenRemaining)
{
@ -477,39 +500,43 @@ nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
void ReleaseData(void* aData, nsAString::DataFlags aFlags);
template <typename T>
void
nsTString_CharT::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue)
nsTString<T>::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue)
{
ReplaceSubstring(nsTDependentString_CharT(aTarget),
nsTDependentString_CharT(aNewValue));
ReplaceSubstring(nsTDependentString<T>(aTarget),
nsTDependentString<T>(aNewValue));
}
template <typename T>
bool
nsTString_CharT::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue,
const fallible_t& aFallible)
nsTString<T>::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue,
const fallible_t& aFallible)
{
return ReplaceSubstring(nsTDependentString_CharT(aTarget),
nsTDependentString_CharT(aNewValue),
return ReplaceSubstring(nsTDependentString<T>(aTarget),
nsTDependentString<T>(aNewValue),
aFallible);
}
template <typename T>
void
nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue)
nsTString<T>::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue)
{
if (!ReplaceSubstring(aTarget, aNewValue, mozilla::fallible)) {
// Note that this may wildly underestimate the allocation that failed, as
// we could have been replacing multiple copies of aTarget.
AllocFailed(mLength + (aNewValue.Length() - aTarget.Length()));
this->AllocFailed(this->mLength + (aNewValue.Length() - aTarget.Length()));
}
}
template <typename T>
bool
nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue,
const fallible_t&)
nsTString<T>::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue,
const fallible_t&)
{
if (aTarget.Length() == 0)
return true;
@ -520,8 +547,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
mozilla::CheckedUint32 newLength;
while (true)
{
int32_t r = FindSubstring(mData + i, mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
int32_t until = (r == kNotFound) ? mLength - i : r;
int32_t r = FindSubstring(this->mData + i, this->mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
int32_t until = (r == kNotFound) ? this->mLength - i : r;
nonMatching.AppendElement(Segment(i, until));
newLength += until;
if (r == kNotFound) {
@ -530,10 +557,10 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
newLength += aNewValue.Length();
i += r + aTarget.Length();
if (i >= mLength) {
if (i >= this->mLength) {
// Add an auxiliary entry at the end of the list to help as an edge case
// for the algorithms below.
nonMatching.AppendElement(Segment(mLength, 0));
nonMatching.AppendElement(Segment(this->mLength, 0));
break;
}
}
@ -545,22 +572,22 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
// If there's only one non-matching segment, then the target string was not
// found, and there's nothing to do.
if (nonMatching.Length() == 1) {
MOZ_ASSERT(nonMatching[0].mBegin == 0 && nonMatching[0].mLength == mLength,
MOZ_ASSERT(nonMatching[0].mBegin == 0 && nonMatching[0].mLength == this->mLength,
"We should have the correct non-matching segment.");
return true;
}
// Make sure that we can mutate our buffer.
// Note that we always allocate at least an mLength sized buffer, because the
// Note that we always allocate at least an this->mLength sized buffer, because the
// rest of the algorithm relies on having access to all of the original
// string. In other words, we over-allocate in the shrinking case.
char_type* oldData;
DataFlags oldFlags;
if (!MutatePrep(XPCOM_MAX(mLength, newLength.value()), &oldData, &oldFlags))
if (!this->MutatePrep(XPCOM_MAX(this->mLength, newLength.value()), &oldData, &oldFlags))
return false;
if (oldData) {
// Copy all of the old data to the new buffer.
char_traits::copy(mData, oldData, mLength);
char_traits::copy(this->mData, oldData, this->mLength);
::ReleaseData(oldData, oldFlags);
}
@ -571,8 +598,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
// When we move the i'th non-matching segment into position, we need to
// account for the characters deleted by the previous |i| replacements by
// subtracting |i * delta|.
const char_type* sourceSegmentPtr = mData + nonMatching[i].mBegin;
char_type* destinationSegmentPtr = mData + nonMatching[i].mBegin - i * delta;
const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin - i * delta;
// Write the i'th replacement immediately before the new i'th non-matching
// segment.
char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
@ -587,8 +614,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
// When we move the i'th non-matching segment into position, we need to
// account for the characters added by the previous |i| replacements by
// adding |i * delta|.
const char_type* sourceSegmentPtr = mData + nonMatching[i].mBegin;
char_type* destinationSegmentPtr = mData + nonMatching[i].mBegin + i * delta;
const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin + i * delta;
char_traits::move(destinationSegmentPtr, sourceSegmentPtr,
nonMatching[i].mLength);
// Write the i'th replacement immediately before the new i'th non-matching
@ -599,8 +626,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
}
// Adjust the length and make sure the string is null terminated.
mLength = newLength.value();
mData[mLength] = char_type(0);
this->mLength = newLength.value();
this->mData[this->mLength] = char_type(0);
return true;
}
@ -609,19 +636,20 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
* nsTString::Trim
*/
template <typename T>
void
nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing, bool aIgnoreQuotes )
nsTString<T>::Trim(const char* aSet, bool aTrimLeading, bool aTrimTrailing, bool aIgnoreQuotes)
{
// the old implementation worried about aSet being null :-/
if (!aSet)
return;
char_type* start = mData;
char_type* end = mData + mLength;
char_type* start = this->mData;
char_type* end = this->mData + this->mLength;
// skip over quotes if requested
if (aIgnoreQuotes && mLength > 2 && mData[0] == mData[mLength - 1] &&
(mData[0] == '\'' || mData[0] == '"'))
if (aIgnoreQuotes && this->mLength > 2 && this->mData[0] == this->mData[this->mLength - 1] &&
(this->mData[0] == '\'' || this->mData[0] == '"'))
{
++start;
--end;
@ -631,7 +659,7 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
if (aTrimLeading)
{
uint32_t cutStart = start - mData;
uint32_t cutStart = start - this->mData;
uint32_t cutLength = 0;
// walk forward from start to end
@ -644,17 +672,17 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
if (cutLength)
{
Cut(cutStart, cutLength);
this->Cut(cutStart, cutLength);
// reset iterators
start = mData + cutStart;
end = mData + mLength - cutStart;
start = this->mData + cutStart;
end = this->mData + this->mLength - cutStart;
}
}
if (aTrimTrailing)
{
uint32_t cutEnd = end - mData;
uint32_t cutEnd = end - this->mData;
uint32_t cutLength = 0;
// walk backward from end to start
@ -667,7 +695,7 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
}
if (cutLength)
Cut(cutEnd - cutLength, cutLength);
this->Cut(cutEnd - cutLength, cutLength);
}
}
@ -676,22 +704,23 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
* nsTString::CompressWhitespace.
*/
template <typename T>
void
nsTString_CharT::CompressWhitespace( bool aTrimLeading, bool aTrimTrailing )
nsTString<T>::CompressWhitespace(bool aTrimLeading, bool aTrimTrailing)
{
// Quick exit
if (mLength == 0) {
if (this->mLength == 0) {
return;
}
if (!EnsureMutable())
AllocFailed(mLength);
if (!this->EnsureMutable())
this->AllocFailed(this->mLength);
const ASCIIMaskArray& mask = mozilla::ASCIIMask::MaskWhitespace();
char_type* to = mData;
char_type* from = mData;
char_type* end = mData + mLength;
char_type* to = this->mData;
char_type* from = this->mData;
char_type* end = this->mData + this->mLength;
// Compresses runs of whitespace down to a normal space ' ' and convert
// any whitespace to a normal space. This assumes that whitespace is
@ -711,10 +740,10 @@ nsTString_CharT::CompressWhitespace( bool aTrimLeading, bool aTrimTrailing )
}
// If we need to trim the trailing whitespace, back up one character.
if (aTrimTrailing && skipWS && to > mData) {
if (aTrimTrailing && skipWS && to > this->mData) {
to--;
}
*to = char_type(0); // add the null
mLength = to - mData;
this->mLength = to - this->mData;
}

Просмотреть файл

@ -0,0 +1,374 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsTStringRepr_h
#define nsTStringRepr_h
#include <type_traits> // std::enable_if
#include "nsStringFlags.h"
#include "nsCharTraits.h"
template <typename T> class nsTSubstringTuple;
// The base for string comparators
template <typename T> class nsTStringComparator
{
public:
typedef T char_type;
nsTStringComparator() {}
virtual int operator()(const char_type*, const char_type*,
uint32_t, uint32_t) const = 0;
};
// The default string comparator (case-sensitive comparision)
template <typename T> class nsTDefaultStringComparator
: public nsTStringComparator<T>
{
public:
typedef T char_type;
nsTDefaultStringComparator() {}
virtual int operator()(const char_type*, const char_type*,
uint32_t, uint32_t) const override;
};
extern template class nsTDefaultStringComparator<char>;
extern template class nsTDefaultStringComparator<char16_t>;
namespace mozilla {
namespace detail {
// nsTStringRepr defines a string's memory layout and some accessor methods.
// This class exists so that nsTLiteralString can avoid inheriting
// nsTSubstring's destructor. All methods on this class must be const because
// literal strings are not writable.
//
// This class is an implementation detail and should not be instantiated
// directly, nor used in any way outside of the string code itself. It is
// buried in a namespace to discourage its use in function parameters.
// If you need to take a parameter, use [const] ns[C]Substring&.
// If you need to instantiate a string, use ns[C]String or descendents.
//
// NAMES:
// nsStringRepr for wide characters
// nsCStringRepr for narrow characters
template <typename T> class nsTStringRepr
{
public:
typedef mozilla::fallible_t fallible_t;
typedef T char_type;
typedef nsCharTraits<char_type> char_traits;
typedef typename char_traits::incompatible_char_type incompatible_char_type;
typedef nsTStringRepr<T> self_type;
typedef self_type base_string_type;
typedef nsTSubstring<T> substring_type;
typedef nsTSubstringTuple<T> substring_tuple_type;
typedef nsReadingIterator<char_type> const_iterator;
typedef nsWritingIterator<char_type> iterator;
typedef nsTStringComparator<char_type> comparator_type;
typedef char_type* char_iterator;
typedef const char_type* const_char_iterator;
typedef uint32_t index_type;
typedef uint32_t size_type;
// These are only for internal use within the string classes:
typedef StringDataFlags DataFlags;
typedef StringClassFlags ClassFlags;
// These are used to conditionally enable functions for specific character
// types.
using IsChar = std::enable_if<std::is_same<char, T>::value>;
using IsChar16 = std::enable_if<std::is_same<char16_t, T>::value>;
// Reading iterators.
const_char_iterator BeginReading() const
{
return mData;
}
const_char_iterator EndReading() const
{
return mData + mLength;
}
// Deprecated reading iterators.
const_iterator& BeginReading(const_iterator& aIter) const
{
aIter.mStart = mData;
aIter.mEnd = mData + mLength;
aIter.mPosition = aIter.mStart;
return aIter;
}
const_iterator& EndReading(const_iterator& aIter) const
{
aIter.mStart = mData;
aIter.mEnd = mData + mLength;
aIter.mPosition = aIter.mEnd;
return aIter;
}
const_char_iterator& BeginReading(const_char_iterator& aIter) const
{
return aIter = mData;
}
const_char_iterator& EndReading(const_char_iterator& aIter) const
{
return aIter = mData + mLength;
}
// Accessors.
template <typename U> struct raw_type { typedef const U* type; };
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <> struct raw_type<char16_t> { typedef char16ptr_t type; };
#endif
// Returns pointer to string data (not necessarily null-terminated)
const typename raw_type<T>::type Data() const
{
return mData;
}
size_type Length() const
{
return mLength;
}
DataFlags GetDataFlags() const
{
return mDataFlags;
}
bool IsEmpty() const
{
return mLength == 0;
}
bool IsLiteral() const
{
return !!(mDataFlags & DataFlags::LITERAL);
}
bool IsVoid() const
{
return !!(mDataFlags & DataFlags::VOIDED);
}
bool IsTerminated() const
{
return !!(mDataFlags & DataFlags::TERMINATED);
}
char_type CharAt(index_type aIndex) const
{
NS_ASSERTION(aIndex < mLength, "index exceeds allowable range");
return mData[aIndex];
}
char_type operator[](index_type aIndex) const
{
return CharAt(aIndex);
}
char_type First() const;
char_type Last() const;
size_type NS_FASTCALL CountChar(char_type) const;
int32_t NS_FASTCALL FindChar(char_type, index_type aOffset = 0) const;
inline bool Contains(char_type aChar) const
{
return FindChar(aChar) != kNotFound;
}
// Equality.
bool NS_FASTCALL Equals(const self_type&) const;
bool NS_FASTCALL Equals(const self_type&, const comparator_type&) const;
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple) const;
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple,
const comparator_type& aComp) const;
bool NS_FASTCALL Equals(const char_type* aData) const;
bool NS_FASTCALL Equals(const char_type* aData,
const comparator_type& aComp) const;
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
bool NS_FASTCALL Equals(char16ptr_t aData) const
{
return Equals(static_cast<const char16_t*>(aData));
}
template <typename EnableIfChar16 = IsChar16>
bool NS_FASTCALL Equals(char16ptr_t aData, const comparator_type& aComp) const
{
return Equals(static_cast<const char16_t*>(aData), aComp);
}
#endif
// An efficient comparison with ASCII that can be used even
// for wide strings. Call this version when you know the
// length of 'data'.
bool NS_FASTCALL EqualsASCII(const char* aData, size_type aLen) const;
// An efficient comparison with ASCII that can be used even
// for wide strings. Call this version when 'data' is
// null-terminated.
bool NS_FASTCALL EqualsASCII(const char* aData) const;
// EqualsLiteral must ONLY be applied to an actual literal string, or
// a char array *constant* declared without an explicit size.
// Do not attempt to use it with a regular char* pointer, or with a
// non-constant char array variable. Use EqualsASCII for them.
// The template trick to acquire the array length at compile time without
// using a macro is due to Corey Kosak, with much thanks.
template<int N>
inline bool EqualsLiteral(const char (&aStr)[N]) const
{
return EqualsASCII(aStr, N - 1);
}
// The LowerCaseEquals methods compare the ASCII-lowercase version of
// this string (lowercasing only ASCII uppercase characters) to some
// ASCII/Literal string. The ASCII string is *not* lowercased for
// you. If you compare to an ASCII or literal string that contains an
// uppercase character, it is guaranteed to return false. We will
// throw assertions too.
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData,
size_type aLen) const;
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData) const;
// LowerCaseEqualsLiteral must ONLY be applied to an actual
// literal string, or a char array *constant* declared without an
// explicit size. Do not attempt to use it with a regular char*
// pointer, or with a non-constant char array variable. Use
// LowerCaseEqualsASCII for them.
template<int N>
bool LowerCaseEqualsLiteral(const char (&aStr)[N]) const
{
return LowerCaseEqualsASCII(aStr, N - 1);
}
// Returns true if this string overlaps with the given string fragment.
bool IsDependentOn(const char_type* aStart, const char_type* aEnd) const
{
// If it _isn't_ the case that one fragment starts after the other ends,
// or ends before the other starts, then, they conflict:
//
// !(f2.begin >= f1.aEnd || f2.aEnd <= f1.begin)
//
// Simplified, that gives us:
return (aStart < (mData + mLength) && aEnd > mData);
}
protected:
nsTStringRepr() = delete; // Never instantiate directly
constexpr
nsTStringRepr(char_type* aData, size_type aLength,
DataFlags aDataFlags, ClassFlags aClassFlags)
: mData(aData)
, mLength(aLength)
, mDataFlags(aDataFlags)
, mClassFlags(aClassFlags)
{
}
char_type* mData;
size_type mLength;
DataFlags mDataFlags;
ClassFlags const mClassFlags;
};
extern template class nsTStringRepr<char>;
extern template class nsTStringRepr<char16_t>;
} // namespace detail
} // namespace mozilla
template <typename T>
int NS_FASTCALL
Compare(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs,
const nsTStringComparator<T>& = nsTDefaultStringComparator<T>());
template <typename T>
inline bool
operator!=(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs)
{
return !aLhs.Equals(aRhs);
}
template <typename T>
inline bool
operator!=(const mozilla::detail::nsTStringRepr<T>& aLhs,
const T* aRhs)
{
return !aLhs.Equals(aRhs);
}
template <typename T>
inline bool
operator<(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs)
{
return Compare(aLhs, aRhs) < 0;
}
template <typename T>
inline bool
operator<=(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs)
{
return Compare(aLhs, aRhs) <= 0;
}
template <typename T>
inline bool
operator==(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs)
{
return aLhs.Equals(aRhs);
}
template <typename T>
inline bool
operator==(const mozilla::detail::nsTStringRepr<T>& aLhs,
const T* aRhs)
{
return aLhs.Equals(aRhs);
}
template <typename T>
inline bool
operator>=(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs)
{
return Compare(aLhs, aRhs) >= 0;
}
template <typename T>
inline bool
operator>(const mozilla::detail::nsTStringRepr<T>& aLhs,
const mozilla::detail::nsTStringRepr<T>& aRhs)
{
return Compare(aLhs, aRhs) > 0;
}
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -5,6 +5,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#ifndef nsTSubstring_h
#define nsTSubstring_h
#include "mozilla/Casting.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/UniquePtr.h"
@ -12,317 +15,14 @@
#include "mozilla/IntegerTypeTraits.h"
#include "mozilla/Span.h"
#include "nsTStringRepr.h"
#ifndef MOZILLA_INTERNAL_API
#error "Using XPCOM strings is limited to code linked into libxul."
#endif
/**
* The base for string comparators
*/
class nsTStringComparator_CharT
{
public:
typedef CharT char_type;
nsTStringComparator_CharT()
{
}
virtual int operator()(const char_type*, const char_type*,
uint32_t, uint32_t) const = 0;
};
/**
* The default string comparator (case-sensitive comparision)
*/
class nsTDefaultStringComparator_CharT
: public nsTStringComparator_CharT
{
public:
typedef CharT char_type;
nsTDefaultStringComparator_CharT()
{
}
virtual int operator()(const char_type*, const char_type*,
uint32_t, uint32_t) const override;
};
class nsTSubstringSplitter_CharT;
namespace mozilla {
namespace detail {
/**
* nsTStringRepr defines a string's memory layout and some accessor methods.
* This class exists so that nsTLiteralString can avoid inheriting
* nsTSubstring's destructor. All methods on this class must be const because
* literal strings are not writable.
*
* This class is an implementation detail and should not be instantiated
* directly, nor used in any way outside of the string code itself. It is
* buried in a namespace to discourage its use in function parameters.
* If you need to take a parameter, use [const] ns[C]Substring&.
* If you need to instantiate a string, use ns[C]String or descendents.
*
* NAMES:
* nsStringRepr for wide characters
* nsCStringRepr for narrow characters
*
*/
class nsTStringRepr_CharT
{
public:
typedef mozilla::fallible_t fallible_t;
typedef CharT char_type;
typedef nsCharTraits<char_type> char_traits;
typedef char_traits::incompatible_char_type incompatible_char_type;
typedef nsTStringRepr_CharT self_type;
typedef self_type base_string_type;
typedef nsTSubstring_CharT substring_type;
typedef nsTSubstringTuple_CharT substring_tuple_type;
typedef nsTString_CharT string_type;
typedef nsReadingIterator<char_type> const_iterator;
typedef nsWritingIterator<char_type> iterator;
typedef nsTStringComparator_CharT comparator_type;
typedef char_type* char_iterator;
typedef const char_type* const_char_iterator;
typedef uint32_t index_type;
typedef uint32_t size_type;
// These are only for internal use within the string classes:
typedef StringDataFlags DataFlags;
typedef StringClassFlags ClassFlags;
/**
* reading iterators
*/
const_char_iterator BeginReading() const
{
return mData;
}
const_char_iterator EndReading() const
{
return mData + mLength;
}
/**
* deprecated reading iterators
*/
const_iterator& BeginReading(const_iterator& aIter) const
{
aIter.mStart = mData;
aIter.mEnd = mData + mLength;
aIter.mPosition = aIter.mStart;
return aIter;
}
const_iterator& EndReading(const_iterator& aIter) const
{
aIter.mStart = mData;
aIter.mEnd = mData + mLength;
aIter.mPosition = aIter.mEnd;
return aIter;
}
const_char_iterator& BeginReading(const_char_iterator& aIter) const
{
return aIter = mData;
}
const_char_iterator& EndReading(const_char_iterator& aIter) const
{
return aIter = mData + mLength;
}
/**
* accessors
*/
// returns pointer to string data (not necessarily null-terminated)
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
char16ptr_t Data() const
#else
const char_type* Data() const
#endif
{
return mData;
}
size_type Length() const
{
return mLength;
}
DataFlags GetDataFlags() const
{
return mDataFlags;
}
bool IsEmpty() const
{
return mLength == 0;
}
bool IsLiteral() const
{
return !!(mDataFlags & DataFlags::LITERAL);
}
bool IsVoid() const
{
return !!(mDataFlags & DataFlags::VOIDED);
}
bool IsTerminated() const
{
return !!(mDataFlags & DataFlags::TERMINATED);
}
char_type CharAt(index_type aIndex) const
{
NS_ASSERTION(aIndex < mLength, "index exceeds allowable range");
return mData[aIndex];
}
char_type operator[](index_type aIndex) const
{
return CharAt(aIndex);
}
char_type First() const;
char_type Last() const;
size_type NS_FASTCALL CountChar(char_type) const;
int32_t NS_FASTCALL FindChar(char_type, index_type aOffset = 0) const;
inline bool Contains(char_type aChar) const
{
return FindChar(aChar) != kNotFound;
}
/**
* equality
*/
bool NS_FASTCALL Equals(const self_type&) const;
bool NS_FASTCALL Equals(const self_type&, const comparator_type&) const;
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple) const;
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple,
const comparator_type& aComp) const;
bool NS_FASTCALL Equals(const char_type* aData) const;
bool NS_FASTCALL Equals(const char_type* aData,
const comparator_type& aComp) const;
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
bool NS_FASTCALL Equals(char16ptr_t aData) const
{
return Equals(static_cast<const char16_t*>(aData));
}
bool NS_FASTCALL Equals(char16ptr_t aData, const comparator_type& aComp) const
{
return Equals(static_cast<const char16_t*>(aData), aComp);
}
#endif
/**
* An efficient comparison with ASCII that can be used even
* for wide strings. Call this version when you know the
* length of 'data'.
*/
bool NS_FASTCALL EqualsASCII(const char* aData, size_type aLen) const;
/**
* An efficient comparison with ASCII that can be used even
* for wide strings. Call this version when 'data' is
* null-terminated.
*/
bool NS_FASTCALL EqualsASCII(const char* aData) const;
// EqualsLiteral must ONLY be applied to an actual literal string, or
// a char array *constant* declared without an explicit size.
// Do not attempt to use it with a regular char* pointer, or with a
// non-constant char array variable. Use EqualsASCII for them.
// The template trick to acquire the array length at compile time without
// using a macro is due to Corey Kosak, with much thanks.
template<int N>
inline bool EqualsLiteral(const char (&aStr)[N]) const
{
return EqualsASCII(aStr, N - 1);
}
// The LowerCaseEquals methods compare the ASCII-lowercase version of
// this string (lowercasing only ASCII uppercase characters) to some
// ASCII/Literal string. The ASCII string is *not* lowercased for
// you. If you compare to an ASCII or literal string that contains an
// uppercase character, it is guaranteed to return false. We will
// throw assertions too.
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData,
size_type aLen) const;
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData) const;
// LowerCaseEqualsLiteral must ONLY be applied to an actual
// literal string, or a char array *constant* declared without an
// explicit size. Do not attempt to use it with a regular char*
// pointer, or with a non-constant char array variable. Use
// LowerCaseEqualsASCII for them.
template<int N>
inline bool LowerCaseEqualsLiteral(const char (&aStr)[N]) const
{
return LowerCaseEqualsASCII(aStr, N - 1);
}
/**
* returns true if this string overlaps with the given string fragment.
*/
bool IsDependentOn(const char_type* aStart, const char_type* aEnd) const
{
/**
* if it _isn't_ the case that one fragment starts after the other ends,
* or ends before the other starts, then, they conflict:
*
* !(f2.begin >= f1.aEnd || f2.aEnd <= f1.begin)
*
* Simplified, that gives us:
*/
return (aStart < (mData + mLength) && aEnd > mData);
}
protected:
nsTStringRepr_CharT() = delete; // Never instantiate directly
constexpr
nsTStringRepr_CharT(char_type* aData, size_type aLength,
DataFlags aDataFlags, ClassFlags aClassFlags)
: mData(aData)
, mLength(aLength)
, mDataFlags(aDataFlags)
, mClassFlags(aClassFlags)
{
}
char_type* mData;
size_type mLength;
DataFlags mDataFlags;
ClassFlags const mClassFlags;
};
} // namespace detail
} // namespace mozilla
template <typename T> class nsTSubstringSplitter;
template <typename T> class nsTString;
/**
* nsTSubstring is an abstract string class. From an API perspective, this
@ -336,13 +36,45 @@ protected:
* nsACString for narrow characters
*
*/
class nsTSubstring_CharT : public mozilla::detail::nsTStringRepr_CharT
template <typename T>
class nsTSubstring : public mozilla::detail::nsTStringRepr<T>
{
public:
typedef nsTSubstring_CharT self_type;
typedef nsTSubstring<T> self_type;
typedef nsTString<T> string_type;
typedef typename mozilla::detail::nsTStringRepr<T> base_string_type;
typedef typename base_string_type::substring_type substring_type;
typedef typename base_string_type::fallible_t fallible_t;
typedef typename base_string_type::char_type char_type;
typedef typename base_string_type::char_traits char_traits;
typedef typename base_string_type::incompatible_char_type incompatible_char_type;
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
typedef typename base_string_type::const_iterator const_iterator;
typedef typename base_string_type::iterator iterator;
typedef typename base_string_type::comparator_type comparator_type;
typedef typename base_string_type::char_iterator char_iterator;
typedef typename base_string_type::const_char_iterator const_char_iterator;
typedef typename base_string_type::index_type index_type;
typedef typename base_string_type::size_type size_type;
// These are only for internal use within the string classes:
typedef typename base_string_type::DataFlags DataFlags;
typedef typename base_string_type::ClassFlags ClassFlags;
using typename base_string_type::IsChar;
using typename base_string_type::IsChar16;
// this acts like a virtual destructor
~nsTSubstring_CharT()
~nsTSubstring()
{
Finalize();
}
@ -354,29 +86,29 @@ public:
char_iterator BeginWriting()
{
if (!EnsureMutable()) {
AllocFailed(mLength);
AllocFailed(base_string_type::mLength);
}
return mData;
return base_string_type::mData;
}
char_iterator BeginWriting(const fallible_t&)
{
return EnsureMutable() ? mData : char_iterator(0);
return EnsureMutable() ? base_string_type::mData : char_iterator(0);
}
char_iterator EndWriting()
{
if (!EnsureMutable()) {
AllocFailed(mLength);
AllocFailed(base_string_type::mLength);
}
return mData + mLength;
return base_string_type::mData + base_string_type::mLength;
}
char_iterator EndWriting(const fallible_t&)
{
return EnsureMutable() ? (mData + mLength) : char_iterator(0);
return EnsureMutable() ? (base_string_type::mData + base_string_type::mLength) : char_iterator(0);
}
char_iterator& BeginWriting(char_iterator& aIter)
@ -407,7 +139,7 @@ public:
{
char_type* data = BeginWriting();
aIter.mStart = data;
aIter.mEnd = data + mLength;
aIter.mEnd = data + base_string_type::mLength;
aIter.mPosition = aIter.mStart;
return aIter;
}
@ -416,7 +148,7 @@ public:
{
char_type* data = BeginWriting();
aIter.mStart = data;
aIter.mEnd = data + mLength;
aIter.mEnd = data + base_string_type::mLength;
aIter.mPosition = aIter.mEnd;
return aIter;
}
@ -443,17 +175,20 @@ public:
MOZ_MUST_USE bool NS_FASTCALL Assign(const substring_tuple_type&,
const fallible_t&);
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
void Assign(char16ptr_t aData)
{
Assign(static_cast<const char16_t*>(aData));
}
template <typename EnableIfChar16 = IsChar16>
void Assign(char16ptr_t aData, size_type aLength)
{
Assign(static_cast<const char16_t*>(aData), aLength);
}
template <typename EnableIfChar16 = IsChar16>
MOZ_MUST_USE bool Assign(char16ptr_t aData, size_type aLength,
const fallible_t& aFallible)
{
@ -490,13 +225,12 @@ public:
{
AssignLiteral(aStr, N - 1);
}
#ifdef CharT_is_PRUnichar
template<int N>
void AssignLiteral(const char (&aStr)[N])
template<int N, typename EnableIfChar16 = IsChar16>
void AssignLiteral(const incompatible_char_type (&aStr)[N])
{
AssignASCII(aStr, N - 1);
}
#endif
self_type& operator=(char_type aChar)
{
@ -508,7 +242,8 @@ public:
Assign(aData);
return *this;
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
self_type& operator=(char16ptr_t aData)
{
Assign(aData);
@ -587,23 +322,24 @@ public:
void Append(char_type aChar)
{
Replace(mLength, 0, aChar);
Replace(base_string_type::mLength, 0, aChar);
}
MOZ_MUST_USE bool Append(char_type aChar, const fallible_t& aFallible)
{
return Replace(mLength, 0, aChar, aFallible);
return Replace(base_string_type::mLength, 0, aChar, aFallible);
}
void Append(const char_type* aData, size_type aLength = size_type(-1))
{
Replace(mLength, 0, aData, aLength);
Replace(base_string_type::mLength, 0, aData, aLength);
}
MOZ_MUST_USE bool Append(const char_type* aData, size_type aLength,
const fallible_t& aFallible)
{
return Replace(mLength, 0, aData, aLength, aFallible);
return Replace(base_string_type::mLength, 0, aData, aLength, aFallible);
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
void Append(char16ptr_t aData, size_type aLength = size_type(-1))
{
Append(static_cast<const char16_t*>(aData), aLength);
@ -612,30 +348,30 @@ public:
void Append(const self_type& aStr)
{
Replace(mLength, 0, aStr);
Replace(base_string_type::mLength, 0, aStr);
}
MOZ_MUST_USE bool Append(const self_type& aStr, const fallible_t& aFallible)
{
return Replace(mLength, 0, aStr, aFallible);
return Replace(base_string_type::mLength, 0, aStr, aFallible);
}
void Append(const substring_tuple_type& aTuple)
{
Replace(mLength, 0, aTuple);
Replace(base_string_type::mLength, 0, aTuple);
}
void AppendASCII(const char* aData, size_type aLength = size_type(-1))
{
ReplaceASCII(mLength, 0, aData, aLength);
ReplaceASCII(base_string_type::mLength, 0, aData, aLength);
}
MOZ_MUST_USE bool AppendASCII(const char* aData, const fallible_t& aFallible)
{
return ReplaceASCII(mLength, 0, aData, size_type(-1), aFallible);
return ReplaceASCII(base_string_type::mLength, 0, aData, size_type(-1), aFallible);
}
MOZ_MUST_USE bool AppendASCII(const char* aData, size_type aLength, const fallible_t& aFallible)
{
return ReplaceASCII(mLength, 0, aData, aLength, aFallible);
return ReplaceASCII(base_string_type::mLength, 0, aData, aLength, aFallible);
}
/**
@ -704,21 +440,23 @@ public:
template<int N>
void AppendLiteral(const char_type (&aStr)[N])
{
ReplaceLiteral(mLength, 0, aStr, N - 1);
ReplaceLiteral(base_string_type::mLength, 0, aStr, N - 1);
}
#ifdef CharT_is_PRUnichar
template<int N>
void AppendLiteral(const char (&aStr)[N])
// Only enable for T = char16_t
template<int N, typename EnableIfChar16 = IsChar16>
void AppendLiteral(const incompatible_char_type (&aStr)[N])
{
AppendASCII(aStr, N - 1);
}
template<int N>
MOZ_MUST_USE bool AppendLiteral(const char (&aStr)[N], const fallible_t& aFallible)
// Only enable for T = char16_t
template<int N, typename EnableIfChar16 = IsChar16>
MOZ_MUST_USE bool
AppendLiteral(const incompatible_char_type (&aStr)[N], const fallible_t& aFallible)
{
return AppendASCII(aStr, N - 1, aFallible);
}
#endif
self_type& operator+=(char_type aChar)
{
@ -730,7 +468,8 @@ public:
Append(aData);
return *this;
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
self_type& operator+=(char16ptr_t aData)
{
Append(aData);
@ -757,7 +496,8 @@ public:
{
Replace(aPos, 0, aData, aLength);
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
void Insert(char16ptr_t aData, index_type aPos,
size_type aLength = size_type(-1))
{
@ -787,7 +527,7 @@ public:
Replace(aCutStart, aCutLength, char_traits::sEmptyBuffer, 0);
}
nsTSubstringSplitter_CharT Split(const char_type aChar) const;
nsTSubstringSplitter<T> Split(const char_type aChar) const;
/**
* buffer sizing
@ -810,7 +550,7 @@ public:
void Truncate(size_type aNewLength = 0)
{
NS_ASSERTION(aNewLength <= mLength, "Truncate cannot make string longer");
NS_ASSERTION(aNewLength <= base_string_type::mLength, "Truncate cannot make string longer");
SetLength(aNewLength);
}
@ -828,8 +568,8 @@ public:
*/
inline size_type GetData(const char_type** aData) const
{
*aData = mData;
return mLength;
*aData = base_string_type::mData;
return base_string_type::mLength;
}
/**
@ -845,11 +585,11 @@ public:
size_type GetMutableData(char_type** aData, size_type aNewLen = size_type(-1))
{
if (!EnsureMutable(aNewLen)) {
AllocFailed(aNewLen == size_type(-1) ? mLength : aNewLen);
AllocFailed(aNewLen == size_type(-1) ? base_string_type::mLength : aNewLen);
}
*aData = mData;
return mLength;
*aData = base_string_type::mData;
return base_string_type::mLength;
}
size_type GetMutableData(char_type** aData, size_type aNewLen, const fallible_t&)
@ -859,16 +599,18 @@ public:
return 0;
}
*aData = mData;
return mLength;
*aData = base_string_type::mData;
return base_string_type::mLength;
}
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
#if defined(MOZ_USE_CHAR16_WRAPPER)
template <typename EnableIfChar16 = IsChar16>
size_type GetMutableData(wchar_t** aData, size_type aNewLen = size_type(-1))
{
return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen);
}
template <typename EnableIfChar16 = IsChar16>
size_type GetMutableData(wchar_t** aData, size_type aNewLen,
const fallible_t& aFallible)
{
@ -883,12 +625,12 @@ public:
operator mozilla::Span<char_type>()
{
return mozilla::MakeSpan(BeginWriting(), Length());
return mozilla::MakeSpan(BeginWriting(), base_string_type::Length());
}
operator mozilla::Span<const char_type>() const
{
return mozilla::MakeSpan(BeginReading(), Length());
return mozilla::MakeSpan(base_string_type::BeginReading(), base_string_type::Length());
}
void Append(mozilla::Span<const char_type> aSpan)
@ -908,19 +650,21 @@ public:
return Append(aSpan.Elements(), len, aFallible);
}
#if !defined(CharT_is_PRUnichar)
template <typename EnableIfChar = IsChar>
operator mozilla::Span<uint8_t>()
{
return mozilla::MakeSpan(reinterpret_cast<uint8_t*>(BeginWriting()),
Length());
base_string_type::Length());
}
template <typename EnableIfChar = IsChar>
operator mozilla::Span<const uint8_t>() const
{
return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(BeginReading()),
Length());
return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(base_string_type::BeginReading()),
base_string_type::Length());
}
template <typename EnableIfChar = IsChar>
void Append(mozilla::Span<const uint8_t> aSpan)
{
auto len = aSpan.Length();
@ -928,6 +672,7 @@ public:
Append(reinterpret_cast<const char*>(aSpan.Elements()), len);
}
template <typename EnableIfChar = IsChar>
MOZ_MUST_USE bool Append(mozilla::Span<const uint8_t> aSpan,
const fallible_t& aFallible)
{
@ -938,7 +683,6 @@ public:
return Append(
reinterpret_cast<const char*>(aSpan.Elements()), len, aFallible);
}
#endif
/**
* string data is never null, but can be marked void. if true, the
@ -995,7 +739,7 @@ public:
*/
void ForgetSharedBuffer()
{
if (mDataFlags & DataFlags::SHARED) {
if (base_string_type::mDataFlags & DataFlags::SHARED) {
SetToEmptyBuffer();
}
}
@ -1003,8 +747,8 @@ public:
protected:
void AssertValid()
{
MOZ_ASSERT(!(mClassFlags & ClassFlags::NULL_TERMINATED) ||
(mDataFlags & DataFlags::TERMINATED),
MOZ_ASSERT(!(this->mClassFlags & ClassFlags::NULL_TERMINATED) ||
(this->mDataFlags & DataFlags::TERMINATED),
"String classes whose static type guarantees a null-terminated "
"buffer must not be assigned a non-null-terminated buffer.");
}
@ -1015,8 +759,8 @@ public:
* this is public to support automatic conversion of tuple to string
* base type, which helps avoid converting to nsTAString.
*/
MOZ_IMPLICIT nsTSubstring_CharT(const substring_tuple_type& aTuple)
: nsTStringRepr_CharT(nullptr, 0, DataFlags(0), ClassFlags(0))
MOZ_IMPLICIT nsTSubstring(const substring_tuple_type& aTuple)
: base_string_type(nullptr, 0, DataFlags(0), ClassFlags(0))
{
AssertValid();
Assign(aTuple);
@ -1038,11 +782,11 @@ public:
size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
const;
template<class T>
template<class N>
void NS_ABORT_OOM(T)
{
struct never {}; // a compiler-friendly way to do static_assert(false)
static_assert(mozilla::IsSame<T, never>::value,
static_assert(mozilla::IsSame<N, never>::value,
"In string classes, use AllocFailed to account for sizeof(char_type). "
"Use the global ::NS_ABORT_OOM if you really have a count of bytes.");
}
@ -1055,27 +799,27 @@ public:
protected:
// default initialization
nsTSubstring_CharT()
: nsTStringRepr_CharT(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
ClassFlags(0))
nsTSubstring()
: base_string_type(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
ClassFlags(0))
{
AssertValid();
}
// copy-constructor, constructs as dependent on given object
// (NOTE: this is for internal use only)
nsTSubstring_CharT(const self_type& aStr)
: nsTStringRepr_CharT(aStr.mData, aStr.mLength,
aStr.mDataFlags & (DataFlags::TERMINATED | DataFlags::VOIDED),
ClassFlags(0))
nsTSubstring(const self_type& aStr)
: base_string_type(aStr.base_string_type::mData, aStr.base_string_type::mLength,
aStr.base_string_type::mDataFlags & (DataFlags::TERMINATED | DataFlags::VOIDED),
ClassFlags(0))
{
AssertValid();
}
// initialization with ClassFlags
explicit nsTSubstring_CharT(ClassFlags aClassFlags)
: nsTStringRepr_CharT(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
aClassFlags)
explicit nsTSubstring(ClassFlags aClassFlags)
: base_string_type(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
aClassFlags)
{
AssertValid();
}
@ -1083,15 +827,15 @@ protected:
/**
* allows for direct initialization of a nsTSubstring object.
*/
nsTSubstring_CharT(char_type* aData, size_type aLength,
DataFlags aDataFlags, ClassFlags aClassFlags)
nsTSubstring(char_type* aData, size_type aLength,
DataFlags aDataFlags, ClassFlags aClassFlags)
// XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING?
#if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
#define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
;
#else
#undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
: nsTStringRepr_CharT(aData, aLength, aDataFlags, aClassFlags)
: base_string_type(aData, aLength, aDataFlags, aClassFlags)
{
AssertValid();
MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "String is too large.");
@ -1100,17 +844,17 @@ protected:
void SetToEmptyBuffer()
{
mData = char_traits::sEmptyBuffer;
mLength = 0;
mDataFlags = DataFlags::TERMINATED;
base_string_type::mData = char_traits::sEmptyBuffer;
base_string_type::mLength = 0;
base_string_type::mDataFlags = DataFlags::TERMINATED;
AssertValid();
}
void SetData(char_type* aData, size_type aLength, DataFlags aDataFlags)
{
mData = aData;
mLength = aLength;
mDataFlags = aDataFlags;
base_string_type::mData = aData;
base_string_type::mLength = aLength;
base_string_type::mDataFlags = aDataFlags;
AssertValid();
}
@ -1213,85 +957,27 @@ public:
void NS_FASTCALL AssignLiteral(const char_type* aData, size_type aLength);
};
static_assert(sizeof(nsTSubstring_CharT) ==
sizeof(mozilla::detail::nsTStringRepr_CharT),
extern template class nsTSubstring<char>;
extern template class nsTSubstring<char16_t>;
static_assert(sizeof(nsTSubstring<char>) ==
sizeof(mozilla::detail::nsTStringRepr<char>),
"Don't add new data fields to nsTSubstring_CharT. "
"Add to nsTStringRepr_CharT instead.");
"Add to nsTStringRepr<T> instead.");
int NS_FASTCALL
Compare(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs,
const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT());
inline bool
operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs)
{
return !aLhs.Equals(aRhs);
}
inline bool
operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::char_type* aRhs)
{
return !aLhs.Equals(aRhs);
}
inline bool
operator<(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs)
{
return Compare(aLhs, aRhs) < 0;
}
inline bool
operator<=(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs)
{
return Compare(aLhs, aRhs) <= 0;
}
inline bool
operator==(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs)
{
return aLhs.Equals(aRhs);
}
inline bool
operator==(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::char_type* aRhs)
{
return aLhs.Equals(aRhs);
}
inline bool
operator>=(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs)
{
return Compare(aLhs, aRhs) >= 0;
}
inline bool
operator>(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs)
{
return Compare(aLhs, aRhs) > 0;
}
// You should not need to instantiate this class directly.
// Use nsTSubstring::Split instead.
class nsTSubstringSplitter_CharT
template <typename T>
class nsTSubstringSplitter
{
typedef nsTSubstring_CharT::size_type size_type;
typedef nsTSubstring_CharT::char_type char_type;
typedef typename nsTSubstring<T>::size_type size_type;
typedef typename nsTSubstring<T>::char_type char_type;
class nsTSubstringSplit_Iter
{
public:
nsTSubstringSplit_Iter(const nsTSubstringSplitter_CharT& aObj,
nsTSubstringSplit_Iter(const nsTSubstringSplitter<T>& aObj,
size_type aPos)
: mObj(aObj)
, mPos(aPos)
@ -1303,7 +989,7 @@ class nsTSubstringSplitter_CharT
return mPos != other.mPos;
}
const nsTDependentSubstring_CharT& operator*() const;
const nsTDependentSubstring<T>& operator*() const;
const nsTSubstringSplit_Iter& operator++()
{
@ -1312,18 +998,18 @@ class nsTSubstringSplitter_CharT
}
private:
const nsTSubstringSplitter_CharT& mObj;
const nsTSubstringSplitter<T>& mObj;
size_type mPos;
};
private:
const nsTSubstring_CharT* const mStr;
mozilla::UniquePtr<nsTDependentSubstring_CharT[]> mArray;
const nsTSubstring<T>* const mStr;
mozilla::UniquePtr<nsTDependentSubstring<T>[]> mArray;
size_type mArraySize;
const char_type mDelim;
public:
nsTSubstringSplitter_CharT(const nsTSubstring_CharT* aStr, char_type aDelim);
nsTSubstringSplitter(const nsTSubstring<T>* aStr, char_type aDelim);
nsTSubstringSplit_Iter begin() const
{
@ -1335,28 +1021,46 @@ public:
return nsTSubstringSplit_Iter(*this, mArraySize);
}
const nsTDependentSubstring_CharT& Get(const size_type index) const
const nsTDependentSubstring<T>& Get(const size_type index) const
{
MOZ_ASSERT(index < mArraySize);
return mArray[index];
}
};
extern template class nsTSubstringSplitter<char>;
extern template class nsTSubstringSplitter<char16_t>;
/**
* Span integration
*/
namespace mozilla {
inline Span<CharT>
MakeSpan(nsTSubstring_CharT& aString)
inline Span<char>
MakeSpan(nsTSubstring<char>& aString)
{
return aString;
}
inline Span<const CharT>
MakeSpan(const nsTSubstring_CharT& aString)
inline Span<const char>
MakeSpan(const nsTSubstring<char>& aString)
{
return aString;
}
inline Span<char16_t>
MakeSpan(nsTSubstring<char16_t>& aString)
{
return aString;
}
inline Span<const char16_t>
MakeSpan(const nsTSubstring<char16_t>& aString)
{
return aString;
}
} // namespace mozilla
#endif

Просмотреть файл

@ -10,8 +10,9 @@
* computes the aggregate string length
*/
nsTSubstringTuple_CharT::size_type
nsTSubstringTuple_CharT::Length() const
template <typename T>
typename nsTSubstringTuple<T>::size_type
nsTSubstringTuple<T>::Length() const
{
mozilla::CheckedInt<size_type> len;
if (mHead) {
@ -32,8 +33,9 @@ nsTSubstringTuple_CharT::Length() const
* method. the string written to |aBuf| is not null-terminated.
*/
template <typename T>
void
nsTSubstringTuple_CharT::WriteTo(char_type* aBuf, uint32_t aBufLen) const
nsTSubstringTuple<T>::WriteTo(char_type* aBuf, uint32_t aBufLen) const
{
MOZ_RELEASE_ASSERT(aBufLen >= mFragB->Length(), "buffer too small");
uint32_t headLen = aBufLen - mFragB->Length();
@ -53,9 +55,10 @@ nsTSubstringTuple_CharT::WriteTo(char_type* aBuf, uint32_t aBufLen) const
* the given char sequence.
*/
template <typename T>
bool
nsTSubstringTuple_CharT::IsDependentOn(const char_type* aStart,
const char_type* aEnd) const
nsTSubstringTuple<T>::IsDependentOn(const char_type* aStart,
const char_type* aEnd) const
{
// we aStart with the right-most fragment since it is faster to check.

Просмотреть файл

@ -5,8 +5,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#ifndef nsTSubstringTuple_h
#define nsTSubstringTuple_h
#include "nsTStringRepr.h"
/**
* nsTSubstringTuple_CharT
* nsTSubstringTuple
*
* Represents a tuple of string fragments. Built as a recursive binary tree.
* It is used to implement the concatenation of two or more string objects.
@ -14,29 +19,30 @@
* NOTE: This class is a private implementation detail and should never be
* referenced outside the string code.
*/
class nsTSubstringTuple_CharT
template <typename T>
class nsTSubstringTuple
{
public:
typedef CharT char_type;
typedef nsCharTraits<char_type> char_traits;
typedef T char_type;
typedef nsCharTraits<char_type> char_traits;
typedef nsTSubstringTuple_CharT self_type;
typedef mozilla::detail::nsTStringRepr_CharT base_string_type;
typedef uint32_t size_type;
typedef nsTSubstringTuple<T> self_type;
typedef mozilla::detail::nsTStringRepr<char_type> base_string_type;
typedef uint32_t size_type;
public:
nsTSubstringTuple_CharT(const base_string_type* aStrA,
const base_string_type* aStrB)
nsTSubstringTuple(const base_string_type* aStrA,
const base_string_type* aStrB)
: mHead(nullptr)
, mFragA(aStrA)
, mFragB(aStrB)
{
}
nsTSubstringTuple_CharT(const self_type& aHead,
const base_string_type* aStrB)
nsTSubstringTuple(const self_type& aHead,
const base_string_type* aStrB)
: mHead(&aHead)
, mFragA(nullptr) // this fragment is ignored when aHead != nullptr
, mFragB(aStrB)
@ -68,16 +74,20 @@ private:
const base_string_type* const mFragB;
};
inline const nsTSubstringTuple_CharT
operator+(const nsTSubstringTuple_CharT::base_string_type& aStrA,
const nsTSubstringTuple_CharT::base_string_type& aStrB)
template <typename T>
inline const nsTSubstringTuple<T>
operator+(const mozilla::detail::nsTStringRepr<T>& aStrA,
const mozilla::detail::nsTStringRepr<T>& aStrB)
{
return nsTSubstringTuple_CharT(&aStrA, &aStrB);
return nsTSubstringTuple<T>(&aStrA, &aStrB);
}
inline const nsTSubstringTuple_CharT
operator+(const nsTSubstringTuple_CharT& aHead,
const nsTSubstringTuple_CharT::base_string_type& aStrB)
template <typename T>
inline const nsTSubstringTuple<T>
operator+(const nsTSubstringTuple<T>& aHead,
const mozilla::detail::nsTStringRepr<T>& aStrB)
{
return nsTSubstringTuple_CharT(aHead, &aStrB);
return nsTSubstringTuple<T>(aHead, &aStrB);
}
#endif

Просмотреть файл

@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsString.h"
// This file provides concrete instantiations for externed string template
// classes and functions.
// ================
// Template classes
// ================
template class mozilla::detail::nsTStringRepr<char>;
template class mozilla::detail::nsTStringRepr<char16_t>;
template class nsTLiteralString<char>;
template class nsTLiteralString<char16_t>;
template class nsTSubstring<char>;
template class nsTSubstring<char16_t>;
template class nsTDependentSubstring<char>;
template class nsTDependentSubstring<char16_t>;
// Note: nsTString is skipped as it's implicitly instantiated by derived
// classes.
template class nsTFixedString<char>;
template class nsTFixedString<char16_t>;
template class nsTAutoStringN<char, 64>;
template class nsTAutoStringN<char16_t, 64>;
template class nsTDependentString<char>;
template class nsTDependentString<char16_t>;
template class nsTPromiseFlatString<char>;
template class nsTPromiseFlatString<char16_t>;
template class nsTSubstringSplitter<char>;
template class nsTSubstringSplitter<char16_t>;
template class nsTDefaultStringComparator<char>;
template class nsTDefaultStringComparator<char16_t>;
// =============================
// Templated top-level functions
// =============================
template
int
Compare<char>(mozilla::detail::nsTStringRepr<char> const&,
mozilla::detail::nsTStringRepr<char> const&,
nsTStringComparator<char> const&);
template
int
Compare<char16_t>(mozilla::detail::nsTStringRepr<char16_t> const&,
mozilla::detail::nsTStringRepr<char16_t> const&,
nsTStringComparator<char16_t> const&);
template
nsTDependentSubstring<char> const
Substring<char>(char const*, char const*);
template
nsTDependentSubstring<char16_t> const
Substring<char16_t>(char16_t const*, char16_t const*);
// =========================================================
// Templated member functions that are conditionally enabled
// =========================================================
template
int32_t
nsTString<char16_t>::Find(const self_type&, int32_t, int32_t) const;
template
int32_t
nsTString<char16_t>::Find(const char_type*, int32_t, int32_t) const;
template
int32_t
nsTString<char16_t>::RFind(const self_type&, int32_t, int32_t) const;
template
int32_t
nsTString<char16_t>::RFind(const char_type*, int32_t, int32_t) const;
template
int32_t
nsTString<char16_t>::FindCharInSet(const char*, int32_t) const;
template
int32_t
nsTString<char>::Compare(const char_type*, bool, int32_t) const;
template
bool
nsTString<char16_t>::EqualsIgnoreCase(const incompatible_char_type*,
int32_t) const;
template
bool
nsTString<char16_t>::StripChars(const incompatible_char_type*,
const fallible_t&);
template
void
nsTString<char16_t>::StripChars(const incompatible_char_type*);
template
void
nsTString<char16_t>::ReplaceChar(const char*, char16_t);

Просмотреть файл

@ -1,28 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#define CharT char
#define CharT_is_char 1
#define nsTAString_IncompatibleCharT nsAString
#define nsTString_CharT nsCString
#define nsTStringRepr_CharT nsCStringRepr
#define nsTFixedString_CharT nsFixedCString
#define nsTAutoStringN_CharT nsAutoCStringN
#define nsTAutoString_CharT nsAutoCString
#define nsTSubstring_CharT nsACString
#define PrintfAppend_CharT PrintfAppend_nsACString
#define nsTSubstringTuple_CharT nsCSubstringTuple
#define nsTStringComparator_CharT nsCStringComparator
#define nsTDefaultStringComparator_CharT nsDefaultCStringComparator
#define nsTDependentString_CharT nsDependentCString
#define nsTDependentSubstring_CharT nsDependentCSubstring
#define nsTLiteralString_CharT nsLiteralCString
#define nsTGetterCopies_CharT nsCGetterCopies
#define nsTPromiseFlatString_CharT nsPromiseFlatCString
#define TPromiseFlatString_CharT PromiseFlatCString
#define nsTSubstringSplitter_CharT nsCSubstringSplitter
#define TNullString_CharT NullCString

Просмотреть файл

@ -1,28 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#define CharT char16_t
#define CharT_is_PRUnichar 1
#define nsTAString_IncompatibleCharT nsACString
#define nsTString_CharT nsString
#define nsTStringRepr_CharT nsStringRepr
#define nsTFixedString_CharT nsFixedString
#define nsTAutoStringN_CharT nsAutoStringN
#define nsTAutoString_CharT nsAutoString
#define nsTSubstring_CharT nsAString
#define PrintfAppend_CharT PrintfAppend_nsAString
#define nsTSubstringTuple_CharT nsSubstringTuple
#define nsTStringComparator_CharT nsStringComparator
#define nsTDefaultStringComparator_CharT nsDefaultStringComparator
#define nsTDependentString_CharT nsDependentString
#define nsTDependentSubstring_CharT nsDependentSubstring
#define nsTLiteralString_CharT nsLiteralString
#define nsTGetterCopies_CharT nsGetterCopies
#define nsTPromiseFlatString_CharT nsPromiseFlatString
#define TPromiseFlatString_CharT PromiseFlatString
#define nsTSubstringSplitter_CharT nsSubstringSplitter
#define TNullString_CharT NullString

Просмотреть файл

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#undef CharT
#undef CharT_is_PRUnichar
#undef CharT_is_char
#undef nsTAString_IncompatibleCharT
#undef nsTString_CharT
#undef nsTStringRepr_CharT
#undef nsTFixedString_CharT
#undef nsTAutoStringN_CharT
#undef nsTAutoString_CharT
#undef nsTSubstring_CharT
#undef PrintfAppend_CharT
#undef nsTSubstringTuple_CharT
#undef nsTStringComparator_CharT
#undef nsTDefaultStringComparator_CharT
#undef nsTDependentString_CharT
#undef nsTDependentSubstring_CharT
#undef nsTLiteralString_CharT
#undef nsTGetterCopies_CharT
#undef nsTPromiseFlatString_CharT
#undef TPromiseFlatString_CharT
#undef nsTSubstringSplitter_CharT
#undef TNullString_CharT