Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


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.

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.