diff --git a/string/public/nsAReadableString.h b/string/public/nsAReadableString.h index 15799b047c2d..f9c343bc8af7 100644 --- a/string/public/nsAReadableString.h +++ b/string/public/nsAReadableString.h @@ -72,8 +72,8 @@ NS_DEF_1_STRING_COMPARISON_OPERATOR(> , T1, T2) #define NS_DEF_STRING_COMPARISONS(T) \ - NS_DEF_STRING_COMPARISON_OPERATORS(const T&, const CharT*) \ - NS_DEF_STRING_COMPARISON_OPERATORS(const CharT*, const T&) + NS_DEF_STRING_COMPARISON_OPERATORS(const T&, const CharT*) \ + NS_DEF_STRING_COMPARISON_OPERATORS(const CharT*, const T&) template class basic_nsAWritableString; // ...because we sometimes use them as `out' params @@ -242,8 +242,8 @@ class basic_nsAReadableString // CharT First() const; // CharT Last() const; - void ToLowerCase( basic_nsAWritableString& ) const; - void ToUpperCase( basic_nsAWritableString& ) const; + // void ToLowerCase( basic_nsAWritableString& ) const; + // void ToUpperCase( basic_nsAWritableString& ) const; // PRUint32 CountChar( char_type ) const; @@ -296,7 +296,7 @@ class basic_nsAReadableString PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } }; -NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) +NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) @@ -366,10 +366,10 @@ class basic_nsLiteralString const CharT* mEnd; }; -NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) +NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) template -class nsConcatString +class nsPromiseConcatenation : public basic_nsAReadableString /* ...not unlike RickG's original |nsSubsumeString| in _intent_. @@ -385,7 +385,7 @@ class nsConcatString static const int kRightString = 1; public: - nsConcatString( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) + nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) { mStrings[kLeftString] = &aLeftString; mStrings[kRightString] = &aRightString; @@ -395,21 +395,21 @@ class nsConcatString private: const basic_nsAReadableString* mStrings[2]; - ConstFragment mFragment; + mutable ConstFragment mFragment; }; -NS_DEF_STRING_COMPARISONS(nsConcatString) +NS_DEF_STRING_COMPARISONS(nsPromiseConcatenation) template PRUint32 -nsConcatString::Length() const +nsPromiseConcatenation::Length() const { return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length(); } template const CharT* -nsConcatString::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const { const int kLeftString = 0; const int kRightString = 1; @@ -477,6 +477,68 @@ nsConcatString::GetFragment( ConstFragment& aFragment, FragmentRequest aR } +template +class nsPromiseSubstring + : public basic_nsAReadableString + { + typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; + typedef typename basic_nsAWritableString::ConstFragment ConstFragment; + + protected: + virtual const CharT* GetFragment( ConstFragment&, FragmentRequest, PRUint32 ) const; + + public: + nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) + : mString(aString), + mStartPos( min(aStartPos, aString.Length()) ), + mLength( min(aLength, aString.Length()-mStartPos) ) + { + // nothing else to do here + } + + virtual PRUint32 Length() const; + + private: + const basic_nsAReadableString& mString; + PRUint32 mStartPos; + PRUint32 mLength; + }; + +NS_DEF_STRING_COMPARISONS(nsPromiseSubstring) + +template +PRUint32 +nsPromiseSubstring::Length() const + { + return mLength; + } + +template +const CharT* +nsPromiseSubstring::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const + { + if ( aRequest == kFirstFragment ) + { + aPosition = mStartPos; + aRequest = kFragmentAt; + } + else if ( aRequest == kLastFragment ) + { + aPosition = mLength + mStartPos; + aRequest = kFragmentAt; + } + else if ( aRequest == kFragmentAt ) + aPosition += mStartPos; + + return mString.GetFragment(aFragment, aRequest, aPosition); + } + +template +nsPromiseSubstring +Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) + { + return nsPromiseSubstring(aString, aStartPos, aSubstringLength); + } template @@ -508,85 +570,30 @@ basic_nsLiteralString::Length() const -template -class do_ToLowerCase : unary_function - { - // std::locale loc; - // std::ctype ct; - - public: - // do_ToLowerCase() : ct( use_facet< std::ctype >(loc) ) { } - - CharT - operator()( CharT aChar ) - { - // return ct.tolower(aChar); - return CharT(std::tolower(aChar)); - } - }; - -template -void -basic_nsAReadableString::ToLowerCase( basic_nsAWritableString& aResult ) const - { - aResult.SetLength(Length()); - std::transform(Begin(), End(), aResult.Begin(), do_ToLowerCase()); - } - -template -class do_ToUpperCase : unary_function - { - // std::locale loc; - // std::ctype ct; - - public: - // do_ToUpperCase() : ct( use_facet< std::ctype >(loc) ) { } - - CharT - operator()( CharT aChar ) - { - // return ct.toupper(aChar); - return CharT(std::toupper(aChar)); - } - }; - -template -void -basic_nsAReadableString::ToUpperCase( basic_nsAWritableString& aResult ) const - { - aResult.SetLength(Length()); - std::transform(Begin(), End(), aResult.Begin(), do_ToUpperCase()); - } - template PRUint32 basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const { - aLengthToCopy = min(aLengthToCopy, Length()); - aResult.SetLength(aLengthToCopy); - std::copy(Begin(), Begin(aLengthToCopy), aResult.Begin()); - return aLengthToCopy; + aResult = Substring(*this, 0, aLengthToCopy); + return aResult.Length(); } template PRUint32 basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const { - aStartPos = min(aStartPos, Length()); - aLengthToCopy = min(aLengthToCopy, Length()-aStartPos); - aResult.SetLength(aLengthToCopy); - std::copy(Begin(aStartPos), Begin(aStartPos+aLengthToCopy), aResult.Begin()); - return aLengthToCopy; + aResult = Substring(*this, aStartPos, aLengthToCopy); + return aResult.Length(); } template PRUint32 basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const { - aLengthToCopy = min(aLengthToCopy, Length()); - aResult.SetLength(aLengthToCopy); - std::copy(End(aLengthToCopy), End(), aResult.Begin()); - return aLengthToCopy; + PRUint32 myLength = Length(); + aLengthToCopy = min(myLength, aLengthToCopy); + aResult = Substring(*this, myLength-aLengthToCopy, aLengthToCopy); + return aResult.Length(); } template @@ -665,7 +672,7 @@ basic_nsAReadableString::Compare( const basic_nsAReadableString& r will really want to do with the result. What might be better, though, is to return a `promise' to concatenate some strings... - By making |nsConcatString| inherit from readable strings, we automatically handle + By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle assignment and other interesting uses within writable strings, plus we drastically reduce the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work @@ -673,31 +680,31 @@ basic_nsAReadableString::Compare( const basic_nsAReadableString& r */ template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template diff --git a/string/public/nsAWritableString.h b/string/public/nsAWritableString.h index 750e5c46c99c..53657ad81ff7 100644 --- a/string/public/nsAWritableString.h +++ b/string/public/nsAWritableString.h @@ -179,6 +179,8 @@ class basic_nsAWritableString return Iterator(fragment, startPos); } + // virtual void Splice( ... ); + virtual void SetCapacity( PRUint32 ) = 0; virtual void SetLength( PRUint32 ) = 0; @@ -205,15 +207,54 @@ class basic_nsAWritableString // void CompressSet( ... ); // void CompareWhitespace( ... ); + virtual void Assign( const basic_nsAReadableString& rhs ); + // Assign // Append( ... ) // Insert // SetString - // operator=( ... ) - // operator+=( ... ) + + basic_nsAWritableString& + operator+=( const basic_nsAReadableString& rhs ) + { + Append(rhs); + return *this; + } + + basic_nsAWritableString& + operator+=( const basic_nsLiteralString& rhs ) + { + Append(rhs); + return *this; + } + + basic_nsAWritableString& + operator=( const basic_nsAReadableString& rhs ) + { + Assign(rhs); + return *this; + } + + basic_nsAWritableString& + operator=( const basic_nsLiteralString& rhs ) + { + Assign(rhs); + return *this; + } }; +NS_DEF_STRING_COMPARISONS(basic_nsAWritableString) + +template +void +basic_nsAWritableString::Assign( const basic_nsAReadableString& rhs ) + { + SetLength(rhs.Length()); + std::copy(rhs.Begin(), rhs.End(), Begin()); + } + + // operator>> // getline (maybe) diff --git a/string/public/nsSharedString.h b/string/public/nsSharedString.h index e7b4b51754c6..5d10c29ca3fd 100644 --- a/string/public/nsSharedString.h +++ b/string/public/nsSharedString.h @@ -56,7 +56,7 @@ class basic_nsSharedString mutable nsrefcnt mRefCount; }; -NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) +NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) diff --git a/xpcom/ds/nsAReadableString.h b/xpcom/ds/nsAReadableString.h index 15799b047c2d..f9c343bc8af7 100644 --- a/xpcom/ds/nsAReadableString.h +++ b/xpcom/ds/nsAReadableString.h @@ -72,8 +72,8 @@ NS_DEF_1_STRING_COMPARISON_OPERATOR(> , T1, T2) #define NS_DEF_STRING_COMPARISONS(T) \ - NS_DEF_STRING_COMPARISON_OPERATORS(const T&, const CharT*) \ - NS_DEF_STRING_COMPARISON_OPERATORS(const CharT*, const T&) + NS_DEF_STRING_COMPARISON_OPERATORS(const T&, const CharT*) \ + NS_DEF_STRING_COMPARISON_OPERATORS(const CharT*, const T&) template class basic_nsAWritableString; // ...because we sometimes use them as `out' params @@ -242,8 +242,8 @@ class basic_nsAReadableString // CharT First() const; // CharT Last() const; - void ToLowerCase( basic_nsAWritableString& ) const; - void ToUpperCase( basic_nsAWritableString& ) const; + // void ToLowerCase( basic_nsAWritableString& ) const; + // void ToUpperCase( basic_nsAWritableString& ) const; // PRUint32 CountChar( char_type ) const; @@ -296,7 +296,7 @@ class basic_nsAReadableString PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } }; -NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) +NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) @@ -366,10 +366,10 @@ class basic_nsLiteralString const CharT* mEnd; }; -NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) +NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) template -class nsConcatString +class nsPromiseConcatenation : public basic_nsAReadableString /* ...not unlike RickG's original |nsSubsumeString| in _intent_. @@ -385,7 +385,7 @@ class nsConcatString static const int kRightString = 1; public: - nsConcatString( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) + nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) { mStrings[kLeftString] = &aLeftString; mStrings[kRightString] = &aRightString; @@ -395,21 +395,21 @@ class nsConcatString private: const basic_nsAReadableString* mStrings[2]; - ConstFragment mFragment; + mutable ConstFragment mFragment; }; -NS_DEF_STRING_COMPARISONS(nsConcatString) +NS_DEF_STRING_COMPARISONS(nsPromiseConcatenation) template PRUint32 -nsConcatString::Length() const +nsPromiseConcatenation::Length() const { return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length(); } template const CharT* -nsConcatString::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const { const int kLeftString = 0; const int kRightString = 1; @@ -477,6 +477,68 @@ nsConcatString::GetFragment( ConstFragment& aFragment, FragmentRequest aR } +template +class nsPromiseSubstring + : public basic_nsAReadableString + { + typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; + typedef typename basic_nsAWritableString::ConstFragment ConstFragment; + + protected: + virtual const CharT* GetFragment( ConstFragment&, FragmentRequest, PRUint32 ) const; + + public: + nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) + : mString(aString), + mStartPos( min(aStartPos, aString.Length()) ), + mLength( min(aLength, aString.Length()-mStartPos) ) + { + // nothing else to do here + } + + virtual PRUint32 Length() const; + + private: + const basic_nsAReadableString& mString; + PRUint32 mStartPos; + PRUint32 mLength; + }; + +NS_DEF_STRING_COMPARISONS(nsPromiseSubstring) + +template +PRUint32 +nsPromiseSubstring::Length() const + { + return mLength; + } + +template +const CharT* +nsPromiseSubstring::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const + { + if ( aRequest == kFirstFragment ) + { + aPosition = mStartPos; + aRequest = kFragmentAt; + } + else if ( aRequest == kLastFragment ) + { + aPosition = mLength + mStartPos; + aRequest = kFragmentAt; + } + else if ( aRequest == kFragmentAt ) + aPosition += mStartPos; + + return mString.GetFragment(aFragment, aRequest, aPosition); + } + +template +nsPromiseSubstring +Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) + { + return nsPromiseSubstring(aString, aStartPos, aSubstringLength); + } template @@ -508,85 +570,30 @@ basic_nsLiteralString::Length() const -template -class do_ToLowerCase : unary_function - { - // std::locale loc; - // std::ctype ct; - - public: - // do_ToLowerCase() : ct( use_facet< std::ctype >(loc) ) { } - - CharT - operator()( CharT aChar ) - { - // return ct.tolower(aChar); - return CharT(std::tolower(aChar)); - } - }; - -template -void -basic_nsAReadableString::ToLowerCase( basic_nsAWritableString& aResult ) const - { - aResult.SetLength(Length()); - std::transform(Begin(), End(), aResult.Begin(), do_ToLowerCase()); - } - -template -class do_ToUpperCase : unary_function - { - // std::locale loc; - // std::ctype ct; - - public: - // do_ToUpperCase() : ct( use_facet< std::ctype >(loc) ) { } - - CharT - operator()( CharT aChar ) - { - // return ct.toupper(aChar); - return CharT(std::toupper(aChar)); - } - }; - -template -void -basic_nsAReadableString::ToUpperCase( basic_nsAWritableString& aResult ) const - { - aResult.SetLength(Length()); - std::transform(Begin(), End(), aResult.Begin(), do_ToUpperCase()); - } - template PRUint32 basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const { - aLengthToCopy = min(aLengthToCopy, Length()); - aResult.SetLength(aLengthToCopy); - std::copy(Begin(), Begin(aLengthToCopy), aResult.Begin()); - return aLengthToCopy; + aResult = Substring(*this, 0, aLengthToCopy); + return aResult.Length(); } template PRUint32 basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const { - aStartPos = min(aStartPos, Length()); - aLengthToCopy = min(aLengthToCopy, Length()-aStartPos); - aResult.SetLength(aLengthToCopy); - std::copy(Begin(aStartPos), Begin(aStartPos+aLengthToCopy), aResult.Begin()); - return aLengthToCopy; + aResult = Substring(*this, aStartPos, aLengthToCopy); + return aResult.Length(); } template PRUint32 basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const { - aLengthToCopy = min(aLengthToCopy, Length()); - aResult.SetLength(aLengthToCopy); - std::copy(End(aLengthToCopy), End(), aResult.Begin()); - return aLengthToCopy; + PRUint32 myLength = Length(); + aLengthToCopy = min(myLength, aLengthToCopy); + aResult = Substring(*this, myLength-aLengthToCopy, aLengthToCopy); + return aResult.Length(); } template @@ -665,7 +672,7 @@ basic_nsAReadableString::Compare( const basic_nsAReadableString& r will really want to do with the result. What might be better, though, is to return a `promise' to concatenate some strings... - By making |nsConcatString| inherit from readable strings, we automatically handle + By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle assignment and other interesting uses within writable strings, plus we drastically reduce the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work @@ -673,31 +680,31 @@ basic_nsAReadableString::Compare( const basic_nsAReadableString& r */ template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template diff --git a/xpcom/ds/nsAWritableString.h b/xpcom/ds/nsAWritableString.h index 750e5c46c99c..53657ad81ff7 100644 --- a/xpcom/ds/nsAWritableString.h +++ b/xpcom/ds/nsAWritableString.h @@ -179,6 +179,8 @@ class basic_nsAWritableString return Iterator(fragment, startPos); } + // virtual void Splice( ... ); + virtual void SetCapacity( PRUint32 ) = 0; virtual void SetLength( PRUint32 ) = 0; @@ -205,15 +207,54 @@ class basic_nsAWritableString // void CompressSet( ... ); // void CompareWhitespace( ... ); + virtual void Assign( const basic_nsAReadableString& rhs ); + // Assign // Append( ... ) // Insert // SetString - // operator=( ... ) - // operator+=( ... ) + + basic_nsAWritableString& + operator+=( const basic_nsAReadableString& rhs ) + { + Append(rhs); + return *this; + } + + basic_nsAWritableString& + operator+=( const basic_nsLiteralString& rhs ) + { + Append(rhs); + return *this; + } + + basic_nsAWritableString& + operator=( const basic_nsAReadableString& rhs ) + { + Assign(rhs); + return *this; + } + + basic_nsAWritableString& + operator=( const basic_nsLiteralString& rhs ) + { + Assign(rhs); + return *this; + } }; +NS_DEF_STRING_COMPARISONS(basic_nsAWritableString) + +template +void +basic_nsAWritableString::Assign( const basic_nsAReadableString& rhs ) + { + SetLength(rhs.Length()); + std::copy(rhs.Begin(), rhs.End(), Begin()); + } + + // operator>> // getline (maybe) diff --git a/xpcom/ds/nsSharedString.h b/xpcom/ds/nsSharedString.h index e7b4b51754c6..5d10c29ca3fd 100644 --- a/xpcom/ds/nsSharedString.h +++ b/xpcom/ds/nsSharedString.h @@ -56,7 +56,7 @@ class basic_nsSharedString mutable nsrefcnt mRefCount; }; -NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) +NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) diff --git a/xpcom/string/public/nsAReadableString.h b/xpcom/string/public/nsAReadableString.h index 15799b047c2d..f9c343bc8af7 100644 --- a/xpcom/string/public/nsAReadableString.h +++ b/xpcom/string/public/nsAReadableString.h @@ -72,8 +72,8 @@ NS_DEF_1_STRING_COMPARISON_OPERATOR(> , T1, T2) #define NS_DEF_STRING_COMPARISONS(T) \ - NS_DEF_STRING_COMPARISON_OPERATORS(const T&, const CharT*) \ - NS_DEF_STRING_COMPARISON_OPERATORS(const CharT*, const T&) + NS_DEF_STRING_COMPARISON_OPERATORS(const T&, const CharT*) \ + NS_DEF_STRING_COMPARISON_OPERATORS(const CharT*, const T&) template class basic_nsAWritableString; // ...because we sometimes use them as `out' params @@ -242,8 +242,8 @@ class basic_nsAReadableString // CharT First() const; // CharT Last() const; - void ToLowerCase( basic_nsAWritableString& ) const; - void ToUpperCase( basic_nsAWritableString& ) const; + // void ToLowerCase( basic_nsAWritableString& ) const; + // void ToUpperCase( basic_nsAWritableString& ) const; // PRUint32 CountChar( char_type ) const; @@ -296,7 +296,7 @@ class basic_nsAReadableString PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } }; -NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) +NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) @@ -366,10 +366,10 @@ class basic_nsLiteralString const CharT* mEnd; }; -NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) +NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) template -class nsConcatString +class nsPromiseConcatenation : public basic_nsAReadableString /* ...not unlike RickG's original |nsSubsumeString| in _intent_. @@ -385,7 +385,7 @@ class nsConcatString static const int kRightString = 1; public: - nsConcatString( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) + nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) { mStrings[kLeftString] = &aLeftString; mStrings[kRightString] = &aRightString; @@ -395,21 +395,21 @@ class nsConcatString private: const basic_nsAReadableString* mStrings[2]; - ConstFragment mFragment; + mutable ConstFragment mFragment; }; -NS_DEF_STRING_COMPARISONS(nsConcatString) +NS_DEF_STRING_COMPARISONS(nsPromiseConcatenation) template PRUint32 -nsConcatString::Length() const +nsPromiseConcatenation::Length() const { return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length(); } template const CharT* -nsConcatString::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const { const int kLeftString = 0; const int kRightString = 1; @@ -477,6 +477,68 @@ nsConcatString::GetFragment( ConstFragment& aFragment, FragmentRequest aR } +template +class nsPromiseSubstring + : public basic_nsAReadableString + { + typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; + typedef typename basic_nsAWritableString::ConstFragment ConstFragment; + + protected: + virtual const CharT* GetFragment( ConstFragment&, FragmentRequest, PRUint32 ) const; + + public: + nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) + : mString(aString), + mStartPos( min(aStartPos, aString.Length()) ), + mLength( min(aLength, aString.Length()-mStartPos) ) + { + // nothing else to do here + } + + virtual PRUint32 Length() const; + + private: + const basic_nsAReadableString& mString; + PRUint32 mStartPos; + PRUint32 mLength; + }; + +NS_DEF_STRING_COMPARISONS(nsPromiseSubstring) + +template +PRUint32 +nsPromiseSubstring::Length() const + { + return mLength; + } + +template +const CharT* +nsPromiseSubstring::GetFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const + { + if ( aRequest == kFirstFragment ) + { + aPosition = mStartPos; + aRequest = kFragmentAt; + } + else if ( aRequest == kLastFragment ) + { + aPosition = mLength + mStartPos; + aRequest = kFragmentAt; + } + else if ( aRequest == kFragmentAt ) + aPosition += mStartPos; + + return mString.GetFragment(aFragment, aRequest, aPosition); + } + +template +nsPromiseSubstring +Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) + { + return nsPromiseSubstring(aString, aStartPos, aSubstringLength); + } template @@ -508,85 +570,30 @@ basic_nsLiteralString::Length() const -template -class do_ToLowerCase : unary_function - { - // std::locale loc; - // std::ctype ct; - - public: - // do_ToLowerCase() : ct( use_facet< std::ctype >(loc) ) { } - - CharT - operator()( CharT aChar ) - { - // return ct.tolower(aChar); - return CharT(std::tolower(aChar)); - } - }; - -template -void -basic_nsAReadableString::ToLowerCase( basic_nsAWritableString& aResult ) const - { - aResult.SetLength(Length()); - std::transform(Begin(), End(), aResult.Begin(), do_ToLowerCase()); - } - -template -class do_ToUpperCase : unary_function - { - // std::locale loc; - // std::ctype ct; - - public: - // do_ToUpperCase() : ct( use_facet< std::ctype >(loc) ) { } - - CharT - operator()( CharT aChar ) - { - // return ct.toupper(aChar); - return CharT(std::toupper(aChar)); - } - }; - -template -void -basic_nsAReadableString::ToUpperCase( basic_nsAWritableString& aResult ) const - { - aResult.SetLength(Length()); - std::transform(Begin(), End(), aResult.Begin(), do_ToUpperCase()); - } - template PRUint32 basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const { - aLengthToCopy = min(aLengthToCopy, Length()); - aResult.SetLength(aLengthToCopy); - std::copy(Begin(), Begin(aLengthToCopy), aResult.Begin()); - return aLengthToCopy; + aResult = Substring(*this, 0, aLengthToCopy); + return aResult.Length(); } template PRUint32 basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const { - aStartPos = min(aStartPos, Length()); - aLengthToCopy = min(aLengthToCopy, Length()-aStartPos); - aResult.SetLength(aLengthToCopy); - std::copy(Begin(aStartPos), Begin(aStartPos+aLengthToCopy), aResult.Begin()); - return aLengthToCopy; + aResult = Substring(*this, aStartPos, aLengthToCopy); + return aResult.Length(); } template PRUint32 basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const { - aLengthToCopy = min(aLengthToCopy, Length()); - aResult.SetLength(aLengthToCopy); - std::copy(End(aLengthToCopy), End(), aResult.Begin()); - return aLengthToCopy; + PRUint32 myLength = Length(); + aLengthToCopy = min(myLength, aLengthToCopy); + aResult = Substring(*this, myLength-aLengthToCopy, aLengthToCopy); + return aResult.Length(); } template @@ -665,7 +672,7 @@ basic_nsAReadableString::Compare( const basic_nsAReadableString& r will really want to do with the result. What might be better, though, is to return a `promise' to concatenate some strings... - By making |nsConcatString| inherit from readable strings, we automatically handle + By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle assignment and other interesting uses within writable strings, plus we drastically reduce the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work @@ -673,31 +680,31 @@ basic_nsAReadableString::Compare( const basic_nsAReadableString& r */ template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template -nsConcatString +nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString& rhs ) { - return nsConcatString(lhs, rhs); + return nsPromiseConcatenation(lhs, rhs); } template diff --git a/xpcom/string/public/nsAWritableString.h b/xpcom/string/public/nsAWritableString.h index 750e5c46c99c..53657ad81ff7 100644 --- a/xpcom/string/public/nsAWritableString.h +++ b/xpcom/string/public/nsAWritableString.h @@ -179,6 +179,8 @@ class basic_nsAWritableString return Iterator(fragment, startPos); } + // virtual void Splice( ... ); + virtual void SetCapacity( PRUint32 ) = 0; virtual void SetLength( PRUint32 ) = 0; @@ -205,15 +207,54 @@ class basic_nsAWritableString // void CompressSet( ... ); // void CompareWhitespace( ... ); + virtual void Assign( const basic_nsAReadableString& rhs ); + // Assign // Append( ... ) // Insert // SetString - // operator=( ... ) - // operator+=( ... ) + + basic_nsAWritableString& + operator+=( const basic_nsAReadableString& rhs ) + { + Append(rhs); + return *this; + } + + basic_nsAWritableString& + operator+=( const basic_nsLiteralString& rhs ) + { + Append(rhs); + return *this; + } + + basic_nsAWritableString& + operator=( const basic_nsAReadableString& rhs ) + { + Assign(rhs); + return *this; + } + + basic_nsAWritableString& + operator=( const basic_nsLiteralString& rhs ) + { + Assign(rhs); + return *this; + } }; +NS_DEF_STRING_COMPARISONS(basic_nsAWritableString) + +template +void +basic_nsAWritableString::Assign( const basic_nsAReadableString& rhs ) + { + SetLength(rhs.Length()); + std::copy(rhs.Begin(), rhs.End(), Begin()); + } + + // operator>> // getline (maybe) diff --git a/xpcom/string/public/nsSharedString.h b/xpcom/string/public/nsSharedString.h index e7b4b51754c6..5d10c29ca3fd 100644 --- a/xpcom/string/public/nsSharedString.h +++ b/xpcom/string/public/nsSharedString.h @@ -56,7 +56,7 @@ class basic_nsSharedString mutable nsrefcnt mRefCount; }; -NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) +NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper)