diff options
Diffstat (limited to 'include/svl')
-rw-r--r-- | include/svl/itempool.hxx | 5 | ||||
-rw-r--r-- | include/svl/itemset.hxx | 52 | ||||
-rw-r--r-- | include/svl/whichranges.hxx | 74 | ||||
-rw-r--r-- | include/svl/whiter.hxx | 7 |
4 files changed, 116 insertions, 22 deletions
diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx index 0ff1c8d4b27a..8d1f2324363b 100644 --- a/include/svl/itempool.hxx +++ b/include/svl/itempool.hxx @@ -23,6 +23,7 @@ #include <svl/poolitem.hxx> #include <svl/svldllapi.h> #include <svl/typedwhich.hxx> +#include <svl/whichranges.hxx> #include <memory> #include <vector> #include <o3tl/sorted_vector.hxx> @@ -63,8 +64,8 @@ private: public: // for default SfxItemSet::CTOR, set default WhichRanges - void FillItemIdRanges_Impl( std::unique_ptr<sal_uInt16[]>& pWhichRanges ) const; - const sal_uInt16* GetFrozenIdRanges() const; + void FillItemIdRanges_Impl( WhichRangesContainer& pWhichRanges ) const; + const WhichRangesContainer & GetFrozenIdRanges() const; protected: static inline void ClearRefCount(SfxPoolItem& rItem); diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index 7c85e7534f59..efae21b3be61 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -32,6 +32,7 @@ #include <svl/svldllapi.h> #include <svl/poolitem.hxx> #include <svl/typedwhich.hxx> +#include <svl/whichranges.hxx> class SfxItemPool; @@ -84,7 +85,12 @@ constexpr std::size_t rangesSize() } -template<sal_uInt16... WIDs> struct Items {}; +template<sal_uInt16... WIDs> struct Items +{ + // This is passed to WhichRangesContainer so we can avoid needing to malloc() + // for compile-time data. + static constexpr std::array<sal_uInt16, sizeof...(WIDs)> value = { { WIDs... } }; +}; } @@ -96,18 +102,18 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet const SfxItemSet* m_pParent; ///< derivation std::unique_ptr<SfxPoolItem const*[]> m_pItems; ///< array of items - sal_uInt16* m_pWhichRanges; ///< array of Which Ranges + WhichRangesContainer m_pWhichRanges; ///< array of Which Ranges sal_uInt16 m_nCount; ///< number of items friend class SfxItemPoolCache; friend class SfxAllItemSet; private: - SVL_DLLPRIVATE sal_uInt16 InitRanges_Impl(const sal_uInt16 *nWhichPairTable); + SVL_DLLPRIVATE void RecreateRanges_Impl(const WhichRangesContainer& pNewRanges); - SfxItemSet( - SfxItemPool & pool, std::initializer_list<sal_uInt16> wids, - std::size_t items); + SfxItemSet( SfxItemPool & pool, const WhichRangesContainer& wids, std::size_t items ); + SfxItemSet( SfxItemPool & pool, WhichRangesContainer&& wids, std::size_t items ); + SfxItemSet( SfxItemPool & pool, std::initializer_list<sal_uInt16> wids, std::size_t items ); public: SfxPoolItem const** GetItems_Impl() const { return m_pItems.get(); } @@ -123,21 +129,32 @@ protected: virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bPassingOwnership ); + /** special constructor for SfxAllItemSet */ + enum class SfxAllItemSetFlag { Flag }; + SfxItemSet( SfxItemPool&, SfxAllItemSetFlag ); + public: struct Pair { sal_uInt16 wid1, wid2; }; + SfxItemSet( const SfxItemSet& ); + SfxItemSet( SfxItemSet&& ) noexcept; + SfxItemSet( SfxItemPool& ); + SfxItemSet( SfxItemPool&, const WhichRangesContainer& ranges ); + SfxItemSet( SfxItemPool&, WhichRangesContainer&& ranges ); - SfxItemSet( const SfxItemSet& ); - SfxItemSet( SfxItemSet&& ) noexcept; + SfxItemSet( SfxItemPool& rPool, sal_uInt16 nWhichStart, sal_uInt16 nWhichEnd ) + : SfxItemSet(rPool, WhichRangesContainer(nWhichStart, nWhichEnd)) {} - SfxItemSet( SfxItemPool&); - template<sal_uInt16... WIDs> SfxItemSet( + template<sal_uInt16... WIDs> + SfxItemSet( typename std::enable_if< svl::detail::validRanges<WIDs...>(), SfxItemPool &>::type pool, - svl::Items<WIDs...>): - SfxItemSet(pool, {WIDs...}, svl::detail::rangesSize<WIDs...>()) {} - SfxItemSet( SfxItemPool&, std::initializer_list<Pair> wids ); - SfxItemSet( SfxItemPool&, const sal_uInt16* nWhichPairTable ); - virtual ~SfxItemSet(); + svl::Items<WIDs...>) + : SfxItemSet(pool, WhichRangesContainer(svl::Items<WIDs...>::value), svl::detail::rangesSize<WIDs...>()) {} + + SfxItemSet( SfxItemPool&, std::initializer_list<Pair> wids ); + SfxItemSet( SfxItemPool&, const sal_uInt16* nWhichPairTable ); + + virtual ~SfxItemSet(); virtual std::unique_ptr<SfxItemSet> Clone(bool bItems = true, SfxItemPool *pToPool = nullptr) const; virtual SfxItemSet CloneAsValue(bool bItems = true, SfxItemPool *pToPool = nullptr) const; @@ -231,8 +248,9 @@ public: void MergeValue( const SfxPoolItem& rItem, bool bOverwriteDefaults = false ); SfxItemPool* GetPool() const { return m_pPool; } - const sal_uInt16* GetRanges() const { return m_pWhichRanges; } - void SetRanges( const sal_uInt16 *pRanges ); + const WhichRangesContainer & GetRanges() const { return m_pWhichRanges; } + void SetRanges( const WhichRangesContainer& ); + void SetRanges( WhichRangesContainer&& ); void MergeRange( sal_uInt16 nFrom, sal_uInt16 nTo ); const SfxItemSet* GetParent() const { return m_pParent; } diff --git a/include/svl/whichranges.hxx b/include/svl/whichranges.hxx new file mode 100644 index 000000000000..b1e87bba38b4 --- /dev/null +++ b/include/svl/whichranges.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include <sal/config.h> +#include <sal/types.h> +#include <svl/svldllapi.h> +#include <array> +#include <memory> +#include <cassert> + +typedef std::pair<sal_uInt16, sal_uInt16> WhichPair; + +/** + * Most of the time, the which ranges we point at are a compile-time literal. + * So we take advantage of that, and avoid the cost of allocating our own array and copying into it. + */ +struct SVL_DLLPUBLIC WhichRangesContainer +{ + using const_iterator = WhichPair const*; + + WhichPair const* m_pairs = nullptr; + sal_Int32 m_size = 0; + /** if true, we allocated and need to delete the pairs, if not, we are pointing + * at a global const literal */ + bool m_bOwnRanges = false; + + WhichRangesContainer() {} + + WhichRangesContainer(std::unique_ptr<WhichPair[]> wids, sal_Int32 nSize) + : m_pairs(wids.release()) + , m_size(nSize) + , m_bOwnRanges(true) + { + } + template <std::size_t N> + WhichRangesContainer(const std::array<sal_uInt16, N>& ranges) + : m_pairs(reinterpret_cast<const WhichPair*>(ranges.data())) + , m_size(static_cast<sal_Int32>(N / 2)) + , m_bOwnRanges(false) + { + } + WhichRangesContainer(const WhichPair* wids, sal_Int32 nSize); + WhichRangesContainer(sal_uInt16 nWhichStart, sal_uInt16 nWhichEnd); + WhichRangesContainer(WhichRangesContainer const& other) { operator=(other); } + WhichRangesContainer(WhichRangesContainer&& other); + ~WhichRangesContainer(); + + WhichRangesContainer& operator=(WhichRangesContainer&& other); + WhichRangesContainer& operator=(WhichRangesContainer const& other); + + bool operator==(WhichRangesContainer const& other) const; + const_iterator begin() const noexcept { return m_pairs; } + const_iterator end() const noexcept { return begin() + size(); } + bool empty() const noexcept { return m_size == 0; } + sal_Int32 size() const noexcept { return m_size; } + WhichPair const& operator[](sal_Int32 idx) const noexcept + { + assert(idx >= 0 && idx < size() && "index out of range"); + return m_pairs[idx]; + } + void reset(); + + // Adds a range to which ranges, keeping the ranges in valid state (sorted, non-overlapping) + WhichRangesContainer MergeRange(sal_uInt16 nFrom, sal_uInt16 nTo) const; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/svl/whiter.hxx b/include/svl/whiter.hxx index be584fc23911..c4a49a06b622 100644 --- a/include/svl/whiter.hxx +++ b/include/svl/whiter.hxx @@ -20,19 +20,20 @@ #define INCLUDED_SVL_WHITER_HXX #include <svl/svldllapi.h> +#include <svl/whichranges.hxx> class SfxItemSet; class SVL_DLLPUBLIC SfxWhichIter { - const sal_uInt16* const pStart; - const sal_uInt16* pRanges; + const WhichRangesContainer& pStart; + const WhichPair* pRanges; sal_uInt16 nOffset; public: SfxWhichIter(const SfxItemSet& rSet); - sal_uInt16 GetCurWhich() const { return pRanges[0] + nOffset; } + sal_uInt16 GetCurWhich() const; sal_uInt16 NextWhich(); sal_uInt16 FirstWhich(); }; |