summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-06-11 12:07:44 +0200
committerMike Kaganski <mike.kaganski@collabora.com>2021-06-14 12:46:07 +0200
commit49b3b9d3391abb50aefe291d2ee0f8bca7eb6bd0 (patch)
treee75e5ade8acbf8aa3f040aa28ef08572752935ad /include
parentd376297c643785564e7bda1a74b573c35ade6cb8 (diff)
Assert on valid order of which ids in ranges on SfxItemSet creation
This allows to make sure we actually use sorted which ranges, and then it's safe to call SfxItemSet::MergeRange when needed. Also this change relaxes the previous requirement that ranges must be separated by at least one; this allows to have adjacent ranges, like in RES_FRMATR_BEGIN, RES_FRMATR_END-1, RES_GRFATR_BEGIN, RES_GRFATR_END-1, where RES_FRMATR_END is equal to RES_GRFATR_BEGIN. Allowing this makes possible to (1) self-document the ranges, so it's clear which ranges are included; and (2) be safe in case when these constants would change, so that the one merged range would not unexpectedly contain everything inserted between RES_FRMATR_END and RES_GRFATR_BEGIN. Change-Id: Iaad0f099b85059b3aa318a347aa7fbd3f6d455c7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116909 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> (cherry picked from commit 8aaa28ed43978a9a4a20d62368410a57ec05c23f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117114
Diffstat (limited to 'include')
-rw-r--r--include/svl/itemset.hxx39
1 files changed, 35 insertions, 4 deletions
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index 41a782d7966f..d4a9304a85dd 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -21,11 +21,13 @@
#include <sal/config.h>
+#include <array>
#include <cassert>
#include <cstddef>
#include <initializer_list>
#include <type_traits>
#include <memory>
+#include <utility>
#include <svl/svldllapi.h>
#include <svl/poolitem.hxx>
@@ -41,7 +43,7 @@ constexpr bool validRange(sal_uInt16 wid1, sal_uInt16 wid2)
{ return wid1 != 0 && wid1 <= wid2; }
constexpr bool validGap(sal_uInt16 wid1, sal_uInt16 wid2)
-{ return wid2 > wid1 && wid2 - wid1 > 1; }
+{ return wid2 > wid1; }
template<sal_uInt16 WID1, sal_uInt16 WID2> constexpr bool validRanges()
{ return validRange(WID1, WID2); }
@@ -52,6 +54,19 @@ constexpr bool validRanges() {
&& validRanges<WID3, WIDs...>();
}
+inline constexpr bool validRanges(const sal_uInt16* pRanges)
+{
+ for (auto p = pRanges; p && *p; p += 2)
+ {
+ if (!validRange(p[0], p[1]))
+ return false;
+ // ranges must be sorted
+ if (p[2] != 0 && !validGap(p[1], p[2]))
+ return false;
+ }
+ return true;
+}
+
// The calculations in rangeSize and rangesSize cannot overflow, assuming
// std::size_t is no smaller than sal_uInt16:
@@ -71,6 +86,24 @@ constexpr std::size_t rangesSize()
template<sal_uInt16... WIDs> struct Items {};
+// This allows creating compile-time which id arrays using syntax like
+//
+// constexpr auto aWids = svl::ItemsArray({ { widFrom1, widTo2 }, { widFrom2, widTo2 }, ... });
+//
+// so that e.g. clang-format would not try to rearrange the initializer sequence to break pairs.
+// Additionally, the array validity is checked in debug builds.
+template <size_t N> constexpr auto ItemsArray(const std::pair<sal_uInt16, sal_uInt16> (&wids)[N])
+{
+ std::array<sal_uInt16, N * 2 + 1> aArray{};
+ sal_uInt16* p = aArray.data();
+ for (const auto& [wid1, wid2] : wids)
+ {
+ *p++ = wid1;
+ *p++ = wid2;
+ }
+ assert(svl::detail::validRanges(aArray.data()));
+ return aArray;
+}
}
class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
@@ -88,7 +121,7 @@ friend class SfxItemPoolCache;
friend class SfxAllItemSet;
private:
- SVL_DLLPRIVATE void InitRanges_Impl(const sal_uInt16 *nWhichPairTable);
+ SVL_DLLPRIVATE sal_uInt16 InitRanges_Impl(const sal_uInt16 *nWhichPairTable);
SfxItemSet(
SfxItemPool & pool, std::initializer_list<sal_uInt16> wids,
@@ -249,8 +282,6 @@ class SVL_DLLPUBLIC SfxAllItemSet: public SfxItemSet
// Handles all Ranges. Ranges are automatically modified by putting items.
{
- sal_uInt16 nFree;
-
public:
SfxAllItemSet( SfxItemPool &rPool );
SfxAllItemSet( const SfxItemSet & );