[Libreoffice-commits] core.git: include/o3tl include/sfx2 o3tl/CppunitTest_o3tl_tests.mk o3tl/qa sd/source sfx2/source sw/source

Noel Grandin noel.grandin at collabora.co.uk
Sat Jun 17 13:08:36 UTC 2017


 include/o3tl/array_view.hxx              |  169 +++++++++++++++++++++++++++++++
 include/sfx2/dispatch.hxx                |    3 
 o3tl/CppunitTest_o3tl_tests.mk           |    1 
 o3tl/qa/test-array_view.cxx              |   79 ++++++++++++++
 sd/source/ui/docshell/docshell.cxx       |    7 -
 sd/source/ui/inc/DrawDocShell.hxx        |    7 -
 sd/source/ui/slideshow/slideshowimpl.cxx |    4 
 sfx2/source/control/dispatch.cxx         |   18 +--
 sw/source/uibase/uiview/view.cxx         |    6 -
 9 files changed, 267 insertions(+), 27 deletions(-)

New commits:
commit 470752f50c146b449b1c9bdccc36ed031535663c
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Thu Jun 15 10:08:20 2017 +0200

    create o3tl::array_view
    
    A very basic implementation of the proposed std::array_view, similar to
    clang's llvm::ArrayRef.
    
    Mostly cribbed from the string_view implementation :-)
    
    Use it for the SfxDispatcher::setSlotFilter function
    
    Change-Id: Ife7e4971741b41827e145787899872c9b2bea82b
    Reviewed-on: https://gerrit.libreoffice.org/38817
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/include/o3tl/array_view.hxx b/include/o3tl/array_view.hxx
new file mode 100644
index 000000000000..9da86866680e
--- /dev/null
+++ b/include/o3tl/array_view.hxx
@@ -0,0 +1,169 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_O3TL_ARRAY_VIEW_HXX
+#define INCLUDED_O3TL_ARRAY_VIEW_HXX
+
+#include <sal/config.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <ios>
+#include <iterator>
+#include <ostream>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include <config_global.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+// A barebones approximation of C++17(?) <array_view>, haven't bothered with more than single-dimensional arrays
+
+#if HAVE_CXX14_CONSTEXPR
+#define CONSTEXPR constexpr
+#else
+#define CONSTEXPR
+#endif
+
+namespace o3tl {
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#pragma warning(disable: 4814) // in C++14 'constexpr' will not imply 'const'
+#endif
+
+template<typename T>
+class array_view {
+public:
+    using value_type = T;
+    using pointer = value_type *;
+    using const_pointer = value_type const *;
+    using reference = value_type &;
+    using const_reference = value_type const &;
+    using const_iterator = const_pointer;
+    using iterator = const_iterator;
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+    using reverse_iterator = const_reverse_iterator;
+    using size_type = std::size_t;
+    using difference_type = std::ptrdiff_t;
+
+    static constexpr size_type npos = size_type(-1);
+
+    constexpr array_view() noexcept : data_(nullptr), size_(0) {}
+
+    template<size_type N>
+    CONSTEXPR array_view (T const (&a)[N]) noexcept : data_(a), size_(N) {}
+
+    CONSTEXPR array_view (T const *a, size_type len) noexcept
+        : data_(a), size_(len)
+    {
+#if HAVE_CXX14_CONSTEXPR
+        // not terribly sure about this, might need to relax it
+        assert((a == nullptr && len == 0) || (a != nullptr && len > 0));
+#endif
+    }
+
+    constexpr bool            empty() const noexcept { return size_ == 0; }
+
+    constexpr const_iterator begin() const noexcept { return data_; }
+    constexpr const_iterator end() const noexcept { return begin() + size(); }
+
+    constexpr const_iterator cbegin() const noexcept { return begin(); }
+    constexpr const_iterator cend() const noexcept { return end(); }
+
+    constexpr const_reverse_iterator rbegin() const noexcept
+    { return const_reverse_iterator(end()); }
+    constexpr const_reverse_iterator rend() const noexcept
+    { return const_reverse_iterator(begin()); }
+
+    constexpr const_reverse_iterator crbegin() const noexcept
+    { return rbegin(); }
+    constexpr const_reverse_iterator crend() const noexcept { return rend(); }
+
+    constexpr size_type size() const noexcept { return size_; }
+    constexpr size_type length() const noexcept { return size(); }
+
+#if !defined __clang__ || HAVE_CXX14_CONSTEXPR
+    constexpr
+#endif
+    size_type max_size() const noexcept {
+#if defined __clang__ // avoid constexpr issues with other, older compilers
+        (void) this; // loplugin:staticmethods
+#endif
+        return npos - 1;
+    }
+
+    constexpr const_reference operator [](size_type pos) const {
+#if HAVE_CXX14_CONSTEXPR
+        assert(pos < size());
+#endif
+        return data_[pos];
+    }
+
+    CONSTEXPR
+    const_reference at(size_type pos) const {
+        if (pos >= size()) {
+            throw std::out_of_range("o3tl::array_view::at");
+        }
+        return operator [](pos);
+    }
+
+    constexpr const_reference front() const {
+#if HAVE_CXX14_CONSTEXPR
+        assert(!empty());
+#endif
+        return operator [](0);
+    }
+
+    constexpr const_reference back() const {
+#if HAVE_CXX14_CONSTEXPR
+        assert(!empty());
+#endif
+        return operator [](size() - 1);
+    }
+
+    constexpr const_pointer data() const noexcept { return data_; }
+
+    CONSTEXPR void swap(array_view & s) noexcept {
+        std::swap(data_, s.data_);
+        std::swap(size_, s.size_);
+    }
+
+private:
+    const_pointer data_;
+    size_type     size_;
+};
+
+
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+} // namespace o3tl
+
+namespace std {
+
+template<typename T>
+struct hash<o3tl::array_view<T>> {
+    std::size_t operator()(o3tl::array_view<T> s)
+    { return hash<T[]>()(s.data(), s.size()); }
+};
+
+} // namespace std
+
+
+#undef CONSTEXPR
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/sfx2/dispatch.hxx b/include/sfx2/dispatch.hxx
index b089764713e9..ca65eeecb198 100644
--- a/include/sfx2/dispatch.hxx
+++ b/include/sfx2/dispatch.hxx
@@ -29,6 +29,7 @@
 #include <sfx2/viewfrm.hxx>
 #include <vcl/menu.hxx>
 #include <o3tl/typed_flags_set.hxx>
+#include <o3tl/array_view.hxx>
 
 #include <initializer_list>
 
@@ -159,7 +160,7 @@ public:
     void                Lock( bool bLock );
     bool                IsLocked() const;
     void                SetSlotFilter( SfxSlotFilterState nEnable = SfxSlotFilterState::DISABLED,
-                                       sal_uInt16 nCount = 0, const sal_uInt16 *pSIDs = nullptr );
+                                       o3tl::array_view<sal_uInt16> pSIDs = o3tl::array_view<sal_uInt16>());
 
     void                HideUI( bool bHide = true );
     ToolbarId           GetObjectBarId( sal_uInt16 nPos ) const;
diff --git a/o3tl/CppunitTest_o3tl_tests.mk b/o3tl/CppunitTest_o3tl_tests.mk
index 55c1fee84a20..01a7cc0cbdc5 100644
--- a/o3tl/CppunitTest_o3tl_tests.mk
+++ b/o3tl/CppunitTest_o3tl_tests.mk
@@ -27,6 +27,7 @@ $(eval $(call gb_CppunitTest_use_libraries,o3tl_tests,\
 
 $(eval $(call gb_CppunitTest_add_exception_objects,o3tl_tests,\
 	o3tl/qa/cow_wrapper_clients \
+	o3tl/qa/test-array_view \
 	o3tl/qa/test-cow_wrapper \
 	o3tl/qa/test-lru_map \
 	o3tl/qa/test-sorted_vector \
diff --git a/o3tl/qa/test-array_view.cxx b/o3tl/qa/test-array_view.cxx
new file mode 100644
index 000000000000..3a19c093304a
--- /dev/null
+++ b/o3tl/qa/test-array_view.cxx
@@ -0,0 +1,79 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <stdexcept>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <o3tl/array_view.hxx>
+
+namespace {
+
+class Test: public CppUnit::TestFixture {
+private:
+    CPPUNIT_TEST_SUITE(Test);
+    CPPUNIT_TEST(testOperations);
+    CPPUNIT_TEST_SUITE_END();
+
+
+    void testOperations() {
+        int some_data[] { 1, 2, 3 };
+        o3tl::array_view<int> v(some_data);
+
+        CPPUNIT_ASSERT_EQUAL(1, *v.begin());
+        CPPUNIT_ASSERT_EQUAL(
+            o3tl::array_view<int>::difference_type(3), v.end() - v.begin());
+        CPPUNIT_ASSERT_EQUAL(1, *v.cbegin());
+        CPPUNIT_ASSERT_EQUAL(
+            o3tl::array_view<int>::difference_type(3), v.cend() - v.cbegin());
+        CPPUNIT_ASSERT_EQUAL(3, *v.rbegin());
+        CPPUNIT_ASSERT_EQUAL(
+            o3tl::array_view<int>::difference_type(3), v.rend() - v.rbegin());
+        CPPUNIT_ASSERT_EQUAL(3, *v.crbegin());
+        CPPUNIT_ASSERT_EQUAL(
+            o3tl::array_view<int>::difference_type(3), v.crend() - v.crbegin());
+        CPPUNIT_ASSERT_EQUAL(o3tl::array_view<int>::size_type(3), v.size());
+        CPPUNIT_ASSERT_EQUAL(o3tl::array_view<int>::size_type(3), v.length());
+        CPPUNIT_ASSERT_EQUAL(o3tl::array_view<int>::npos - 1, v.max_size());
+        CPPUNIT_ASSERT(!v.empty());
+        CPPUNIT_ASSERT_EQUAL(2, v[1]);
+        try {
+            v.at(o3tl::array_view<int>::npos);
+            CPPUNIT_FAIL("missing exception");
+        } catch (std::out_of_range &) {}
+        CPPUNIT_ASSERT_EQUAL(1, v.at(0));
+        CPPUNIT_ASSERT_EQUAL(3, v.at(2));
+        try {
+            v.at(3);
+            CPPUNIT_FAIL("missing exception");
+        } catch (std::out_of_range &) {}
+        CPPUNIT_ASSERT_EQUAL(1, v.front());
+        CPPUNIT_ASSERT_EQUAL(3, v.back());
+        CPPUNIT_ASSERT_EQUAL(1, *v.data());
+        {
+            int d1[] { 1, 2 };
+            int d2[] { 3, 4, 5, 6 };
+            o3tl::array_view<int> v1( d1 );
+            o3tl::array_view<int> v2( d2 );
+            v1.swap(v2);
+            CPPUNIT_ASSERT_EQUAL(o3tl::array_view<int>::size_type(4), v1.size());
+            CPPUNIT_ASSERT_EQUAL(o3tl::array_view<int>::size_type(2), v2.size());
+        }
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sd/source/ui/docshell/docshell.cxx b/sd/source/ui/docshell/docshell.cxx
index 799c2cfaa907..77d7cf641c8b 100644
--- a/sd/source/ui/docshell/docshell.cxx
+++ b/sd/source/ui/docshell/docshell.cxx
@@ -124,7 +124,6 @@ DrawDocShell::DrawDocShell(SfxObjectCreateMode eMode,
     mpViewShell(nullptr),
     mpFontList(nullptr),
     meDocType(eDocumentType),
-    mpFilterSIDs(nullptr),
     mbSdDataObj(bDataObject),
     mbOwnPrinter(false),
     mbNewDocument( true )
@@ -140,7 +139,6 @@ DrawDocShell::DrawDocShell( SfxModelFlags nModelCreationFlags, bool bDataObject,
     mpViewShell(nullptr),
     mpFontList(nullptr),
     meDocType(eDocumentType),
-    mpFilterSIDs(nullptr),
     mbSdDataObj(bDataObject),
     mbOwnPrinter(false),
     mbNewDocument( true )
@@ -158,7 +156,6 @@ DrawDocShell::DrawDocShell(SdDrawDocument* pDoc, SfxObjectCreateMode eMode,
     mpViewShell(nullptr),
     mpFontList(nullptr),
     meDocType(eDocumentType),
-    mpFilterSIDs(nullptr),
     mbSdDataObj(bDataObject),
     mbOwnPrinter(false),
     mbNewDocument( true )
@@ -405,8 +402,8 @@ void DrawDocShell::ApplySlotFilter() const
         {
             SfxDispatcher* pDispatcher = pTestViewShell->GetViewFrame()->GetDispatcher();
 
-            if( mpFilterSIDs )
-                pDispatcher->SetSlotFilter( mbFilterEnable ? SfxSlotFilterState::ENABLED : SfxSlotFilterState::DISABLED, mnFilterCount, mpFilterSIDs );
+            if( !mpFilterSIDs.empty() )
+                pDispatcher->SetSlotFilter( mbFilterEnable ? SfxSlotFilterState::ENABLED : SfxSlotFilterState::DISABLED, mpFilterSIDs );
             else
                 pDispatcher->SetSlotFilter();
 
diff --git a/sd/source/ui/inc/DrawDocShell.hxx b/sd/source/ui/inc/DrawDocShell.hxx
index a4e3deeb5901..3dad521b119f 100644
--- a/sd/source/ui/inc/DrawDocShell.hxx
+++ b/sd/source/ui/inc/DrawDocShell.hxx
@@ -20,6 +20,7 @@
 #ifndef INCLUDED_SD_SOURCE_UI_INC_DRAWDOCSHELL_HXX
 #define INCLUDED_SD_SOURCE_UI_INC_DRAWDOCSHELL_HXX
 
+#include <o3tl/array_view.hxx>
 #include <sfx2/docfac.hxx>
 #include <sfx2/objsh.hxx>
 
@@ -152,7 +153,7 @@ public:
      */
     bool                    CheckPageName(vcl::Window* pWin, OUString& rName );
 
-    void                    SetSlotFilter(bool bEnable = false, sal_uInt16 nCount = 0, const sal_uInt16* pSIDs = nullptr) { mbFilterEnable = bEnable; mnFilterCount = nCount; mpFilterSIDs = pSIDs; }
+    void                    SetSlotFilter(bool bEnable = false, o3tl::array_view<sal_uInt16> pSIDs = o3tl::array_view<sal_uInt16>()) { mbFilterEnable = bEnable; mpFilterSIDs = pSIDs; }
     void                    ApplySlotFilter() const;
 
     SfxStyleFamily          GetStyleFamily() const { return mnStyleFamily; }
@@ -218,8 +219,8 @@ protected:
     rtl::Reference<FuPoor> mxDocShellFunction;
     DocumentType            meDocType;
     SfxStyleFamily          mnStyleFamily;
-    const sal_uInt16*       mpFilterSIDs;
-    sal_uInt16              mnFilterCount;
+    o3tl::array_view<sal_uInt16>
+                            mpFilterSIDs;
     bool                    mbFilterEnable;
     bool                    mbSdDataObj;
     bool                    mbInDestruction;
diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx
index 6174640dc8f5..327ecb633bb4 100644
--- a/sd/source/ui/slideshow/slideshowimpl.cxx
+++ b/sd/source/ui/slideshow/slideshowimpl.cxx
@@ -925,7 +925,7 @@ bool SlideshowImpl::startShow( PresentationSettingsEx* pPresSettings )
             // these Slots are forbidden in other views for this document
             if( mpDocSh )
             {
-                mpDocSh->SetSlotFilter( true, SAL_N_ELEMENTS( pAllowed ), pAllowed );
+                mpDocSh->SetSlotFilter( true, pAllowed );
                 mpDocSh->ApplySlotFilter();
             }
 
@@ -2453,7 +2453,7 @@ void SAL_CALL SlideshowImpl::activate()
                 if( pDispatcher )
                 {
                     // filter all forbidden slots
-                    pDispatcher->SetSlotFilter( SfxSlotFilterState::ENABLED, SAL_N_ELEMENTS(pAllowed), pAllowed );
+                    pDispatcher->SetSlotFilter( SfxSlotFilterState::ENABLED, pAllowed );
                 }
 
                 if( getBindings() )
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index 15b445663deb..c4435e113e9a 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -139,8 +139,8 @@ struct SfxDispatcher_Impl
 
     SfxSlotFilterState   nFilterEnabling; // 1==filter enabled slots,
                                           // 2==ReadOnlyDoc overturned
-    sal_uInt16           nFilterCount;  // Number of SIDs in pFilterSIDs
-    const sal_uInt16*    pFilterSIDs;   // sorted Array of SIDs
+    o3tl::array_view<sal_uInt16>
+                         pFilterSIDs;   // sorted Array of SIDs
     SfxDisableFlags      nDisableFlags;
     bool                 bFlushed;
     std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack;
@@ -422,8 +422,6 @@ void SfxDispatcher::Construct_Impl()
     xImp->bModal = false;
     xImp->pInCallAliveFlag = nullptr;
     xImp->nFilterEnabling = SfxSlotFilterState::DISABLED;
-    xImp->nFilterCount = 0;
-    xImp->pFilterSIDs = nullptr;
     xImp->nDisableFlags = SfxDisableFlags::NONE;
 
     xImp->pParent = nullptr;
@@ -1637,19 +1635,15 @@ void SfxDispatcher::FlushImpl()
         pDisp->SetSlotFilter();
 */
 void SfxDispatcher::SetSlotFilter(SfxSlotFilterState nEnable,
-        sal_uInt16 nCount, const sal_uInt16* pSIDs)
+        o3tl::array_view<sal_uInt16> pSIDs)
 {
 #ifdef DBG_UTIL
     // Check Array
-    for ( sal_uInt16 n = 1; n < nCount; ++n )
+    for ( size_t n = 1; n < pSIDs.size(); ++n )
         DBG_ASSERT( pSIDs[n] > pSIDs[n-1], "SetSlotFilter: SIDs not sorted" );
 #endif
 
-    if ( xImp->pFilterSIDs )
-        xImp->pFilterSIDs = nullptr;
-
     xImp->nFilterEnabling = nEnable;
-    xImp->nFilterCount = nCount;
     xImp->pFilterSIDs = pSIDs;
 
     GetBindings()->InvalidateAll(true);
@@ -1671,12 +1665,12 @@ extern "C" int SAL_CALL SfxCompareSIDs_Impl(const void* pSmaller, const void* pB
 SfxSlotFilterState SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID ) const
 {
     // no filter?
-    if ( 0 == xImp->nFilterCount )
+    if ( xImp->pFilterSIDs.empty() )
         // => all SIDs allowed
         return SfxSlotFilterState::ENABLED;
 
     // search
-    bool bFound = nullptr != bsearch( &nSID, xImp->pFilterSIDs, xImp->nFilterCount,
+    bool bFound = nullptr != bsearch( &nSID, xImp->pFilterSIDs.data(), xImp->pFilterSIDs.size(),
                                 sizeof(sal_uInt16), SfxCompareSIDs_Impl );
 
     // even if ReadOnlyDoc
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index 08f69fe9c533..752cdca79381 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -588,7 +588,7 @@ void SwView::CheckReadonlyState()
         }
         if ( SfxItemState::DISABLED == eStateRO )
         {
-            rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, SAL_N_ELEMENTS(aROIds), aROIds );
+            rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aROIds );
             bChgd = true;
         }
     }
@@ -603,9 +603,7 @@ void SwView::CheckReadonlyState()
                 qsort( static_cast<void*>(aAllProtIds), SAL_N_ELEMENTS(aAllProtIds), sizeof(sal_uInt16), lcl_CmpIds );
                 bAllProtFirst = false;
             }
-            rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY,
-                                SAL_N_ELEMENTS(aAllProtIds),
-                                aAllProtIds );
+            rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aAllProtIds );
             bChgd = true;
         }
     }


More information about the Libreoffice-commits mailing list