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

Reply via email to