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
- Re: Using a real parser generator to parse numbers (and dates) (continued)
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.