diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-06-15 10:08:20 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-06-17 15:08:07 +0200 |
commit | 470752f50c146b449b1c9bdccc36ed031535663c (patch) | |
tree | 92e5af3b31e63e6cffdcc51717d1bd6584c59729 | |
parent | 561a02ec72cf963d7cd59cfb9a183c1032f0861b (diff) |
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@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | include/o3tl/array_view.hxx | 169 | ||||
-rw-r--r-- | include/sfx2/dispatch.hxx | 3 | ||||
-rw-r--r-- | o3tl/CppunitTest_o3tl_tests.mk | 1 | ||||
-rw-r--r-- | o3tl/qa/test-array_view.cxx | 79 | ||||
-rw-r--r-- | sd/source/ui/docshell/docshell.cxx | 7 | ||||
-rw-r--r-- | sd/source/ui/inc/DrawDocShell.hxx | 7 | ||||
-rw-r--r-- | sd/source/ui/slideshow/slideshowimpl.cxx | 4 | ||||
-rw-r--r-- | sfx2/source/control/dispatch.cxx | 18 | ||||
-rw-r--r-- | sw/source/uibase/uiview/view.cxx | 6 |
9 files changed, 267 insertions, 27 deletions
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; } } |