author | Eric Rahm <erahm@mozilla.com> |
Tue, 03 Oct 2017 12:44:44 -0700 | |
changeset 387196 | 0d2b1057b968860044a6b7c35bf03712d4c155be |
parent 387195 | 381eb8e69ec8fb823177782a3de0a3b2442742fa |
child 387197 | b871e93e7912a3b51e0f4aa180dc53091918cb18 |
push id | 32715 |
push user | acraciun@mozilla.com |
push date | Fri, 20 Oct 2017 09:04:45 +0000 |
treeherder | mozilla-central@be030533c5af [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | froydnj |
bugs | 1403083 |
milestone | 58.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/xpcom/string/nsStringObsolete.cpp +++ b/xpcom/string/nsStringObsolete.cpp @@ -851,81 +851,81 @@ RFind_ComputeSearchRange( uint32_t bigLe #include "nsTStringObsolete.cpp" //----------------------------------------------------------------------------- // specialized methods: template <typename T> -template <typename EnableIfChar16> +template <typename Q, typename EnableIfChar16> int32_t 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(this->mLength, aString.Length(), aOffset, aCount); // 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> +template <typename Q, typename EnableIfChar16> int32_t nsTString<T>::Find(const char_type* aString, int32_t aOffset, int32_t aCount) const { return Find(nsTDependentString<T>(aString), aOffset, aCount); } template <typename T> -template <typename EnableIfChar16> +template <typename Q, typename EnableIfChar16> int32_t 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(this->mLength, aString.Length(), aOffset, aCount); // 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> +template <typename Q, typename EnableIfChar16> int32_t nsTString<T>::RFind(const char_type* aString, int32_t aOffset, int32_t aCount) const { return RFind(nsTDependentString<T>(aString), aOffset, aCount); } template <typename T> -template <typename EnableIfChar16> +template <typename Q, typename EnableIfChar16> int32_t nsTString<T>::FindCharInSet(const char* aSet, int32_t aOffset) const { if (aOffset < 0) aOffset = 0; else if (aOffset >= int32_t(this->mLength)) return kNotFound; int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet); if (result != kNotFound) result += aOffset; return result; } template <typename T> -template <typename EnableIfChar16> +template <typename Q, typename EnableIfChar16> void nsTString<T>::ReplaceChar(const char* aSet, char16_t aNewChar) { if (!this->EnsureMutable()) // XXX do this lazily? this->AllocFailed(this->mLength); char16_t* data = this->mData; uint32_t lenRemaining = this->mLength; @@ -943,17 +943,17 @@ nsTString<T>::ReplaceChar(const char* aS } /** * nsTString::Compare,CompareWithConversion,etc. */ template <typename T> -template <typename EnableIfChar> +template <typename Q, typename EnableIfChar> int32_t 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(this->mLength, strLen)); int32_t compareCount; @@ -974,17 +974,17 @@ nsTString<T>::Compare(const char_type* a if (this->mLength != strLen) result = (this->mLength < strLen) ? -1 : 1; } return result; } template <typename T> -template <typename EnableIfChar16> +template <typename Q, typename EnableIfChar16> bool 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(this->mLength, strLen)); int32_t compareCount;
--- a/xpcom/string/nsTDependentString.h +++ b/xpcom/string/nsTDependentString.h @@ -47,54 +47,50 @@ public: 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: /** * constructors */ nsTDependentString(const char_type* aStart, const char_type* aEnd); nsTDependentString(const char_type* aData, uint32_t aLength) : string_type(const_cast<char_type*>(aData), aLength, DataFlags::TERMINATED, ClassFlags(0)) { this->AssertValidDependentString(); } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> nsTDependentString(char16ptr_t aData, uint32_t aLength) : nsTDependentString(static_cast<const char16_t*>(aData), aLength) { } #endif explicit nsTDependentString(const char_type* aData) : string_type(const_cast<char_type*>(aData), uint32_t(char_traits::length(aData)), DataFlags::TERMINATED, ClassFlags(0)) { string_type::AssertValidDependentString(); } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> explicit nsTDependentString(char16ptr_t aData) : nsTDependentString(static_cast<const char16_t*>(aData)) { } #endif nsTDependentString(const string_type& aStr, uint32_t aStartPos)
--- a/xpcom/string/nsTDependentSubstring.cpp +++ b/xpcom/string/nsTDependentSubstring.cpp @@ -55,17 +55,17 @@ nsTDependentSubstring<T>::nsTDependentSu : substring_type(const_cast<char_type*>(aStart), uint32_t(aEnd - aStart), DataFlags(0), ClassFlags(0)) { MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!"); } #if defined(MOZ_USE_CHAR16_WRAPPER) template <typename T> -template <typename EnableIfChar16> +template <typename Q, 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), "Overflow!");
--- a/xpcom/string/nsTDependentSubstring.h +++ b/xpcom/string/nsTDependentSubstring.h @@ -47,19 +47,16 @@ public: 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: void Rebind(const substring_type&, uint32_t aStartPos, uint32_t aLength = size_type(-1)); void Rebind(const char_type* aData, size_type aLength); void Rebind(const char_type* aStart, const char_type* aEnd); @@ -75,23 +72,23 @@ public: : substring_type(const_cast<char_type*>(aData), aLength, DataFlags(0), ClassFlags(0)) { } nsTDependentSubstring(const char_type* aStart, const char_type* aEnd); #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> nsTDependentSubstring(char16ptr_t aData, size_type aLength) : nsTDependentSubstring(static_cast<const char16_t*>(aData), aLength) { } - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> nsTDependentSubstring(char16ptr_t aStart, char16ptr_t aEnd); #endif nsTDependentSubstring(const const_iterator& aStart, const const_iterator& aEnd); // Create a nsTDependentSubstring to be bound later nsTDependentSubstring()
--- a/xpcom/string/nsTString.h +++ b/xpcom/string/nsTString.h @@ -58,19 +58,16 @@ public: 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: /** * constructors */ nsTString() : substring_type(ClassFlags::NULL_TERMINATED) @@ -80,17 +77,17 @@ public: explicit nsTString(const char_type* aData, size_type aLength = size_type(-1)) : substring_type(ClassFlags::NULL_TERMINATED) { this->Assign(aData, aLength); } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> explicit nsTString(char16ptr_t aStr, size_type aLength = size_type(-1)) : substring_type(ClassFlags::NULL_TERMINATED) { this->Assign(static_cast<const char16_t*>(aStr), aLength); } #endif @@ -152,17 +149,17 @@ public: return *this; } self_type& operator=(self_type&& aStr) { this->Assign(mozilla::Move(aStr)); return *this; } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> self_type& operator=(const char16ptr_t aStr) { this->Assign(static_cast<const char16_t*>(aStr)); return *this; } #endif self_type& operator=(const substring_type& aStr) { @@ -234,24 +231,24 @@ public: * @return offset in string, or kNotFound */ 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; - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> int32_t Find(const self_type& aString, int32_t aOffset = 0, int32_t aCount = -1) const; - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> 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> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> 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 @@ -268,20 +265,20 @@ public: */ // 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; - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> int32_t RFind(const self_type& aString, int32_t aOffset = -1, int32_t aCount = -1) const; - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> int32_t RFind(const char_type* aString, int32_t aOffset = -1, int32_t aCount = -1) const; /** * Search for given char within this string * * @param aChar is the character to search for @@ -307,17 +304,17 @@ public: */ 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); } - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> int32_t FindCharInSet(const char* aSet, int32_t aOffset = 0) const; /** * This method searches this string for the last character found in * the given string. * * @param aString contains set of chars to be found @@ -336,36 +333,36 @@ public: /** * Compares a given string to this string. * * @param aString is the string to be compared * @param aIgnoreCase tells us how to treat case * @param aCount tells us how many chars to compare * @return -1,0,1 */ - template <typename EnableIfChar = IsChar> + template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> int32_t Compare(const char_type* aString, bool aIgnoreCase = false, int32_t aCount = -1) const; /** * Equality check between given string and this string. * * @param aString is the string to check * @param aIgnoreCase tells us how to treat case * @param aCount tells us how many chars to compare * @return boolean */ - template <typename EnableIfChar = IsChar> + template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> bool EqualsIgnoreCase(const char_type* aString, int32_t aCount = -1) const { return Compare(aString, true, aCount) == 0; } - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> bool EqualsIgnoreCase(const incompatible_char_type* aString, int32_t aCount = -1) const; /** * Perform string to double-precision float conversion. * * @param aErrorCode will contain error if one occurs * @return double-precision float rep of string value */ @@ -441,37 +438,37 @@ public: /** * These methods are used to remove all occurrences of the * characters found in aSet from this string. * * @param aSet -- characters to be cut from this */ void StripChars(const char_type* aSet); - template<typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> bool StripChars(const incompatible_char_type* aSet, const fallible_t&); - template<typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> void StripChars(const incompatible_char_type* aSet); /** * This method strips whitespace throughout the string. */ void StripWhitespace(); bool StripWhitespace(const fallible_t&); /** * swaps occurence of 1 string for another */ void ReplaceChar(char_type aOldChar, char_type aNewChar); void ReplaceChar(const char_type* aSet, char_type aNewChar); - template<typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> 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 * and m being the length of aNewValue. */ void ReplaceSubstring(const self_type& aTarget, const self_type& aNewValue); @@ -591,19 +588,16 @@ public: typedef typename base_string_type::size_type size_type; typedef typename base_string_type::substring_tuple_type substring_tuple_type; typedef typename base_string_type::literalstring_type literalstring_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: /** * constructors */ nsTAutoStringN() : string_type(mStorage, 0, DataFlags::TERMINATED | DataFlags::INLINE, @@ -624,17 +618,17 @@ public: explicit nsTAutoStringN(const char_type* aData, size_type aLength = size_type(-1)) : self_type() { this->Assign(aData, aLength); } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> explicit nsTAutoStringN(char16ptr_t aData, size_type aLength = size_type(-1)) : self_type(static_cast<const char16_t*>(aData), aLength) { } #endif nsTAutoStringN(const self_type& aStr) @@ -684,17 +678,17 @@ public: return *this; } self_type& operator=(const char_type* aData) { this->Assign(aData); return *this; } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> self_type& operator=(char16ptr_t aStr) { this->Assign(aStr); return *this; } #endif self_type& operator=(const self_type& aStr) {
--- a/xpcom/string/nsTStringObsolete.cpp +++ b/xpcom/string/nsTStringObsolete.cpp @@ -403,27 +403,27 @@ nsTString<T>::SetCharAt(char16_t aChar, } /** * nsTString::StripChars,StripChar,StripWhitespace */ template<typename T> -template<typename EnableIfChar16> +template<typename Q, typename EnableIfChar16> void nsTString<T>::StripChars(const incompatible_char_type* aSet) { if (!StripChars(aSet, mozilla::fallible)) { this->AllocFailed(this->mLength); } } template<typename T> -template<typename EnableIfChar16> +template<typename Q, typename EnableIfChar16> bool nsTString<T>::StripChars(const incompatible_char_type* aSet, const fallible_t&) { if (!this->EnsureMutable()) { return false; } this->mLength = nsBufferRoutines<T>::strip_chars(this->mData, this->mLength, aSet);
--- a/xpcom/string/nsTStringRepr.h +++ b/xpcom/string/nsTStringRepr.h @@ -39,16 +39,46 @@ public: 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 { + +// This is mainly intended to be used in the context of nsTStrings where +// we want to enable a specific function only for a given character class. In +// order for this technique to work the member function needs to be templated +// on something other than `T`. We keep this in the `mozilla` namespace rather +// than `nsTStringRepr` as it's intentionally not dependent on `T`. +// +// The 'T' at the end of `Char[16]OnlyT` is refering to the `::type` portion +// which will only be defined if the character class is correct. This is similar +// to `std::enable_if_t` which is available in C++14, but not C++11. +// +// `CharType` is generally going to be a shadowed type of `T`. +// +// Example usage of a function that will only be defined if `T` == `char`: +// +// template <typename T> +// class nsTSubstring : public nsTStringRepr<T> { +// template <typename Q = T, typename EnableForChar = typename CharOnlyT<Q>> +// int Foo() { return 42; } +// }; +// +// Please note that we had to use a separate type `Q` for this to work. You +// will get a semi-decent compiler error if you use `T` directly. + +template <typename CharType> using CharOnlyT = + typename std::enable_if<std::is_same<char, CharType>::value>::type; + +template <typename CharType> using Char16OnlyT = + typename std::enable_if<std::is_same<char16_t, CharType>::value>::type; + 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 @@ -87,21 +117,16 @@ public: 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; @@ -207,22 +232,22 @@ public: 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> + template <typename Q = T, typename EnableIfChar16 = Char16OnlyT<Q>> bool NS_FASTCALL Equals(char16ptr_t aData) const { return Equals(static_cast<const char16_t*>(aData)); } - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = Char16OnlyT<Q>> 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
--- a/xpcom/string/nsTSubstring.h +++ b/xpcom/string/nsTSubstring.h @@ -66,19 +66,16 @@ public: 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() { Finalize(); } /** * writing iterators @@ -182,29 +179,29 @@ public: // them. void NS_FASTCALL Assign(const literalstring_type&); void NS_FASTCALL Assign(const substring_tuple_type&); MOZ_MUST_USE bool NS_FASTCALL Assign(const substring_tuple_type&, const fallible_t&); #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> void Assign(char16ptr_t aData) { Assign(static_cast<const char16_t*>(aData)); } - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> void Assign(char16ptr_t aData, size_type aLength) { Assign(static_cast<const char16_t*>(aData), aLength); } - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> MOZ_MUST_USE bool Assign(char16ptr_t aData, size_type aLength, const fallible_t& aFallible) { return Assign(static_cast<const char16_t*>(aData), aLength, aFallible); } #endif @@ -232,34 +229,34 @@ public: // There are not fallible version of these methods because they only really // apply to small allocations that we wouldn't want to check anyway. template<int N> void AssignLiteral(const char_type (&aStr)[N]) { AssignLiteral(aStr, N - 1); } - template<int N, typename EnableIfChar16 = IsChar16> + template<int N, typename Q = T, typename EnableIfChar16 = typename mozilla::Char16OnlyT<Q>> void AssignLiteral(const incompatible_char_type (&aStr)[N]) { AssignASCII(aStr, N - 1); } self_type& operator=(char_type aChar) { Assign(aChar); return *this; } self_type& operator=(const char_type* aData) { Assign(aData); return *this; } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> self_type& operator=(char16ptr_t aData) { Assign(aData); return *this; } #endif self_type& operator=(const self_type& aStr) { @@ -356,17 +353,17 @@ public: } MOZ_MUST_USE bool Append(const char_type* aData, size_type aLength, const fallible_t& aFallible) { return Replace(base_string_type::mLength, 0, aData, aLength, aFallible); } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> void Append(char16ptr_t aData, size_type aLength = size_type(-1)) { Append(static_cast<const char16_t*>(aData), aLength); } #endif void Append(const self_type& aStr) { @@ -461,24 +458,24 @@ public: // array variable. Use Append or AppendASCII for those. template<int N> void AppendLiteral(const char_type (&aStr)[N]) { ReplaceLiteral(base_string_type::mLength, 0, aStr, N - 1); } // Only enable for T = char16_t - template<int N, typename EnableIfChar16 = IsChar16> + template <int N, typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> void AppendLiteral(const incompatible_char_type (&aStr)[N]) { AppendASCII(aStr, N - 1); } // Only enable for T = char16_t - template<int N, typename EnableIfChar16 = IsChar16> + template <int N, typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> MOZ_MUST_USE bool AppendLiteral(const incompatible_char_type (&aStr)[N], const fallible_t& aFallible) { return AppendASCII(aStr, N - 1, aFallible); } self_type& operator+=(char_type aChar) { @@ -486,17 +483,17 @@ public: return *this; } self_type& operator+=(const char_type* aData) { Append(aData); return *this; } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> self_type& operator+=(char16ptr_t aData) { Append(aData); return *this; } #endif self_type& operator+=(const self_type& aStr) { @@ -514,17 +511,17 @@ public: Replace(aPos, 0, aChar); } void Insert(const char_type* aData, index_type aPos, size_type aLength = size_type(-1)) { Replace(aPos, 0, aData, aLength); } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> void Insert(char16ptr_t aData, index_type aPos, size_type aLength = size_type(-1)) { Insert(static_cast<const char16_t*>(aData), aPos, aLength); } #endif void Insert(const self_type& aStr, index_type aPos) { @@ -621,23 +618,23 @@ public: return 0; } *aData = base_string_type::mData; return base_string_type::mLength; } #if defined(MOZ_USE_CHAR16_WRAPPER) - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> size_type GetMutableData(wchar_t** aData, size_type aNewLen = size_type(-1)) { return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen); } - template <typename EnableIfChar16 = IsChar16> + template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> size_type GetMutableData(wchar_t** aData, size_type aNewLen, const fallible_t& aFallible) { return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen, aFallible); } #endif @@ -667,39 +664,39 @@ public: { auto len = aSpan.Length(); if (len > mozilla::MaxValue<size_type>::value) { return false; } return Append(aSpan.Elements(), len, aFallible); } - template <typename EnableIfChar = IsChar> + template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> operator mozilla::Span<uint8_t>() { return mozilla::MakeSpan(reinterpret_cast<uint8_t*>(BeginWriting()), base_string_type::Length()); } - template <typename EnableIfChar = IsChar> + template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> operator mozilla::Span<const uint8_t>() const { return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(base_string_type::BeginReading()), base_string_type::Length()); } - template <typename EnableIfChar = IsChar> + template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> void Append(mozilla::Span<const uint8_t> aSpan) { auto len = aSpan.Length(); MOZ_RELEASE_ASSERT(len <= mozilla::MaxValue<size_type>::value); Append(reinterpret_cast<const char*>(aSpan.Elements()), len); } - template <typename EnableIfChar = IsChar> + template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> MOZ_MUST_USE bool Append(mozilla::Span<const uint8_t> aSpan, const fallible_t& aFallible) { auto len = aSpan.Length(); if (len > mozilla::MaxValue<size_type>::value) { return false; } return Append(