On Wed, Feb 29, 2012 at 02:57:09PM +0100, Stephan Bergmann wrote:
> On 02/29/2012 11:49 AM, Lionel Elie Mamane wrote:
>>2) I add a const_iterator interface to rtl::OUString. Instead of
>> coding it manually to use iterateCodePoints, I again reuse the
>> power of boost.
>> That's also more generally a more "C++ natural" interface to
>> OUStrings, so we can use it throughout our codebase instead of
>> iterateCodePoints.
>> I don't define an iterator interface, as this could be *extremely*
>> slow: writing one character in the middle of a string is O(n)
>> (linear in the length of the string) when replacing a
>> surrogates-encoded codepoint by a non-surrogate encoded one and
> > vice-versa.
> [...]
>>5) I've stuck the LibreOffice<->Spirit integration in
>> svl/source/numbers/spirit/, but possibly we could move it to a more
>> general location (sal/rtl?) so that it can be reused in other parts
>> of LibreOffice.
> Note that the stable sal interface historically stays clear of
> boost, because of differences in the various boost versions
> available in the various environments.
OK, two prongs:
1) Use of boost in rtl/ustring.hxx
But this is completely header-only code, so no ABI probl...^W Ah
no, you are right; if the size or memory layout of a
boost::u16_to_u32_iterator changes, there will be problems when
passing a const_iterator between old binaries and new binaries.
So here's the patch for a boost-free OUString, with manually
implemented const_iterator.
2) So, OK if we don't put the LibO<->spirit integration in sal/,
what's the right place? In tools? I didn't envision it becoming
part of our "external" ABI, only for internal use in LibO's source
code.
--
Lionel
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index 27d3750..4e34649 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -45,7 +45,7 @@
#include <new>
#endif
-#include <boost/regex/pending/unicode_iterator.hpp>
+#include <iterator>
namespace rtl
{
@@ -80,9 +80,73 @@ class OUString
public:
/** @internal */
rtl_uString * pData;
- typedef boost::u16_to_u32_iterator<const sal_Unicode*> const_iterator;
- const_iterator begin() const { return boost::u16_to_u32_iterator<const sal_Unicode*>(getStr()); };
- const_iterator end() const { return boost::u16_to_u32_iterator<const sal_Unicode*>(getStr() + getLength()); };
+ class const_iterator : std::iterator< std::random_access_iterator_tag, sal_uInt32, sal_Int32, const sal_uInt32*, const sal_uInt32>
+ {
+ const OUString *pStr;
+ sal_Int32 nPos;
+ // default copy-constructor OK
+ // default operator= OK
+ public:
+ const_iterator(const OUString *s = NULL, sal_Int32 p = 0) : pStr(s), nPos(p)
+ {
+ OSL_ASSERT( p <= s->getLength() );
+ if ( p < s->getLength() )
+ {
+ // The code unit at this place should *not* be a trail surrogate.
+ // Can be either a BMP codepoint (0x0000..0xD7FF or 0xE000..0xFFFF)
+ // or a lead surrogate (0xD800..0xDBFF).
+ sal_Unicode c((*s)[p]);
+ c &= 0xFC00;
+ OSL_ASSERT( c != 0xDC00 );
+ }
+ };
+ const_iterator& operator++() { pStr->iterateCodePoints(&nPos); return *this; };
+ const_iterator operator++(int) { const_iterator t(pStr, nPos); pStr->iterateCodePoints(&nPos); return t; };
+ const_iterator& operator--() { pStr->iterateCodePoints(&nPos, -1); return *this; };
+ const_iterator operator--(int) { const_iterator t(pStr, nPos); pStr->iterateCodePoints(&nPos, -1); return t; };
+ const_iterator& operator+=(sal_Int32 i) { pStr->iterateCodePoints(&nPos, i); return *this; }
+ const_iterator& operator-=(sal_Int32 i) { pStr->iterateCodePoints(&nPos, -i); return *this; }
+ bool operator==(const const_iterator i) const { return nPos == i.nPos; }
+ bool operator!=(const const_iterator i) const { return nPos != i.nPos; }
+ const_iterator operator+(sal_Int32 i) const { const_iterator t(*this); t+=i; return t; }
+ const_iterator operator-(sal_Int32 i) const { const_iterator t(*this); t-=i; return t; }
+ sal_Int32 operator-(const const_iterator i) const
+ {
+ // complexity O(getLength()) !
+ OSL_ASSERT(pStr == i.pStr);
+ sal_Int32 d(0);
+ const_iterator t(i);
+ while (*this > t)
+ {
+ ++d;
+ ++t;
+ }
+ while (*this < t)
+ {
+ --d;
+ --t;
+ }
+ return d;
+ }
+ sal_uInt32 operator*() const
+ {
+ // iterateCodePoints is supposed *not* to change nPos when passed 0 as second argument
+ return pStr->iterateCodePoints(const_cast<sal_Int32*>(&nPos), 0);
+ }
+ sal_uInt32 operator[](sal_Int32 index)
+ {
+ const_iterator t(pStr, 0);
+ // complexity O(getLength()) !
+ t += index;
+ return *t;
+ }
+ bool operator< (const const_iterator i) const { OSL_ASSERT(pStr == i.pStr); return nPos < i.nPos; }
+ bool operator<=(const const_iterator i) const { OSL_ASSERT(pStr == i.pStr); return nPos <= i.nPos; }
+ bool operator> (const const_iterator i) const { OSL_ASSERT(pStr == i.pStr); return nPos > i.nPos; }
+ bool operator>=(const const_iterator i) const { OSL_ASSERT(pStr == i.pStr); return nPos >= i.nPos; }
+ };
+ const_iterator begin() const { return const_iterator(this, 0); };
+ const_iterator end() const { return const_iterator(this, getLength()); };
private:
/** @internal */
@@ -1508,6 +1572,8 @@ public:
}
};
+inline OUString::const_iterator operator+(sal_Int32 i, const OUString::const_iterator p) { return p+i; }
+
/* ======================================================================= */
/** A helper to use OUStrings with hash maps.
_______________________________________________
LibreOffice mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/libreoffice