summaryrefslogtreecommitdiff
path: root/include/svl/itemset.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'include/svl/itemset.hxx')
-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 & );