File: | home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx |
Warning: | line 2387, column 8 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||
2 | /* | ||||||
3 | * This file is part of the LibreOffice project. | ||||||
4 | * | ||||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
8 | * | ||||||
9 | * This file incorporates work covered by the following license notice: | ||||||
10 | * | ||||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||||
13 | * with this work for additional information regarding copyright | ||||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||||
16 | * except in compliance with the License. You may obtain a copy of | ||||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||||
18 | */ | ||||||
19 | |||||||
20 | #include <sal/config.h> | ||||||
21 | |||||||
22 | #include <o3tl/safeint.hxx> | ||||||
23 | #include <svx/svxids.hrc> | ||||||
24 | #include <hintids.hxx> | ||||||
25 | #include <vcl/svapp.hxx> | ||||||
26 | #include <svl/hint.hxx> | ||||||
27 | #include <svtools/ctrltool.hxx> | ||||||
28 | #include <svl/style.hxx> | ||||||
29 | #include <svl/itemiter.hxx> | ||||||
30 | #include <svl/listener.hxx> | ||||||
31 | #include <svl/zforlist.hxx> | ||||||
32 | #include <svl/zformat.hxx> | ||||||
33 | #include <svx/pageitem.hxx> | ||||||
34 | #include <editeng/colritem.hxx> | ||||||
35 | #include <editeng/contouritem.hxx> | ||||||
36 | #include <editeng/crossedoutitem.hxx> | ||||||
37 | #include <editeng/fontitem.hxx> | ||||||
38 | #include <editeng/sizeitem.hxx> | ||||||
39 | #include <editeng/udlnitem.hxx> | ||||||
40 | #include <editeng/ulspitem.hxx> | ||||||
41 | #include <editeng/lrspitem.hxx> | ||||||
42 | #include <editeng/boxitem.hxx> | ||||||
43 | #include <editeng/postitem.hxx> | ||||||
44 | #include <editeng/shdditem.hxx> | ||||||
45 | #include <editeng/brushitem.hxx> | ||||||
46 | #include <editeng/flstitem.hxx> | ||||||
47 | #include <editeng/fhgtitem.hxx> | ||||||
48 | #include <editeng/paperinf.hxx> | ||||||
49 | #include <editeng/wghtitem.hxx> | ||||||
50 | #include <pagedesc.hxx> | ||||||
51 | #include <doc.hxx> | ||||||
52 | #include <IDocumentUndoRedo.hxx> | ||||||
53 | #include <IDocumentDeviceAccess.hxx> | ||||||
54 | #include <IDocumentStylePoolAccess.hxx> | ||||||
55 | #include <docary.hxx> | ||||||
56 | #include <charfmt.hxx> | ||||||
57 | #include <cmdid.h> | ||||||
58 | #include <unomid.h> | ||||||
59 | #include <unomap.hxx> | ||||||
60 | #include <unostyle.hxx> | ||||||
61 | #include <unosett.hxx> | ||||||
62 | #include <docsh.hxx> | ||||||
63 | #include <paratr.hxx> | ||||||
64 | #include <unoprnms.hxx> | ||||||
65 | #include <shellio.hxx> | ||||||
66 | #include <docstyle.hxx> | ||||||
67 | #include <unotextbodyhf.hxx> | ||||||
68 | #include <fmthdft.hxx> | ||||||
69 | #include <fmtpdsc.hxx> | ||||||
70 | #include <strings.hrc> | ||||||
71 | #include <poolfmt.hxx> | ||||||
72 | #include <unoevent.hxx> | ||||||
73 | #include <fmtruby.hxx> | ||||||
74 | #include <SwStyleNameMapper.hxx> | ||||||
75 | #include <sfx2/printer.hxx> | ||||||
76 | #include <com/sun/star/frame/XModel.hpp> | ||||||
77 | #include <com/sun/star/io/IOException.hpp> | ||||||
78 | #include <com/sun/star/style/ParagraphStyleCategory.hpp> | ||||||
79 | #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> | ||||||
80 | #include <com/sun/star/beans/PropertyAttribute.hpp> | ||||||
81 | #include <com/sun/star/beans/NamedValue.hpp> | ||||||
82 | #include <com/sun/star/drawing/BitmapMode.hpp> | ||||||
83 | #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> | ||||||
84 | #include <com/sun/star/lang/IllegalArgumentException.hpp> | ||||||
85 | #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> | ||||||
86 | #include <com/sun/star/document/XEventsSupplier.hpp> | ||||||
87 | #include <com/sun/star/io/XInputStream.hpp> | ||||||
88 | #include <istyleaccess.hxx> | ||||||
89 | #include <GetMetricVal.hxx> | ||||||
90 | #include <fmtfsize.hxx> | ||||||
91 | #include <numrule.hxx> | ||||||
92 | #include <tblafmt.hxx> | ||||||
93 | #include <frameformats.hxx> | ||||||
94 | |||||||
95 | #include <comphelper/servicehelper.hxx> | ||||||
96 | #include <cppuhelper/exc_hlp.hxx> | ||||||
97 | #include <cppuhelper/supportsservice.hxx> | ||||||
98 | #include <cppuhelper/typeprovider.hxx> | ||||||
99 | #include <comphelper/sequence.hxx> | ||||||
100 | #include <sal/log.hxx> | ||||||
101 | |||||||
102 | #include <svl/stylepool.hxx> | ||||||
103 | #include <svx/unobrushitemhelper.hxx> | ||||||
104 | #include <editeng/unoipset.hxx> | ||||||
105 | #include <editeng/memberids.h> | ||||||
106 | #include <svx/unomid.hxx> | ||||||
107 | #include <svx/unoshape.hxx> | ||||||
108 | #include <svx/xflbstit.hxx> | ||||||
109 | #include <svx/xflbmtit.hxx> | ||||||
110 | #include <swunohelper.hxx> | ||||||
111 | #include <svx/xbtmpit.hxx> | ||||||
112 | |||||||
113 | #include <ccoll.hxx> | ||||||
114 | #include <hints.hxx> | ||||||
115 | |||||||
116 | #include <cassert> | ||||||
117 | #include <memory> | ||||||
118 | #include <set> | ||||||
119 | #include <limits> | ||||||
120 | |||||||
121 | using namespace css; | ||||||
122 | using namespace css::io; | ||||||
123 | using namespace css::lang; | ||||||
124 | using namespace css::uno; | ||||||
125 | |||||||
126 | namespace { | ||||||
127 | |||||||
128 | class SwXStyle; | ||||||
129 | class SwStyleProperties_Impl; | ||||||
130 | |||||||
131 | struct StyleFamilyEntry | ||||||
132 | { | ||||||
133 | using GetCountOrName_t = std::function<sal_Int32 (const SwDoc&, OUString*, sal_Int32)>; | ||||||
134 | using CreateStyle_t = std::function<uno::Reference<css::style::XStyle>(SfxStyleSheetBasePool*, SwDocShell*, const OUString&)>; | ||||||
135 | using TranslateIndex_t = std::function<sal_uInt16(const sal_uInt16)>; | ||||||
136 | SfxStyleFamily m_eFamily; | ||||||
137 | sal_uInt16 m_nPropMapType; | ||||||
138 | uno::Reference<beans::XPropertySetInfo> m_xPSInfo; | ||||||
139 | SwGetPoolIdFromName m_aPoolId; | ||||||
140 | OUString m_sName; | ||||||
141 | const char* m_pResId; | ||||||
142 | GetCountOrName_t m_fGetCountOrName; | ||||||
143 | CreateStyle_t m_fCreateStyle; | ||||||
144 | TranslateIndex_t m_fTranslateIndex; | ||||||
145 | StyleFamilyEntry(SfxStyleFamily eFamily, sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, OUString const& sName, const char* pResId, GetCountOrName_t const & fGetCountOrName, CreateStyle_t const & fCreateStyle, TranslateIndex_t const & fTranslateIndex) | ||||||
146 | : m_eFamily(eFamily) | ||||||
147 | , m_nPropMapType(nPropMapType) | ||||||
148 | , m_xPSInfo(aSwMapProvider.GetPropertySet(nPropMapType)->getPropertySetInfo()) | ||||||
149 | , m_aPoolId(aPoolId) | ||||||
150 | , m_sName(sName) | ||||||
151 | , m_pResId(pResId) | ||||||
152 | , m_fGetCountOrName(fGetCountOrName) | ||||||
153 | , m_fCreateStyle(fCreateStyle) | ||||||
154 | , m_fTranslateIndex(fTranslateIndex) | ||||||
155 | { } | ||||||
156 | }; | ||||||
157 | const std::vector<StyleFamilyEntry>* our_pStyleFamilyEntries; | ||||||
158 | // these should really be constexprs, but MSVC still is apparently too stupid for them | ||||||
159 | #define nPoolChrNormalRange(RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN) (RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN) | ||||||
160 | #define nPoolChrHtmlRange(RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN) (RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN) | ||||||
161 | #define nPoolCollTextRange( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN) ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN) | ||||||
162 | #define nPoolCollListsRange( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN) ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN) | ||||||
163 | #define nPoolCollExtraRange( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN) ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN) | ||||||
164 | #define nPoolCollRegisterRange( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN) ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN) | ||||||
165 | #define nPoolCollDocRange( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN) ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN) | ||||||
166 | #define nPoolCollHtmlRange( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN) ( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN) | ||||||
167 | #define nPoolFrameRange( RES_POOLFRM_END - RES_POOLFRM_BEGIN) ( RES_POOLFRM_END - RES_POOLFRM_BEGIN) | ||||||
168 | #define nPoolPageRange( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN) ( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN) | ||||||
169 | #define nPoolNumRange( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN) ( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN) | ||||||
170 | #define nPoolCollListsStackedStart( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) ( nPoolCollTextRange( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) | ||||||
171 | #define nPoolCollExtraStackedStart( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) ( nPoolCollListsStackedStart( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + nPoolCollListsRange( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) | ||||||
172 | #define nPoolCollRegisterStackedStart( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) ( nPoolCollExtraStackedStart( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + nPoolCollExtraRange( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) | ||||||
173 | #define nPoolCollDocStackedStart( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) ( nPoolCollRegisterStackedStart( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + nPoolCollRegisterRange( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) | ||||||
174 | #define nPoolCollHtmlStackedStart( ( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) + ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN )) ( nPoolCollDocStackedStart( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) + nPoolCollDocRange( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN)) | ||||||
175 | using paragraphstyle_t = std::remove_const<decltype(style::ParagraphStyleCategory::TEXT)>::type; | ||||||
176 | using collectionbits_t = sal_uInt16; | ||||||
177 | struct ParagraphStyleCategoryEntry | ||||||
178 | { | ||||||
179 | paragraphstyle_t m_eCategory; | ||||||
180 | SfxStyleSearchBits m_nSwStyleBits; | ||||||
181 | collectionbits_t m_nCollectionBits; | ||||||
182 | ParagraphStyleCategoryEntry(paragraphstyle_t eCategory, SfxStyleSearchBits nSwStyleBits, collectionbits_t nCollectionBits) | ||||||
183 | : m_eCategory(eCategory) | ||||||
184 | , m_nSwStyleBits(nSwStyleBits) | ||||||
185 | , m_nCollectionBits(nCollectionBits) | ||||||
186 | { } | ||||||
187 | }; | ||||||
188 | const std::vector<ParagraphStyleCategoryEntry>* our_pParagraphStyleCategoryEntries; | ||||||
189 | } | ||||||
190 | static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries(); | ||||||
191 | |||||||
192 | using namespace ::com::sun::star; | ||||||
193 | |||||||
194 | namespace sw | ||||||
195 | { | ||||||
196 | namespace { | ||||||
197 | |||||||
198 | class XStyleFamily : public cppu::WeakImplHelper | ||||||
199 | < | ||||||
200 | container::XNameContainer, | ||||||
201 | lang::XServiceInfo, | ||||||
202 | container::XIndexAccess, | ||||||
203 | beans::XPropertySet | ||||||
204 | > | ||||||
205 | , public SfxListener | ||||||
206 | { | ||||||
207 | const StyleFamilyEntry& m_rEntry; | ||||||
208 | SfxStyleSheetBasePool* m_pBasePool; | ||||||
209 | SwDocShell* m_pDocShell; | ||||||
210 | |||||||
211 | SwXStyle* FindStyle(const OUString& rStyleName) const; | ||||||
212 | sal_Int32 GetCountOrName(OUString* pString, sal_Int32 nIndex = SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF)) | ||||||
213 | { return m_rEntry.m_fGetCountOrName(*m_pDocShell->GetDoc(), pString, nIndex); }; | ||||||
214 | static const StyleFamilyEntry& InitEntry(SfxStyleFamily eFamily) | ||||||
215 | { | ||||||
216 | auto pEntries = lcl_GetStyleFamilyEntries(); | ||||||
217 | const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(), | ||||||
218 | [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; }); | ||||||
219 | assert(pEntry != pEntries->end())(static_cast <bool> (pEntry != pEntries->end()) ? void (0) : __assert_fail ("pEntry != pEntries->end()", "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 219, __extension__ __PRETTY_FUNCTION__)); | ||||||
220 | return *pEntry; | ||||||
221 | } | ||||||
222 | public: | ||||||
223 | XStyleFamily(SwDocShell* pDocShell, const SfxStyleFamily eFamily) | ||||||
224 | : m_rEntry(InitEntry(eFamily)) | ||||||
225 | , m_pBasePool(pDocShell->GetStyleSheetPool()) | ||||||
226 | , m_pDocShell(pDocShell) | ||||||
227 | { | ||||||
228 | if (m_pBasePool) //tdf#124142 html docs can have no styles | ||||||
229 | StartListening(*m_pBasePool); | ||||||
230 | } | ||||||
231 | |||||||
232 | //XIndexAccess | ||||||
233 | virtual sal_Int32 SAL_CALL getCount() override | ||||||
234 | { | ||||||
235 | SolarMutexGuard aGuard; | ||||||
236 | return GetCountOrName(nullptr); | ||||||
237 | }; | ||||||
238 | virtual uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override; | ||||||
239 | |||||||
240 | //XElementAccess | ||||||
241 | virtual uno::Type SAL_CALL getElementType( ) override | ||||||
242 | { return cppu::UnoType<style::XStyle>::get(); }; | ||||||
243 | virtual sal_Bool SAL_CALL hasElements( ) override | ||||||
244 | { | ||||||
245 | if(!m_pBasePool) | ||||||
246 | throw uno::RuntimeException(); | ||||||
247 | return true; | ||||||
248 | } | ||||||
249 | |||||||
250 | //XNameAccess | ||||||
251 | virtual uno::Any SAL_CALL getByName(const OUString& Name) override; | ||||||
252 | virtual uno::Sequence< OUString > SAL_CALL getElementNames() override; | ||||||
253 | virtual sal_Bool SAL_CALL hasByName(const OUString& Name) override; | ||||||
254 | |||||||
255 | //XNameContainer | ||||||
256 | virtual void SAL_CALL insertByName(const OUString& Name, const uno::Any& Element) override; | ||||||
257 | virtual void SAL_CALL replaceByName(const OUString& Name, const uno::Any& Element) override; | ||||||
258 | virtual void SAL_CALL removeByName(const OUString& Name) override; | ||||||
259 | |||||||
260 | //XPropertySet | ||||||
261 | virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override | ||||||
262 | { return {}; }; | ||||||
263 | virtual void SAL_CALL setPropertyValue( const OUString&, const uno::Any&) override | ||||||
264 | { SAL_WARN("sw.uno", "###unexpected!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "###unexpected!") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "264" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "264" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "###unexpected!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "264" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "264" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); }; | ||||||
265 | virtual uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; | ||||||
266 | virtual void SAL_CALL addPropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override | ||||||
267 | { SAL_WARN("sw.uno", "###unexpected!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "###unexpected!") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "267" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "267" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "###unexpected!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "267" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "267" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); }; | ||||||
268 | virtual void SAL_CALL removePropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override | ||||||
269 | { SAL_WARN("sw.uno", "###unexpected!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "###unexpected!") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "269" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "269" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "###unexpected!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "269" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "269" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); }; | ||||||
270 | virtual void SAL_CALL addVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override | ||||||
271 | { SAL_WARN("sw.uno", "###unexpected!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "###unexpected!") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "271" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "271" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "###unexpected!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "271" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "271" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); }; | ||||||
272 | virtual void SAL_CALL removeVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override | ||||||
273 | { SAL_WARN("sw.uno", "###unexpected!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "###unexpected!") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "273" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "273" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "###unexpected!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "273" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "###unexpected!"), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "###unexpected!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "273" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); }; | ||||||
274 | |||||||
275 | //SfxListener | ||||||
276 | virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override | ||||||
277 | { | ||||||
278 | if(rHint.GetId() == SfxHintId::Dying) | ||||||
279 | { | ||||||
280 | m_pBasePool = nullptr; | ||||||
281 | m_pDocShell = nullptr; | ||||||
282 | EndListening(rBC); | ||||||
283 | } | ||||||
284 | } | ||||||
285 | |||||||
286 | //XServiceInfo | ||||||
287 | virtual OUString SAL_CALL getImplementationName() override | ||||||
288 | { return {"XStyleFamily"}; }; | ||||||
289 | virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override | ||||||
290 | { return cppu::supportsService(this, rServiceName); }; | ||||||
291 | virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override | ||||||
292 | { return { "com.sun.star.style.StyleFamily" }; } | ||||||
293 | }; | ||||||
294 | |||||||
295 | } | ||||||
296 | } | ||||||
297 | |||||||
298 | namespace { | ||||||
299 | |||||||
300 | class SwStyleBase_Impl; | ||||||
301 | class SwXStyle : public cppu::WeakImplHelper | ||||||
302 | < | ||||||
303 | css::style::XStyle, | ||||||
304 | css::beans::XPropertySet, | ||||||
305 | css::beans::XMultiPropertySet, | ||||||
306 | css::lang::XServiceInfo, | ||||||
307 | css::lang::XUnoTunnel, | ||||||
308 | css::beans::XPropertyState, | ||||||
309 | css::beans::XMultiPropertyStates | ||||||
310 | > | ||||||
311 | , public SfxListener | ||||||
312 | , public SvtListener | ||||||
313 | { | ||||||
314 | SwDoc* m_pDoc; | ||||||
315 | OUString m_sStyleName; | ||||||
316 | const StyleFamilyEntry& m_rEntry; | ||||||
317 | bool m_bIsDescriptor; | ||||||
318 | bool m_bIsConditional; | ||||||
319 | OUString m_sParentStyleName; | ||||||
320 | |||||||
321 | protected: | ||||||
322 | SfxStyleSheetBasePool* m_pBasePool; | ||||||
323 | std::unique_ptr<SwStyleProperties_Impl> m_pPropertiesImpl; | ||||||
324 | css::uno::Reference<css::container::XNameAccess> m_xStyleFamily; | ||||||
325 | css::uno::Reference<css::beans::XPropertySet> m_xStyleData; | ||||||
326 | |||||||
327 | template<sal_uInt16> | ||||||
328 | void SetPropertyValue(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&); | ||||||
329 | void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ); | ||||||
330 | SfxStyleSheetBase* GetStyleSheetBase(); | ||||||
331 | void PrepareStyleBase(SwStyleBase_Impl& rBase); | ||||||
332 | template<sal_uInt16> | ||||||
333 | uno::Any GetStyleProperty(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase); | ||||||
334 | uno::Any GetStyleProperty_Impl(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase); | ||||||
335 | uno::Any GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName); | ||||||
336 | |||||||
337 | public: | ||||||
338 | SwXStyle(SwDoc* pDoc, SfxStyleFamily eFam, bool bConditional = false); | ||||||
339 | SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const OUString& rStyleName); | ||||||
340 | virtual ~SwXStyle() override; | ||||||
341 | |||||||
342 | |||||||
343 | static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId(); | ||||||
344 | |||||||
345 | //XUnoTunnel | ||||||
346 | virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override; | ||||||
347 | |||||||
348 | //XNamed | ||||||
349 | virtual OUString SAL_CALL getName() override; | ||||||
350 | virtual void SAL_CALL setName(const OUString& Name_) override; | ||||||
351 | |||||||
352 | //XStyle | ||||||
353 | virtual sal_Bool SAL_CALL isUserDefined() override; | ||||||
354 | virtual sal_Bool SAL_CALL isInUse() override; | ||||||
355 | virtual OUString SAL_CALL getParentStyle() override; | ||||||
356 | virtual void SAL_CALL setParentStyle(const OUString& aParentStyle) override; | ||||||
357 | |||||||
358 | //XPropertySet | ||||||
359 | virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; | ||||||
360 | virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; | ||||||
361 | virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; | ||||||
362 | virtual void SAL_CALL addPropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override | ||||||
363 | { OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "363" ": "), "%s", "not implemented"); } } while (false); }; | ||||||
364 | virtual void SAL_CALL removePropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override | ||||||
365 | { OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "365" ": "), "%s", "not implemented"); } } while (false); }; | ||||||
366 | virtual void SAL_CALL addVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override | ||||||
367 | { OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "367" ": "), "%s", "not implemented"); } } while (false); }; | ||||||
368 | virtual void SAL_CALL removeVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override | ||||||
369 | { OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "369" ": "), "%s", "not implemented"); } } while (false); }; | ||||||
370 | |||||||
371 | //XMultiPropertySet | ||||||
372 | virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override; | ||||||
373 | virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override; | ||||||
374 | virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override | ||||||
375 | {}; | ||||||
376 | virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override | ||||||
377 | {}; | ||||||
378 | virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override | ||||||
379 | {}; | ||||||
380 | |||||||
381 | //XPropertyState | ||||||
382 | virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; | ||||||
383 | virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override; | ||||||
384 | virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; | ||||||
385 | virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; | ||||||
386 | |||||||
387 | //XMultiPropertyStates | ||||||
388 | virtual void SAL_CALL setAllPropertiesToDefault( ) override; | ||||||
389 | virtual void SAL_CALL setPropertiesToDefault( const css::uno::Sequence< OUString >& aPropertyNames ) override; | ||||||
390 | virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyDefaults( const css::uno::Sequence< OUString >& aPropertyNames ) override; | ||||||
391 | |||||||
392 | //XServiceInfo | ||||||
393 | virtual OUString SAL_CALL getImplementationName() override | ||||||
394 | { return {"SwXStyle"}; }; | ||||||
395 | virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override | ||||||
396 | { return cppu::supportsService(this, rServiceName); }; | ||||||
397 | virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; | ||||||
398 | |||||||
399 | //SfxListener | ||||||
400 | virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; | ||||||
401 | //SvtListener | ||||||
402 | virtual void Notify(const SfxHint&) override; | ||||||
403 | const OUString& GetStyleName() const { return m_sStyleName;} | ||||||
404 | SfxStyleFamily GetFamily() const {return m_rEntry.m_eFamily;} | ||||||
405 | |||||||
406 | bool IsDescriptor() const {return m_bIsDescriptor;} | ||||||
407 | bool IsConditional() const { return m_bIsConditional;} | ||||||
408 | const OUString& GetParentStyleName() const { return m_sParentStyleName;} | ||||||
409 | void SetDoc(SwDoc* pDc, SfxStyleSheetBasePool* pPool) | ||||||
410 | { | ||||||
411 | m_bIsDescriptor = false; m_pDoc = pDc; | ||||||
412 | m_pBasePool = pPool; | ||||||
413 | SfxListener::StartListening(*m_pBasePool); | ||||||
414 | } | ||||||
415 | SwDoc* GetDoc() const { return m_pDoc; } | ||||||
416 | void Invalidate(); | ||||||
417 | void ApplyDescriptorProperties(); | ||||||
418 | void SetStyleName(const OUString& rSet){ m_sStyleName = rSet;} | ||||||
419 | /// @throws beans::PropertyVetoException | ||||||
420 | /// @throws lang::IllegalArgumentException | ||||||
421 | /// @throws lang::WrappedTargetException | ||||||
422 | /// @throws uno::RuntimeException | ||||||
423 | void SetStyleProperty(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase); | ||||||
424 | void PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertySimpleEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl); | ||||||
425 | }; | ||||||
426 | |||||||
427 | class SwXFrameStyle | ||||||
428 | : public SwXStyle | ||||||
429 | , public css::document::XEventsSupplier | ||||||
430 | , public sw::ICoreFrameStyle | ||||||
431 | { | ||||||
432 | public: | ||||||
433 | SwXFrameStyle(SfxStyleSheetBasePool& rPool, | ||||||
434 | SwDoc* pDoc, | ||||||
435 | const OUString& rStyleName) : | ||||||
436 | SwXStyle(&rPool, SfxStyleFamily::Frame, pDoc, rStyleName){} | ||||||
437 | explicit SwXFrameStyle(SwDoc *pDoc); | ||||||
438 | |||||||
439 | virtual void SAL_CALL acquire( ) throw() override {SwXStyle::acquire();} | ||||||
440 | virtual void SAL_CALL release( ) throw() override {SwXStyle::release();} | ||||||
441 | |||||||
442 | virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override; | ||||||
443 | virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override; | ||||||
444 | virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents( ) override; | ||||||
445 | |||||||
446 | //ICoreStyle | ||||||
447 | virtual void SetItem(sal_uInt16 eAtr, const SfxPoolItem& rItem) override; | ||||||
448 | virtual const SfxPoolItem* GetItem(sal_uInt16 eAtr) override; | ||||||
449 | virtual css::document::XEventsSupplier& GetEventsSupplier() override | ||||||
450 | { return *this; }; | ||||||
451 | }; | ||||||
452 | |||||||
453 | class SwXPageStyle | ||||||
454 | : public SwXStyle | ||||||
455 | { | ||||||
456 | protected: | ||||||
457 | void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ); | ||||||
458 | css::uno::Sequence< css::uno::Any > GetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames ); | ||||||
459 | |||||||
460 | public: | ||||||
461 | SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName); | ||||||
462 | explicit SwXPageStyle(SwDocShell* pDocSh); | ||||||
463 | |||||||
464 | virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; | ||||||
465 | virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; | ||||||
466 | |||||||
467 | virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override; | ||||||
468 | virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override; | ||||||
469 | }; | ||||||
470 | |||||||
471 | } | ||||||
472 | |||||||
473 | using sw::XStyleFamily; | ||||||
474 | |||||||
475 | OUString SwXStyleFamilies::getImplementationName() | ||||||
476 | { return {"SwXStyleFamilies"}; } | ||||||
477 | |||||||
478 | sal_Bool SwXStyleFamilies::supportsService(const OUString& rServiceName) | ||||||
479 | { | ||||||
480 | return cppu::supportsService(this, rServiceName); | ||||||
481 | } | ||||||
482 | |||||||
483 | uno::Sequence< OUString > SwXStyleFamilies::getSupportedServiceNames() | ||||||
484 | { return { "com.sun.star.style.StyleFamilies" }; } | ||||||
485 | |||||||
486 | SwXStyleFamilies::SwXStyleFamilies(SwDocShell& rDocShell) : | ||||||
487 | SwUnoCollection(rDocShell.GetDoc()), | ||||||
488 | m_pDocShell(&rDocShell) | ||||||
489 | { } | ||||||
490 | |||||||
491 | SwXStyleFamilies::~SwXStyleFamilies() | ||||||
492 | { } | ||||||
493 | |||||||
494 | uno::Any SAL_CALL SwXStyleFamilies::getByName(const OUString& Name) | ||||||
495 | { | ||||||
496 | SolarMutexGuard aGuard; | ||||||
497 | if(!IsValid()) | ||||||
498 | throw uno::RuntimeException(); | ||||||
499 | auto pEntries(lcl_GetStyleFamilyEntries()); | ||||||
500 | const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(), | ||||||
501 | [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; }); | ||||||
502 | if(pEntry == pEntries->end()) | ||||||
503 | throw container::NoSuchElementException(); | ||||||
504 | return getByIndex(pEntry-pEntries->begin()); | ||||||
505 | } | ||||||
506 | |||||||
507 | uno::Sequence< OUString > SwXStyleFamilies::getElementNames() | ||||||
508 | { | ||||||
509 | auto pEntries(lcl_GetStyleFamilyEntries()); | ||||||
510 | uno::Sequence<OUString> aNames(pEntries->size()); | ||||||
511 | std::transform(pEntries->begin(), pEntries->end(), | ||||||
512 | aNames.begin(), [] (const StyleFamilyEntry& e) { return e.m_sName; }); | ||||||
513 | return aNames; | ||||||
514 | } | ||||||
515 | |||||||
516 | sal_Bool SwXStyleFamilies::hasByName(const OUString& Name) | ||||||
517 | { | ||||||
518 | auto pEntries(lcl_GetStyleFamilyEntries()); | ||||||
519 | return std::any_of(pEntries->begin(), pEntries->end(), | ||||||
520 | [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; }); | ||||||
521 | } | ||||||
522 | |||||||
523 | sal_Int32 SwXStyleFamilies::getCount() | ||||||
524 | { | ||||||
525 | return lcl_GetStyleFamilyEntries()->size(); | ||||||
526 | } | ||||||
527 | |||||||
528 | uno::Any SwXStyleFamilies::getByIndex(sal_Int32 nIndex) | ||||||
529 | { | ||||||
530 | auto pEntries(lcl_GetStyleFamilyEntries()); | ||||||
531 | SolarMutexGuard aGuard; | ||||||
532 | if(nIndex < 0 || nIndex >= static_cast<sal_Int32>(pEntries->size())) | ||||||
533 | throw lang::IndexOutOfBoundsException(); | ||||||
534 | if(!IsValid()) | ||||||
535 | throw uno::RuntimeException(); | ||||||
536 | auto eFamily = (*pEntries)[nIndex].m_eFamily; | ||||||
537 | assert(eFamily != SfxStyleFamily::All)(static_cast <bool> (eFamily != SfxStyleFamily::All) ? void (0) : __assert_fail ("eFamily != SfxStyleFamily::All", "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 537, __extension__ __PRETTY_FUNCTION__)); | ||||||
538 | auto& rxFamily = m_vFamilies[eFamily]; | ||||||
539 | if(!rxFamily.is()) | ||||||
540 | rxFamily = new XStyleFamily(m_pDocShell, eFamily); | ||||||
541 | return uno::makeAny(rxFamily); | ||||||
542 | } | ||||||
543 | |||||||
544 | uno::Type SwXStyleFamilies::getElementType() | ||||||
545 | { | ||||||
546 | return cppu::UnoType<container::XNameContainer>::get(); | ||||||
547 | } | ||||||
548 | |||||||
549 | sal_Bool SwXStyleFamilies::hasElements() | ||||||
550 | { return true; } | ||||||
551 | |||||||
552 | void SwXStyleFamilies::loadStylesFromURL(const OUString& rURL, | ||||||
553 | const uno::Sequence< beans::PropertyValue >& aOptions) | ||||||
554 | { | ||||||
555 | SolarMutexGuard aGuard; | ||||||
556 | if(!IsValid() || rURL.isEmpty()) | ||||||
557 | throw uno::RuntimeException(); | ||||||
558 | SwgReaderOption aOpt; | ||||||
559 | aOpt.SetFrameFormats(true); | ||||||
560 | aOpt.SetTextFormats(true); | ||||||
561 | aOpt.SetPageDescs(true); | ||||||
562 | aOpt.SetNumRules(true); | ||||||
563 | aOpt.SetMerge(false); | ||||||
564 | for(const auto& rProperty: aOptions) | ||||||
565 | { | ||||||
566 | bool bValue = false; | ||||||
567 | if(rProperty.Value.getValueType() == cppu::UnoType<bool>::get()) | ||||||
568 | bValue = rProperty.Value.get<bool>(); | ||||||
569 | |||||||
570 | if(rProperty.Name == UNO_NAME_OVERWRITE_STYLES"OverwriteStyles") | ||||||
571 | aOpt.SetMerge(!bValue); | ||||||
572 | else if(rProperty.Name == UNO_NAME_LOAD_NUMBERING_STYLES"LoadNumberingStyles") | ||||||
573 | aOpt.SetNumRules(bValue); | ||||||
574 | else if(rProperty.Name == UNO_NAME_LOAD_PAGE_STYLES"LoadPageStyles") | ||||||
575 | aOpt.SetPageDescs(bValue); | ||||||
576 | else if(rProperty.Name == UNO_NAME_LOAD_FRAME_STYLES"LoadFrameStyles") | ||||||
577 | aOpt.SetFrameFormats(bValue); | ||||||
578 | else if(rProperty.Name == UNO_NAME_LOAD_TEXT_STYLES"LoadTextStyles") | ||||||
579 | aOpt.SetTextFormats(bValue); | ||||||
580 | else if(rProperty.Name == "InputStream") | ||||||
581 | { | ||||||
582 | Reference<XInputStream> xInputStream; | ||||||
583 | if (!(rProperty.Value >>= xInputStream)) | ||||||
584 | throw IllegalArgumentException("Parameter 'InputStream' could not be converted to " | ||||||
585 | "type 'com::sun::star::io::XInputStream'", | ||||||
586 | nullptr, 0); | ||||||
587 | |||||||
588 | aOpt.SetInputStream(xInputStream); | ||||||
589 | |||||||
590 | } | ||||||
591 | } | ||||||
592 | const ErrCode nErr = m_pDocShell->LoadStylesFromFile( rURL, aOpt, true ); | ||||||
593 | if(nErr) | ||||||
594 | throw io::IOException(); | ||||||
595 | } | ||||||
596 | |||||||
597 | uno::Sequence< beans::PropertyValue > SwXStyleFamilies::getStyleLoaderOptions() | ||||||
598 | { | ||||||
599 | SolarMutexGuard aGuard; | ||||||
600 | uno::Sequence< beans::PropertyValue > aSeq(5); | ||||||
601 | beans::PropertyValue* pArray = aSeq.getArray(); | ||||||
602 | const uno::Any aVal(true); | ||||||
603 | pArray[0] = beans::PropertyValue(UNO_NAME_LOAD_TEXT_STYLES"LoadTextStyles", -1, aVal, beans::PropertyState_DIRECT_VALUE); | ||||||
604 | pArray[1] = beans::PropertyValue(UNO_NAME_LOAD_FRAME_STYLES"LoadFrameStyles", -1, aVal, beans::PropertyState_DIRECT_VALUE); | ||||||
605 | pArray[2] = beans::PropertyValue(UNO_NAME_LOAD_PAGE_STYLES"LoadPageStyles", -1, aVal, beans::PropertyState_DIRECT_VALUE); | ||||||
606 | pArray[3] = beans::PropertyValue(UNO_NAME_LOAD_NUMBERING_STYLES"LoadNumberingStyles", -1, aVal, beans::PropertyState_DIRECT_VALUE); | ||||||
607 | pArray[4] = beans::PropertyValue(UNO_NAME_OVERWRITE_STYLES"OverwriteStyles", -1, aVal, beans::PropertyState_DIRECT_VALUE); | ||||||
608 | return aSeq; | ||||||
609 | } | ||||||
610 | |||||||
611 | static bool lcl_GetHeaderFooterItem( | ||||||
612 | SfxItemSet const& rSet, OUString const& rPropName, bool const bFooter, | ||||||
613 | SvxSetItem const*& o_rpItem) | ||||||
614 | { | ||||||
615 | SfxItemState eState = rSet.GetItemState( | ||||||
616 | bFooter ? SID_ATTR_PAGE_FOOTERSETTypedWhichId<SvxSetItem>( 10000 + 58 ) : SID_ATTR_PAGE_HEADERSETTypedWhichId<SvxSetItem>( 10000 + 57 ), | ||||||
617 | false, reinterpret_cast<const SfxPoolItem**>(&o_rpItem)); | ||||||
618 | if (SfxItemState::SET != eState && | ||||||
619 | rPropName == UNO_NAME_FIRST_IS_SHARED"FirstIsShared") | ||||||
620 | { // fdo#79269 header may not exist, check footer then | ||||||
621 | eState = rSet.GetItemState( | ||||||
622 | (!bFooter) ? SID_ATTR_PAGE_FOOTERSETTypedWhichId<SvxSetItem>( 10000 + 58 ) : SID_ATTR_PAGE_HEADERSETTypedWhichId<SvxSetItem>( 10000 + 57 ), | ||||||
623 | false, reinterpret_cast<const SfxPoolItem**>(&o_rpItem)); | ||||||
624 | } | ||||||
625 | return SfxItemState::SET == eState; | ||||||
626 | } | ||||||
627 | |||||||
628 | template<enum SfxStyleFamily> | ||||||
629 | static sal_Int32 lcl_GetCountOrName(const SwDoc&, OUString*, sal_Int32); | ||||||
630 | |||||||
631 | template<> | ||||||
632 | sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Char>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) | ||||||
633 | { | ||||||
634 | const sal_uInt16 nBaseCount = nPoolChrHtmlRange(RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN) + nPoolChrNormalRange(RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN); | ||||||
635 | nIndex -= nBaseCount; | ||||||
636 | sal_Int32 nCount = 0; | ||||||
637 | for(auto pFormat : *rDoc.GetCharFormats()) | ||||||
638 | { | ||||||
639 | if(pFormat->IsDefault() && pFormat != rDoc.GetDfltCharFormat()) | ||||||
640 | continue; | ||||||
641 | if(!IsPoolUserFormat(pFormat->GetPoolFormatId())) | ||||||
642 | continue; | ||||||
643 | if(nIndex == nCount) | ||||||
644 | { | ||||||
645 | // the default character format needs to be set to "Default!" | ||||||
646 | if(rDoc.GetDfltCharFormat() == pFormat) | ||||||
647 | *pString = SwResId(STR_POOLCHR_STANDARDreinterpret_cast<char const *>("STR_POOLCHR_STANDARD" "\004" u8"Default Character Style")); | ||||||
648 | else | ||||||
649 | *pString = pFormat->GetName(); | ||||||
650 | break; | ||||||
651 | } | ||||||
652 | ++nCount; | ||||||
653 | } | ||||||
654 | return nCount + nBaseCount; | ||||||
655 | } | ||||||
656 | |||||||
657 | template<> | ||||||
658 | sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Para>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) | ||||||
659 | { | ||||||
660 | const sal_uInt16 nBaseCount = nPoolCollHtmlStackedStart( ( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) + ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN )) + nPoolCollHtmlRange( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN); | ||||||
661 | nIndex -= nBaseCount; | ||||||
662 | sal_Int32 nCount = 0; | ||||||
663 | for(auto pColl : *rDoc.GetTextFormatColls()) | ||||||
664 | { | ||||||
665 | if(pColl->IsDefault()) | ||||||
666 | continue; | ||||||
667 | if(!IsPoolUserFormat(pColl->GetPoolFormatId())) | ||||||
668 | continue; | ||||||
669 | if(nIndex == nCount) | ||||||
670 | { | ||||||
671 | *pString = pColl->GetName(); | ||||||
672 | break; | ||||||
673 | } | ||||||
674 | ++nCount; | ||||||
675 | } | ||||||
676 | return nCount + nBaseCount; | ||||||
677 | } | ||||||
678 | |||||||
679 | template<> | ||||||
680 | sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Frame>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) | ||||||
681 | { | ||||||
682 | nIndex -= nPoolFrameRange( RES_POOLFRM_END - RES_POOLFRM_BEGIN); | ||||||
683 | sal_Int32 nCount = 0; | ||||||
684 | for(const auto pFormat : *rDoc.GetFrameFormats()) | ||||||
685 | { | ||||||
686 | if(pFormat->IsDefault() || pFormat->IsAuto()) | ||||||
687 | continue; | ||||||
688 | if(!IsPoolUserFormat(pFormat->GetPoolFormatId())) | ||||||
689 | continue; | ||||||
690 | if(nIndex == nCount) | ||||||
691 | { | ||||||
692 | *pString = pFormat->GetName(); | ||||||
693 | break; | ||||||
694 | } | ||||||
695 | ++nCount; | ||||||
696 | } | ||||||
697 | return nCount + nPoolFrameRange( RES_POOLFRM_END - RES_POOLFRM_BEGIN); | ||||||
698 | } | ||||||
699 | |||||||
700 | template<> | ||||||
701 | sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Page>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) | ||||||
702 | { | ||||||
703 | nIndex -= nPoolPageRange( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN); | ||||||
704 | sal_Int32 nCount = 0; | ||||||
705 | const size_t nArrLen = rDoc.GetPageDescCnt(); | ||||||
706 | for(size_t i = 0; i < nArrLen; ++i) | ||||||
707 | { | ||||||
708 | const SwPageDesc& rDesc = rDoc.GetPageDesc(i); | ||||||
709 | if(!IsPoolUserFormat(rDesc.GetPoolFormatId())) | ||||||
710 | continue; | ||||||
711 | if(nIndex == nCount) | ||||||
712 | { | ||||||
713 | *pString = rDesc.GetName(); | ||||||
714 | break; | ||||||
715 | } | ||||||
716 | ++nCount; | ||||||
717 | } | ||||||
718 | nCount += nPoolPageRange( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN); | ||||||
719 | return nCount; | ||||||
720 | } | ||||||
721 | |||||||
722 | template<> | ||||||
723 | sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Pseudo>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) | ||||||
724 | { | ||||||
725 | nIndex -= nPoolNumRange( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN); | ||||||
726 | sal_Int32 nCount = 0; | ||||||
727 | for(const auto pRule : rDoc.GetNumRuleTable()) | ||||||
728 | { | ||||||
729 | if(pRule->IsAutoRule()) | ||||||
730 | continue; | ||||||
731 | if(!IsPoolUserFormat(pRule->GetPoolFormatId())) | ||||||
732 | continue; | ||||||
733 | if(nIndex == nCount) | ||||||
734 | { | ||||||
735 | *pString = pRule->GetName(); | ||||||
736 | break; | ||||||
737 | } | ||||||
738 | ++nCount; | ||||||
739 | } | ||||||
740 | return nCount + nPoolNumRange( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN); | ||||||
741 | } | ||||||
742 | |||||||
743 | template<> | ||||||
744 | sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Table>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) | ||||||
745 | { | ||||||
746 | if (!rDoc.HasTableStyles()) | ||||||
747 | return 0; | ||||||
748 | |||||||
749 | const auto pAutoFormats = &rDoc.GetTableStyles(); | ||||||
750 | const sal_Int32 nCount = pAutoFormats->size(); | ||||||
751 | if (0 <= nIndex && nIndex < nCount) | ||||||
752 | *pString = pAutoFormats->operator[](nIndex).GetName(); | ||||||
753 | |||||||
754 | return nCount; | ||||||
755 | } | ||||||
756 | |||||||
757 | template<> | ||||||
758 | sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Cell>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) | ||||||
759 | { | ||||||
760 | const auto& rAutoFormats = rDoc.GetTableStyles(); | ||||||
761 | const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap(); | ||||||
762 | const sal_Int32 nUsedCellStylesCount = rAutoFormats.size() * rTableTemplateMap.size(); | ||||||
763 | const sal_Int32 nCount = nUsedCellStylesCount + rDoc.GetCellStyles().size(); | ||||||
764 | if (0 <= nIndex && nIndex < nCount) | ||||||
765 | { | ||||||
766 | if (nUsedCellStylesCount > nIndex) | ||||||
767 | { | ||||||
768 | const sal_Int32 nAutoFormat = nIndex / rTableTemplateMap.size(); | ||||||
769 | const sal_Int32 nBoxFormat = rTableTemplateMap[nIndex % rTableTemplateMap.size()]; | ||||||
770 | const SwTableAutoFormat& rTableFormat = rAutoFormats[nAutoFormat]; | ||||||
771 | SwStyleNameMapper::FillProgName(rTableFormat.GetName(), *pString, SwGetPoolIdFromName::TabStyle); | ||||||
772 | *pString += rTableFormat.GetTableTemplateCellSubName(rTableFormat.GetBoxFormat(nBoxFormat)); | ||||||
773 | } | ||||||
774 | else | ||||||
775 | *pString = rDoc.GetCellStyles()[nIndex-nUsedCellStylesCount].GetName(); | ||||||
776 | } | ||||||
777 | return nCount; | ||||||
778 | } | ||||||
779 | |||||||
780 | template<SfxStyleFamily eFamily> | ||||||
781 | static uno::Reference< css::style::XStyle> lcl_CreateStyle(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName) | ||||||
782 | { return pBasePool ? new SwXStyle(pBasePool, eFamily, pDocShell->GetDoc(), sStyleName) : new SwXStyle(pDocShell->GetDoc(), eFamily, false); }; | ||||||
783 | |||||||
784 | template<> | ||||||
785 | uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Para>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName) | ||||||
786 | { return pBasePool ? new SwXStyle(pBasePool, SfxStyleFamily::Para, pDocShell->GetDoc(), sStyleName) : new SwXStyle(pDocShell->GetDoc(), SfxStyleFamily::Para, false); }; | ||||||
787 | template<> | ||||||
788 | uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Frame>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName) | ||||||
789 | { return pBasePool ? new SwXFrameStyle(*pBasePool, pDocShell->GetDoc(), sStyleName) : new SwXFrameStyle(pDocShell->GetDoc()); }; | ||||||
790 | |||||||
791 | template<> | ||||||
792 | uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Page>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName) | ||||||
793 | { return pBasePool ? new SwXPageStyle(*pBasePool, pDocShell, sStyleName) : new SwXPageStyle(pDocShell); }; | ||||||
794 | |||||||
795 | template<> | ||||||
796 | uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Table>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName) | ||||||
797 | { return SwXTextTableStyle::CreateXTextTableStyle(pDocShell, sStyleName); }; | ||||||
798 | |||||||
799 | template<> | ||||||
800 | uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Cell>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName) | ||||||
801 | { return SwXTextCellStyle::CreateXTextCellStyle(pDocShell, sStyleName); }; | ||||||
802 | |||||||
803 | uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyle(SfxStyleFamily eFamily, SwDoc& rDoc) | ||||||
804 | { | ||||||
805 | auto pEntries(lcl_GetStyleFamilyEntries()); | ||||||
806 | const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(), | ||||||
807 | [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; }); | ||||||
808 | return pEntry == pEntries->end() ? nullptr : pEntry->m_fCreateStyle(nullptr, rDoc.GetDocShell(), ""); | ||||||
809 | } | ||||||
810 | |||||||
811 | // FIXME: Ugly special casing that should die. | ||||||
812 | uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyleCondParagraph(SwDoc& rDoc) | ||||||
813 | { return new SwXStyle(&rDoc, SfxStyleFamily::Para, true); }; | ||||||
814 | |||||||
815 | template<enum SfxStyleFamily> | ||||||
816 | static sal_uInt16 lcl_TranslateIndex(const sal_uInt16 nIndex); | ||||||
817 | |||||||
818 | template<> | ||||||
819 | sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Char>(const sal_uInt16 nIndex) | ||||||
820 | { | ||||||
821 | static_assert(nPoolChrNormalRange(RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN) > 0 && nPoolChrHtmlRange(RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN) > 0, "invalid pool range"); | ||||||
822 | if(nIndex < nPoolChrNormalRange(RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN)) | ||||||
823 | return nIndex + RES_POOLCHR_NORMAL_BEGIN; | ||||||
824 | else if(nIndex < (nPoolChrHtmlRange(RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN)+nPoolChrNormalRange(RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN))) | ||||||
825 | return nIndex + RES_POOLCHR_HTML_BEGIN - nPoolChrNormalRange(RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN); | ||||||
826 | throw lang::IndexOutOfBoundsException(); | ||||||
827 | } | ||||||
828 | |||||||
829 | template<> | ||||||
830 | sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Para>(const sal_uInt16 nIndex) | ||||||
831 | { | ||||||
832 | static_assert(nPoolCollTextRange( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN) > 0 && nPoolCollListsRange( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN) > 0 && nPoolCollExtraRange( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN) > 0 && nPoolCollRegisterRange( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN) > 0 && nPoolCollDocRange( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN) > 0 && nPoolCollHtmlRange( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN) > 0, "weird pool range"); | ||||||
833 | if(nIndex < nPoolCollListsStackedStart( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN))) | ||||||
834 | return nIndex + RES_POOLCOLL_TEXT_BEGIN; | ||||||
835 | else if(nIndex < nPoolCollExtraStackedStart( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN))) | ||||||
836 | return nIndex + RES_POOLCOLL_LISTS_BEGIN - nPoolCollListsStackedStart( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)); | ||||||
837 | else if(nIndex < nPoolCollRegisterStackedStart( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN))) | ||||||
838 | return nIndex + RES_POOLCOLL_EXTRA_BEGIN - nPoolCollExtraStackedStart( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)); | ||||||
839 | else if(nIndex < nPoolCollDocStackedStart( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN))) | ||||||
840 | return nIndex + RES_POOLCOLL_REGISTER_BEGIN - nPoolCollRegisterStackedStart( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)); | ||||||
841 | else if(nIndex < nPoolCollHtmlStackedStart( ( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) + ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN ))) | ||||||
842 | return nIndex + RES_POOLCOLL_DOC_BEGIN - nPoolCollDocStackedStart( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)); | ||||||
843 | else if(nIndex < nPoolCollHtmlStackedStart( ( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) + ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN )) + nPoolCollTextRange( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) | ||||||
844 | return nIndex + RES_POOLCOLL_HTML_BEGIN - nPoolCollHtmlStackedStart( ( ( ( ( ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)) + ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)) + ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)) + ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)) + ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN )); | ||||||
845 | throw lang::IndexOutOfBoundsException(); | ||||||
846 | } | ||||||
847 | |||||||
848 | template<> | ||||||
849 | sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Table>(const sal_uInt16 nIndex) | ||||||
850 | { | ||||||
851 | return nIndex; | ||||||
852 | } | ||||||
853 | |||||||
854 | template<> | ||||||
855 | sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Cell>(const sal_uInt16 nIndex) | ||||||
856 | { | ||||||
857 | return nIndex; | ||||||
858 | } | ||||||
859 | |||||||
860 | template<sal_uInt16 nRangeBegin, sal_uInt16 nRangeSize> | ||||||
861 | static sal_uInt16 lcl_TranslateIndexRange(const sal_uInt16 nIndex) | ||||||
862 | { | ||||||
863 | if(nIndex < nRangeSize) | ||||||
864 | return nIndex + nRangeBegin; | ||||||
865 | throw lang::IndexOutOfBoundsException(); | ||||||
866 | } | ||||||
867 | |||||||
868 | uno::Any XStyleFamily::getByIndex(sal_Int32 nIndex) | ||||||
869 | { | ||||||
870 | SolarMutexGuard aGuard; | ||||||
871 | if(nIndex < 0) | ||||||
872 | throw lang::IndexOutOfBoundsException(); | ||||||
873 | if(!m_pBasePool) | ||||||
874 | throw uno::RuntimeException(); | ||||||
875 | OUString sStyleName; | ||||||
876 | try | ||||||
877 | { | ||||||
878 | SwStyleNameMapper::FillUIName(m_rEntry.m_fTranslateIndex(nIndex), sStyleName); | ||||||
879 | } catch(...) {} | ||||||
880 | if (sStyleName.isEmpty()) | ||||||
881 | GetCountOrName(&sStyleName, nIndex); | ||||||
882 | if(sStyleName.isEmpty()) | ||||||
883 | throw lang::IndexOutOfBoundsException(); | ||||||
884 | return getByName(sStyleName); | ||||||
885 | } | ||||||
886 | |||||||
887 | uno::Any XStyleFamily::getByName(const OUString& rName) | ||||||
888 | { | ||||||
889 | SolarMutexGuard aGuard; | ||||||
890 | OUString sStyleName; | ||||||
891 | SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId); | ||||||
892 | if(!m_pBasePool) | ||||||
893 | throw uno::RuntimeException(); | ||||||
894 | SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily); | ||||||
895 | if(!pBase) | ||||||
896 | throw container::NoSuchElementException(); | ||||||
897 | uno::Reference<style::XStyle> xStyle = FindStyle(sStyleName); | ||||||
898 | if(!xStyle.is()) | ||||||
899 | xStyle = m_rEntry.m_fCreateStyle(m_pBasePool, m_pDocShell, m_rEntry.m_eFamily == SfxStyleFamily::Frame ? pBase->GetName() : sStyleName); | ||||||
900 | return uno::makeAny(xStyle); | ||||||
901 | } | ||||||
902 | |||||||
903 | uno::Sequence<OUString> XStyleFamily::getElementNames() | ||||||
904 | { | ||||||
905 | SolarMutexGuard aGuard; | ||||||
906 | if(!m_pBasePool) | ||||||
907 | throw uno::RuntimeException(); | ||||||
908 | std::vector<OUString> vRet; | ||||||
909 | std::unique_ptr<SfxStyleSheetIterator> pIt = m_pBasePool->CreateIterator(m_rEntry.m_eFamily); | ||||||
910 | for (SfxStyleSheetBase* pStyle = pIt->First(); pStyle; pStyle = pIt->Next()) | ||||||
911 | { | ||||||
912 | OUString sName; | ||||||
913 | SwStyleNameMapper::FillProgName(pStyle->GetName(), sName, m_rEntry.m_aPoolId); | ||||||
914 | vRet.push_back(sName); | ||||||
915 | } | ||||||
916 | return comphelper::containerToSequence(vRet); | ||||||
917 | } | ||||||
918 | |||||||
919 | sal_Bool XStyleFamily::hasByName(const OUString& rName) | ||||||
920 | { | ||||||
921 | SolarMutexGuard aGuard; | ||||||
922 | if(!m_pBasePool) | ||||||
923 | throw uno::RuntimeException(); | ||||||
924 | OUString sStyleName; | ||||||
925 | SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId); | ||||||
926 | SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily); | ||||||
927 | return nullptr != pBase; | ||||||
928 | } | ||||||
929 | |||||||
930 | void XStyleFamily::insertByName(const OUString& rName, const uno::Any& rElement) | ||||||
931 | { | ||||||
932 | SolarMutexGuard aGuard; | ||||||
933 | if(!m_pBasePool) | ||||||
934 | throw uno::RuntimeException(); | ||||||
935 | OUString sStyleName; | ||||||
936 | SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId); | ||||||
937 | SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily); | ||||||
938 | SfxStyleSheetBase* pUINameBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily); | ||||||
939 | if(pBase || pUINameBase) | ||||||
940 | throw container::ElementExistException(); | ||||||
941 | if(rElement.getValueType().getTypeClass() != uno::TypeClass_INTERFACE) | ||||||
942 | throw lang::IllegalArgumentException(); | ||||||
943 | if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId) | ||||||
944 | { | ||||||
945 | // handle cell style | ||||||
946 | uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>(); | ||||||
947 | SwXTextCellStyle* pNewStyle = dynamic_cast<SwXTextCellStyle*>(xStyle.get()); | ||||||
948 | if (!pNewStyle) | ||||||
949 | throw lang::IllegalArgumentException(); | ||||||
950 | |||||||
951 | pNewStyle->setName(sStyleName); // insertByName sets the element name | ||||||
952 | m_pDocShell->GetDoc()->GetCellStyles().AddBoxFormat(*pNewStyle->GetBoxFormat(), sStyleName); | ||||||
953 | pNewStyle->SetPhysical(); | ||||||
954 | } | ||||||
955 | else if (SwGetPoolIdFromName::TabStyle == m_rEntry.m_aPoolId) | ||||||
956 | { | ||||||
957 | // handle table style | ||||||
958 | uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>(); | ||||||
959 | SwXTextTableStyle* pNewStyle = dynamic_cast<SwXTextTableStyle*>(xStyle.get()); | ||||||
960 | if (!pNewStyle) | ||||||
961 | throw lang::IllegalArgumentException(); | ||||||
962 | |||||||
963 | pNewStyle->setName(sStyleName); // insertByName sets the element name | ||||||
964 | m_pDocShell->GetDoc()->GetTableStyles().AddAutoFormat(*pNewStyle->GetTableFormat()); | ||||||
965 | pNewStyle->SetPhysical(); | ||||||
966 | } | ||||||
967 | else | ||||||
968 | { | ||||||
969 | uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>(); | ||||||
970 | SwXStyle* pNewStyle = nullptr; | ||||||
971 | if(xStyleTunnel.is()) | ||||||
972 | { | ||||||
973 | pNewStyle = reinterpret_cast< SwXStyle * >( | ||||||
974 | sal::static_int_cast< sal_IntPtr >( xStyleTunnel->getSomething( SwXStyle::getUnoTunnelId()) )); | ||||||
975 | } | ||||||
976 | |||||||
977 | if (!pNewStyle || !pNewStyle->IsDescriptor() || pNewStyle->GetFamily() != m_rEntry.m_eFamily) | ||||||
978 | throw lang::IllegalArgumentException(); | ||||||
979 | |||||||
980 | SfxStyleSearchBits nMask = SfxStyleSearchBits::All; | ||||||
981 | if(m_rEntry.m_eFamily == SfxStyleFamily::Para && !pNewStyle->IsConditional()) | ||||||
982 | nMask &= ~SfxStyleSearchBits::SwCondColl; | ||||||
983 | m_pBasePool->Make(sStyleName, m_rEntry.m_eFamily, nMask); | ||||||
984 | pNewStyle->SetDoc(m_pDocShell->GetDoc(), m_pBasePool); | ||||||
985 | pNewStyle->SetStyleName(sStyleName); | ||||||
986 | const OUString sParentStyleName(pNewStyle->GetParentStyleName()); | ||||||
987 | if (!sParentStyleName.isEmpty()) | ||||||
988 | { | ||||||
989 | SfxStyleSheetBase* pParentBase = m_pBasePool->Find(sParentStyleName, m_rEntry.m_eFamily); | ||||||
990 | if(pParentBase && pParentBase->GetFamily() == m_rEntry.m_eFamily && | ||||||
991 | pParentBase->GetPool() == m_pBasePool) | ||||||
992 | m_pBasePool->SetParent(m_rEntry.m_eFamily, sStyleName, sParentStyleName); | ||||||
993 | } | ||||||
994 | // after all, we still need to apply the properties of the descriptor | ||||||
995 | pNewStyle->ApplyDescriptorProperties(); | ||||||
996 | } | ||||||
997 | } | ||||||
998 | |||||||
999 | void XStyleFamily::replaceByName(const OUString& rName, const uno::Any& rElement) | ||||||
1000 | { | ||||||
1001 | SolarMutexGuard aGuard; | ||||||
1002 | if(!m_pBasePool) | ||||||
1003 | throw uno::RuntimeException(); | ||||||
1004 | OUString sStyleName; | ||||||
1005 | SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId); | ||||||
1006 | SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily); | ||||||
1007 | // replacements only for userdefined styles | ||||||
1008 | if(!pBase) | ||||||
1009 | throw container::NoSuchElementException(); | ||||||
1010 | if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId) | ||||||
1011 | { | ||||||
1012 | // handle cell styles, don't call on assigned cell styles (TableStyle child) | ||||||
1013 | OUString sParent; | ||||||
1014 | SwBoxAutoFormat* pBoxAutoFormat = SwXTextCellStyle::GetBoxAutoFormat(m_pDocShell, sStyleName, &sParent); | ||||||
1015 | if (pBoxAutoFormat && sParent.isEmpty())// if parent exists then this style is assigned to a table style. Don't replace. | ||||||
1016 | { | ||||||
1017 | uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>(); | ||||||
1018 | SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get()); | ||||||
1019 | if (!pStyleToReplaceWith) | ||||||
1020 | throw lang::IllegalArgumentException(); | ||||||
1021 | |||||||
1022 | pStyleToReplaceWith->setName(sStyleName); | ||||||
1023 | *pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat(); | ||||||
1024 | pStyleToReplaceWith->SetPhysical(); | ||||||
1025 | } | ||||||
1026 | } | ||||||
1027 | else if (SwGetPoolIdFromName::TabStyle == m_rEntry.m_aPoolId) | ||||||
1028 | { | ||||||
1029 | // handle table styles | ||||||
1030 | SwTableAutoFormat* pTableAutoFormat = SwXTextTableStyle::GetTableAutoFormat(m_pDocShell, sStyleName); | ||||||
1031 | if (pTableAutoFormat) | ||||||
1032 | { | ||||||
1033 | uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>(); | ||||||
1034 | SwXTextTableStyle* pStyleToReplaceWith = dynamic_cast<SwXTextTableStyle*>(xStyle.get()); | ||||||
1035 | if (!pStyleToReplaceWith) | ||||||
1036 | throw lang::IllegalArgumentException(); | ||||||
1037 | |||||||
1038 | pStyleToReplaceWith->setName(sStyleName); | ||||||
1039 | *pTableAutoFormat = *pStyleToReplaceWith->GetTableFormat(); | ||||||
1040 | pStyleToReplaceWith->SetPhysical(); | ||||||
1041 | } | ||||||
1042 | } | ||||||
1043 | else | ||||||
1044 | { | ||||||
1045 | if(!pBase->IsUserDefined()) | ||||||
1046 | throw lang::IllegalArgumentException(); | ||||||
1047 | //if there's an object available to this style then it must be invalidated | ||||||
1048 | uno::Reference<style::XStyle> xStyle = FindStyle(pBase->GetName()); | ||||||
1049 | if(xStyle.is()) | ||||||
1050 | { | ||||||
1051 | SwXStyle* pStyle = comphelper::getUnoTunnelImplementation<SwXStyle>(xStyle); | ||||||
1052 | if(pStyle) | ||||||
1053 | pStyle->Invalidate(); | ||||||
1054 | } | ||||||
1055 | m_pBasePool->Remove(pBase); | ||||||
1056 | insertByName(rName, rElement); | ||||||
1057 | } | ||||||
1058 | } | ||||||
1059 | |||||||
1060 | void XStyleFamily::removeByName(const OUString& rName) | ||||||
1061 | { | ||||||
1062 | SolarMutexGuard aGuard; | ||||||
1063 | if(!m_pBasePool) | ||||||
1064 | throw uno::RuntimeException(); | ||||||
1065 | OUString sName; | ||||||
1066 | SwStyleNameMapper::FillUIName(rName, sName, m_rEntry.m_aPoolId); | ||||||
1067 | SfxStyleSheetBase* pBase = m_pBasePool->Find(sName, m_rEntry.m_eFamily); | ||||||
1068 | if(!pBase) | ||||||
1069 | throw container::NoSuchElementException(); | ||||||
1070 | if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId) | ||||||
1071 | { | ||||||
1072 | // handle cell style | ||||||
1073 | m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(rName); | ||||||
1074 | } | ||||||
1075 | else if (SwGetPoolIdFromName::TabStyle == m_rEntry.m_aPoolId) | ||||||
1076 | { | ||||||
1077 | // handle table style | ||||||
1078 | m_pDocShell->GetDoc()->GetTableStyles().EraseAutoFormat(rName); | ||||||
1079 | } | ||||||
1080 | else | ||||||
1081 | m_pBasePool->Remove(pBase); | ||||||
1082 | } | ||||||
1083 | |||||||
1084 | uno::Any SAL_CALL XStyleFamily::getPropertyValue( const OUString& sPropertyName ) | ||||||
1085 | { | ||||||
1086 | if(sPropertyName != "DisplayName") | ||||||
1087 | throw beans::UnknownPropertyException( "unknown property: " + sPropertyName, static_cast<OWeakObject *>(this) ); | ||||||
1088 | SolarMutexGuard aGuard; | ||||||
1089 | return uno::makeAny(SwResId(m_rEntry.m_pResId)); | ||||||
1090 | } | ||||||
1091 | |||||||
1092 | |||||||
1093 | SwXStyle* XStyleFamily::FindStyle(const OUString& rStyleName) const | ||||||
1094 | { | ||||||
1095 | const size_t nLCount = m_pBasePool->GetSizeOfVector(); | ||||||
1096 | for(size_t i = 0; i < nLCount; ++i) | ||||||
1097 | { | ||||||
1098 | SfxListener* pListener = m_pBasePool->GetListener(i); | ||||||
1099 | SwXStyle* pTempStyle = dynamic_cast<SwXStyle*>(pListener); | ||||||
1100 | if(pTempStyle && pTempStyle->GetFamily() == m_rEntry.m_eFamily && pTempStyle->GetStyleName() == rStyleName) | ||||||
1101 | return pTempStyle; | ||||||
1102 | } | ||||||
1103 | return nullptr; | ||||||
1104 | } | ||||||
1105 | |||||||
1106 | static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries() | ||||||
1107 | { | ||||||
1108 | if(!our_pStyleFamilyEntries) | ||||||
1109 | { | ||||||
1110 | our_pStyleFamilyEntries = new std::vector<StyleFamilyEntry>{ | ||||||
1111 | { SfxStyleFamily::Char, PROPERTY_MAP_CHAR_STYLE1, SwGetPoolIdFromName::ChrFmt, "CharacterStyles", STR_STYLE_FAMILY_CHARACTERreinterpret_cast<char const *>("STR_STYLE_FAMILY_CHARACTER" "\004" u8"Character"), &lcl_GetCountOrName<SfxStyleFamily::Char>, &lcl_CreateStyle<SfxStyleFamily::Char>, &lcl_TranslateIndex<SfxStyleFamily::Char> }, | ||||||
1112 | { SfxStyleFamily::Para, PROPERTY_MAP_PARA_STYLE2, SwGetPoolIdFromName::TxtColl, "ParagraphStyles", STR_STYLE_FAMILY_PARAGRAPHreinterpret_cast<char const *>("STR_STYLE_FAMILY_PARAGRAPH" "\004" u8"Paragraph"), &lcl_GetCountOrName<SfxStyleFamily::Para>, &lcl_CreateStyle<SfxStyleFamily::Para>, &lcl_TranslateIndex<SfxStyleFamily::Para> }, | ||||||
1113 | { SfxStyleFamily::Page, PROPERTY_MAP_PAGE_STYLE4, SwGetPoolIdFromName::PageDesc, "PageStyles", STR_STYLE_FAMILY_PAGEreinterpret_cast<char const *>("STR_STYLE_FAMILY_PAGE" "\004" u8"Pages"), &lcl_GetCountOrName<SfxStyleFamily::Page>, &lcl_CreateStyle<SfxStyleFamily::Page>, &lcl_TranslateIndexRange<RES_POOLPAGE_BEGIN, nPoolPageRange( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)> }, | ||||||
1114 | { SfxStyleFamily::Frame, PROPERTY_MAP_FRAME_STYLE3, SwGetPoolIdFromName::FrmFmt, "FrameStyles", STR_STYLE_FAMILY_FRAMEreinterpret_cast<char const *>("STR_STYLE_FAMILY_FRAME" "\004" u8"Frame"), &lcl_GetCountOrName<SfxStyleFamily::Frame>, &lcl_CreateStyle<SfxStyleFamily::Frame>, &lcl_TranslateIndexRange<RES_POOLFRM_BEGIN, nPoolFrameRange( RES_POOLFRM_END - RES_POOLFRM_BEGIN)> }, | ||||||
1115 | { SfxStyleFamily::Pseudo, PROPERTY_MAP_NUM_STYLE5, SwGetPoolIdFromName::NumRule, "NumberingStyles", STR_STYLE_FAMILY_NUMBERINGreinterpret_cast<char const *>("STR_STYLE_FAMILY_NUMBERING" "\004" u8"Numbering"), &lcl_GetCountOrName<SfxStyleFamily::Pseudo>, &lcl_CreateStyle<SfxStyleFamily::Pseudo>, &lcl_TranslateIndexRange<RES_POOLNUMRULE_BEGIN, nPoolNumRange( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN)> }, | ||||||
1116 | { SfxStyleFamily::Table, PROPERTY_MAP_TABLE_STYLE100, SwGetPoolIdFromName::TabStyle, "TableStyles", STR_STYLE_FAMILY_TABLEreinterpret_cast<char const *>("STR_STYLE_FAMILY_TABLE" "\004" u8"Table"), &lcl_GetCountOrName<SfxStyleFamily::Table>, &lcl_CreateStyle<SfxStyleFamily::Table>, &lcl_TranslateIndex<SfxStyleFamily::Table> }, | ||||||
1117 | { SfxStyleFamily::Cell, PROPERTY_MAP_CELL_STYLE101, SwGetPoolIdFromName::CellStyle,"CellStyles", STR_STYLE_FAMILY_CELLreinterpret_cast<char const *>("STR_STYLE_FAMILY_CELL" "\004" u8"Cell"), &lcl_GetCountOrName<SfxStyleFamily::Cell>, &lcl_CreateStyle<SfxStyleFamily::Cell>, &lcl_TranslateIndex<SfxStyleFamily::Cell> } | ||||||
1118 | }; | ||||||
1119 | } | ||||||
1120 | return our_pStyleFamilyEntries; | ||||||
1121 | } | ||||||
1122 | |||||||
1123 | static const std::vector<ParagraphStyleCategoryEntry>* lcl_GetParagraphStyleCategoryEntries() | ||||||
1124 | { | ||||||
1125 | if(!our_pParagraphStyleCategoryEntries) | ||||||
1126 | { | ||||||
1127 | our_pParagraphStyleCategoryEntries = new std::vector<ParagraphStyleCategoryEntry>{ | ||||||
1128 | { style::ParagraphStyleCategory::TEXT, SfxStyleSearchBits::SwText, COLL_TEXT_BITS }, | ||||||
1129 | { style::ParagraphStyleCategory::CHAPTER, SfxStyleSearchBits::SwChapter, COLL_DOC_BITS }, | ||||||
1130 | { style::ParagraphStyleCategory::LIST, SfxStyleSearchBits::SwList, COLL_LISTS_BITS }, | ||||||
1131 | { style::ParagraphStyleCategory::INDEX, SfxStyleSearchBits::SwIndex, COLL_REGISTER_BITS }, | ||||||
1132 | { style::ParagraphStyleCategory::EXTRA, SfxStyleSearchBits::SwExtra, COLL_EXTRA_BITS }, | ||||||
1133 | { style::ParagraphStyleCategory::HTML, SfxStyleSearchBits::SwHtml, COLL_HTML_BITS } | ||||||
1134 | }; | ||||||
1135 | } | ||||||
1136 | return our_pParagraphStyleCategoryEntries; | ||||||
1137 | } | ||||||
1138 | |||||||
1139 | namespace { | ||||||
1140 | |||||||
1141 | class SwStyleProperties_Impl | ||||||
1142 | { | ||||||
1143 | const PropertyEntryVector_t aPropertyEntries; | ||||||
1144 | std::map<OUString, uno::Any> m_vPropertyValues; | ||||||
1145 | public: | ||||||
1146 | explicit SwStyleProperties_Impl(const SfxItemPropertyMap& rMap) | ||||||
1147 | : aPropertyEntries(rMap.getPropertyEntries()) | ||||||
1148 | { } | ||||||
1149 | |||||||
1150 | bool AllowsKey(const OUString& rName) | ||||||
1151 | { | ||||||
1152 | return std::any_of(aPropertyEntries.begin(), aPropertyEntries.end(), | ||||||
1153 | [rName] (const SfxItemPropertyNamedEntry& rEntry) {return rName == rEntry.sName;} ); | ||||||
1154 | } | ||||||
1155 | bool SetProperty(const OUString& rName, const uno::Any& rValue) | ||||||
1156 | { | ||||||
1157 | if(!AllowsKey(rName)) | ||||||
1158 | return false; | ||||||
1159 | m_vPropertyValues[rName] = rValue; | ||||||
1160 | return true; | ||||||
1161 | } | ||||||
1162 | void GetProperty(const OUString& rName, const uno::Any*& pAny) | ||||||
1163 | { | ||||||
1164 | if(!AllowsKey(rName)) | ||||||
1165 | { | ||||||
1166 | pAny = nullptr; | ||||||
1167 | return; | ||||||
1168 | } | ||||||
1169 | pAny = &m_vPropertyValues[rName]; | ||||||
1170 | return; | ||||||
1171 | } | ||||||
1172 | bool ClearProperty( const OUString& rName ) | ||||||
1173 | { | ||||||
1174 | if(!AllowsKey(rName)) | ||||||
1175 | return false; | ||||||
1176 | m_vPropertyValues[rName] = uno::Any(); | ||||||
1177 | return true; | ||||||
1178 | } | ||||||
1179 | void ClearAllProperties( ) | ||||||
1180 | { m_vPropertyValues.clear(); } | ||||||
1181 | void Apply(SwXStyle& rStyle) | ||||||
1182 | { | ||||||
1183 | for(const auto& rPropertyPair : m_vPropertyValues) | ||||||
1184 | { | ||||||
1185 | if(rPropertyPair.second.hasValue()) | ||||||
1186 | rStyle.setPropertyValue(rPropertyPair.first, rPropertyPair.second); | ||||||
1187 | } | ||||||
1188 | } | ||||||
1189 | static void GetProperty(const OUString &rPropertyName, const uno::Reference < beans::XPropertySet > &rxPropertySet, uno::Any& rAny ) | ||||||
1190 | { | ||||||
1191 | rAny = rxPropertySet->getPropertyValue( rPropertyName ); | ||||||
1192 | } | ||||||
1193 | }; | ||||||
1194 | |||||||
1195 | } | ||||||
1196 | |||||||
1197 | static SwGetPoolIdFromName lcl_GetSwEnumFromSfxEnum(SfxStyleFamily eFamily) | ||||||
1198 | { | ||||||
1199 | auto pEntries(lcl_GetStyleFamilyEntries()); | ||||||
1200 | const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(), | ||||||
1201 | [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; }); | ||||||
1202 | if(pEntry != pEntries->end()) | ||||||
1203 | return pEntry->m_aPoolId; | ||||||
1204 | SAL_WARN("sw.uno", "someone asking for all styles in unostyle.cxx!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "someone asking for all styles in unostyle.cxx!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1204" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "someone asking for all styles in unostyle.cxx!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "someone asking for all styles in unostyle.cxx!"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ( "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1204" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "someone asking for all styles in unostyle.cxx!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1204" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "someone asking for all styles in unostyle.cxx!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "someone asking for all styles in unostyle.cxx!"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ( "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1204" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1205 | return SwGetPoolIdFromName::ChrFmt; | ||||||
1206 | } | ||||||
1207 | |||||||
1208 | namespace | ||||||
1209 | { | ||||||
1210 | class theSwXStyleUnoTunnelId : public rtl::Static<UnoTunnelIdInit, theSwXStyleUnoTunnelId> {}; | ||||||
1211 | } | ||||||
1212 | |||||||
1213 | const uno::Sequence<sal_Int8>& SwXStyle::getUnoTunnelId() | ||||||
1214 | { | ||||||
1215 | return theSwXStyleUnoTunnelId::get().getSeq(); | ||||||
1216 | } | ||||||
1217 | |||||||
1218 | sal_Int64 SAL_CALL SwXStyle::getSomething(const uno::Sequence<sal_Int8>& rId) | ||||||
1219 | { | ||||||
1220 | if(isUnoTunnelId<SwXStyle>(rId)) | ||||||
1221 | { | ||||||
1222 | return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); | ||||||
1223 | } | ||||||
1224 | return 0; | ||||||
1225 | } | ||||||
1226 | |||||||
1227 | |||||||
1228 | uno::Sequence< OUString > SwXStyle::getSupportedServiceNames() | ||||||
1229 | { | ||||||
1230 | long nCount = 1; | ||||||
1231 | if(SfxStyleFamily::Para == m_rEntry.m_eFamily) | ||||||
1232 | { | ||||||
1233 | nCount = 5; | ||||||
1234 | if(m_bIsConditional) | ||||||
1235 | nCount++; | ||||||
1236 | } | ||||||
1237 | else if(SfxStyleFamily::Char == m_rEntry.m_eFamily) | ||||||
1238 | nCount = 5; | ||||||
1239 | else if(SfxStyleFamily::Page == m_rEntry.m_eFamily) | ||||||
1240 | nCount = 3; | ||||||
1241 | uno::Sequence< OUString > aRet(nCount); | ||||||
1242 | OUString* pArray = aRet.getArray(); | ||||||
1243 | pArray[0] = "com.sun.star.style.Style"; | ||||||
1244 | switch(m_rEntry.m_eFamily) | ||||||
1245 | { | ||||||
1246 | case SfxStyleFamily::Char: | ||||||
1247 | pArray[1] = "com.sun.star.style.CharacterStyle"; | ||||||
1248 | pArray[2] = "com.sun.star.style.CharacterProperties"; | ||||||
1249 | pArray[3] = "com.sun.star.style.CharacterPropertiesAsian"; | ||||||
1250 | pArray[4] = "com.sun.star.style.CharacterPropertiesComplex"; | ||||||
1251 | break; | ||||||
1252 | case SfxStyleFamily::Page: | ||||||
1253 | pArray[1] = "com.sun.star.style.PageStyle"; | ||||||
1254 | pArray[2] = "com.sun.star.style.PageProperties"; | ||||||
1255 | break; | ||||||
1256 | case SfxStyleFamily::Para: | ||||||
1257 | pArray[1] = "com.sun.star.style.ParagraphStyle"; | ||||||
1258 | pArray[2] = "com.sun.star.style.ParagraphProperties"; | ||||||
1259 | pArray[3] = "com.sun.star.style.ParagraphPropertiesAsian"; | ||||||
1260 | pArray[4] = "com.sun.star.style.ParagraphPropertiesComplex"; | ||||||
1261 | if(m_bIsConditional) | ||||||
1262 | pArray[5] = "com.sun.star.style.ConditionalParagraphStyle"; | ||||||
1263 | break; | ||||||
1264 | |||||||
1265 | default: | ||||||
1266 | ; | ||||||
1267 | } | ||||||
1268 | return aRet; | ||||||
1269 | } | ||||||
1270 | |||||||
1271 | static uno::Reference<beans::XPropertySet> lcl_InitStandardStyle(const SfxStyleFamily eFamily, uno::Reference<container::XNameAccess> const & rxStyleFamily) | ||||||
1272 | { | ||||||
1273 | using return_t = decltype(lcl_InitStandardStyle(eFamily, rxStyleFamily)); | ||||||
1274 | if(eFamily != SfxStyleFamily::Para && eFamily != SfxStyleFamily::Page) | ||||||
1275 | return {}; | ||||||
1276 | auto aResult(rxStyleFamily->getByName("Standard")); | ||||||
1277 | if(!aResult.has<return_t>()) | ||||||
1278 | return {}; | ||||||
1279 | return aResult.get<return_t>(); | ||||||
1280 | } | ||||||
1281 | |||||||
1282 | static uno::Reference<container::XNameAccess> lcl_InitStyleFamily(SwDoc* pDoc, const StyleFamilyEntry& rEntry) | ||||||
1283 | { | ||||||
1284 | using return_t = decltype(lcl_InitStyleFamily(pDoc, rEntry)); | ||||||
1285 | if(rEntry.m_eFamily != SfxStyleFamily::Char | ||||||
1286 | && rEntry.m_eFamily != SfxStyleFamily::Para | ||||||
1287 | && rEntry.m_eFamily != SfxStyleFamily::Page) | ||||||
1288 | return {}; | ||||||
1289 | auto xModel(pDoc->GetDocShell()->GetBaseModel()); | ||||||
1290 | uno::Reference<style::XStyleFamiliesSupplier> xFamilySupplier(xModel, uno::UNO_QUERY); | ||||||
1291 | auto xFamilies = xFamilySupplier->getStyleFamilies(); | ||||||
1292 | auto aResult(xFamilies->getByName(rEntry.m_sName)); | ||||||
1293 | if(!aResult.has<return_t>()) | ||||||
1294 | return {}; | ||||||
1295 | return aResult.get<return_t>(); | ||||||
1296 | } | ||||||
1297 | |||||||
1298 | static bool lcl_InitConditional(SfxStyleSheetBasePool* pBasePool, const SfxStyleFamily eFamily, const OUString& rStyleName) | ||||||
1299 | { | ||||||
1300 | if(!pBasePool || eFamily != SfxStyleFamily::Para) | ||||||
1301 | return false; | ||||||
1302 | SfxStyleSheetBase* pBase = pBasePool->Find(rStyleName, eFamily); | ||||||
1303 | SAL_WARN_IF(!pBase, "sw.uno", "where is the style?" )do { if (true && (!pBase)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "where is the style?" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1303" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1303" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "where is the style?") == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1303" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1303" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1304 | if(!pBase) | ||||||
1305 | return false; | ||||||
1306 | const sal_uInt16 nId(SwStyleNameMapper::GetPoolIdFromUIName(rStyleName, SwGetPoolIdFromName::TxtColl)); | ||||||
1307 | if(nId != USHRT_MAX(32767 *2 +1)) | ||||||
1308 | return ::IsConditionalByPoolId(nId); | ||||||
1309 | return RES_CONDTXTFMTCOLL == static_cast<SwDocStyleSheet*>(pBase)->GetCollection()->Which(); | ||||||
1310 | } | ||||||
1311 | |||||||
1312 | static const StyleFamilyEntry& lcl_GetStyleEntry(const SfxStyleFamily eFamily) | ||||||
1313 | { | ||||||
1314 | auto pEntries = lcl_GetStyleFamilyEntries(); | ||||||
1315 | const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(), | ||||||
1316 | [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; }); | ||||||
1317 | assert(pEntry != pEntries->end())(static_cast <bool> (pEntry != pEntries->end()) ? void (0) : __assert_fail ("pEntry != pEntries->end()", "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 1317, __extension__ __PRETTY_FUNCTION__)); | ||||||
1318 | return *pEntry; | ||||||
1319 | } | ||||||
1320 | |||||||
1321 | SwXStyle::SwXStyle(SwDoc* pDoc, SfxStyleFamily eFamily, bool bConditional) | ||||||
1322 | : m_pDoc(pDoc) | ||||||
1323 | , m_rEntry(lcl_GetStyleEntry(eFamily)) | ||||||
1324 | , m_bIsDescriptor(true) | ||||||
1325 | , m_bIsConditional(bConditional) | ||||||
1326 | , m_pBasePool(nullptr) | ||||||
1327 | , m_xStyleFamily(lcl_InitStyleFamily(pDoc, m_rEntry)) | ||||||
1328 | , m_xStyleData(lcl_InitStandardStyle(eFamily, m_xStyleFamily)) | ||||||
1329 | { | ||||||
1330 | assert(!m_bIsConditional || m_rEntry.m_eFamily == SfxStyleFamily::Para)(static_cast <bool> (!m_bIsConditional || m_rEntry.m_eFamily == SfxStyleFamily::Para) ? void (0) : __assert_fail ("!m_bIsConditional || m_rEntry.m_eFamily == SfxStyleFamily::Para" , "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 1330, __extension__ __PRETTY_FUNCTION__)); // only paragraph styles are conditional | ||||||
1331 | // Register ourselves as a listener to the document (via the page descriptor) | ||||||
1332 | SvtListener::StartListening(pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier()); | ||||||
1333 | m_pPropertiesImpl = std::make_unique<SwStyleProperties_Impl>( | ||||||
1334 | aSwMapProvider.GetPropertySet(m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE93 : m_rEntry.m_nPropMapType)->getPropertyMap()); | ||||||
1335 | } | ||||||
1336 | |||||||
1337 | SwXStyle::SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const OUString& rStyleName) | ||||||
1338 | : m_pDoc(pDoc) | ||||||
1339 | , m_sStyleName(rStyleName) | ||||||
1340 | , m_rEntry(lcl_GetStyleEntry(eFamily)) | ||||||
1341 | , m_bIsDescriptor(false) | ||||||
1342 | , m_bIsConditional(lcl_InitConditional(pPool, eFamily, rStyleName)) | ||||||
1343 | , m_pBasePool(pPool) | ||||||
1344 | { } | ||||||
1345 | |||||||
1346 | SwXStyle::~SwXStyle() | ||||||
1347 | { | ||||||
1348 | SolarMutexGuard aGuard; | ||||||
1349 | if(m_pBasePool) | ||||||
1350 | SfxListener::EndListening(*m_pBasePool); | ||||||
1351 | m_pPropertiesImpl.reset(); | ||||||
1352 | SvtListener::EndListeningAll(); | ||||||
1353 | } | ||||||
1354 | |||||||
1355 | void SwXStyle::Notify(const SfxHint& rHint) | ||||||
1356 | { | ||||||
1357 | if(rHint.GetId() == SfxHintId::Dying) | ||||||
1358 | { | ||||||
1359 | m_pDoc = nullptr; | ||||||
1360 | m_xStyleData.clear(); | ||||||
1361 | m_xStyleFamily.clear(); | ||||||
1362 | } | ||||||
1363 | } | ||||||
1364 | |||||||
1365 | OUString SwXStyle::getName() | ||||||
1366 | { | ||||||
1367 | SolarMutexGuard aGuard; | ||||||
1368 | if(!m_pBasePool) | ||||||
1369 | return m_sStyleName; | ||||||
1370 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
1371 | SAL_WARN_IF(!pBase, "sw.uno", "where is the style?")do { if (true && (!pBase)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "where is the style?" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1371" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1371" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "where is the style?") == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1371" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1371" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1372 | if(!pBase) | ||||||
1373 | throw uno::RuntimeException(); | ||||||
1374 | OUString aString; | ||||||
1375 | SwStyleNameMapper::FillProgName(pBase->GetName(), aString, lcl_GetSwEnumFromSfxEnum ( m_rEntry.m_eFamily )); | ||||||
1376 | return aString; | ||||||
1377 | } | ||||||
1378 | |||||||
1379 | void SwXStyle::setName(const OUString& rName) | ||||||
1380 | { | ||||||
1381 | SolarMutexGuard aGuard; | ||||||
1382 | if(!m_pBasePool) | ||||||
1383 | { | ||||||
1384 | m_sStyleName = rName; | ||||||
1385 | return; | ||||||
1386 | } | ||||||
1387 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
1388 | SAL_WARN_IF(!pBase, "sw.uno", "where is the style?")do { if (true && (!pBase)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "where is the style?" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1388" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1388" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "where is the style?") == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1388" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "1388" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1389 | if(!pBase || !pBase->IsUserDefined()) | ||||||
1390 | throw uno::RuntimeException(); | ||||||
1391 | rtl::Reference<SwDocStyleSheet> xTmp(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
1392 | if(!xTmp->SetName(rName)) | ||||||
1393 | throw uno::RuntimeException(); | ||||||
1394 | m_sStyleName = rName; | ||||||
1395 | } | ||||||
1396 | |||||||
1397 | sal_Bool SwXStyle::isUserDefined() | ||||||
1398 | { | ||||||
1399 | SolarMutexGuard aGuard; | ||||||
1400 | if(!m_pBasePool) | ||||||
1401 | throw uno::RuntimeException(); | ||||||
1402 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
1403 | //if it is not found it must be non user defined | ||||||
1404 | return pBase && pBase->IsUserDefined(); | ||||||
1405 | } | ||||||
1406 | |||||||
1407 | sal_Bool SwXStyle::isInUse() | ||||||
1408 | { | ||||||
1409 | SolarMutexGuard aGuard; | ||||||
1410 | if(!m_pBasePool) | ||||||
1411 | throw uno::RuntimeException(); | ||||||
1412 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily, SfxStyleSearchBits::Used); | ||||||
1413 | return pBase && pBase->IsUsed(); | ||||||
1414 | } | ||||||
1415 | |||||||
1416 | OUString SwXStyle::getParentStyle() | ||||||
1417 | { | ||||||
1418 | SolarMutexGuard aGuard; | ||||||
1419 | if(!m_pBasePool) | ||||||
1420 | { | ||||||
1421 | if(!m_bIsDescriptor) | ||||||
1422 | throw uno::RuntimeException(); | ||||||
1423 | return m_sParentStyleName; | ||||||
1424 | } | ||||||
1425 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
1426 | OUString aString; | ||||||
1427 | if(pBase) | ||||||
1428 | aString = pBase->GetParent(); | ||||||
1429 | SwStyleNameMapper::FillProgName(aString, aString, lcl_GetSwEnumFromSfxEnum(m_rEntry.m_eFamily)); | ||||||
1430 | return aString; | ||||||
1431 | } | ||||||
1432 | |||||||
1433 | void SwXStyle::setParentStyle(const OUString& rParentStyle) | ||||||
1434 | { | ||||||
1435 | SolarMutexGuard aGuard; | ||||||
1436 | OUString sParentStyle; | ||||||
1437 | SwStyleNameMapper::FillUIName(rParentStyle, sParentStyle, lcl_GetSwEnumFromSfxEnum ( m_rEntry.m_eFamily ) ); | ||||||
1438 | if(!m_pBasePool) | ||||||
1439 | { | ||||||
1440 | if(!m_bIsDescriptor) | ||||||
1441 | throw uno::RuntimeException(); | ||||||
1442 | m_sParentStyleName = sParentStyle; | ||||||
1443 | try | ||||||
1444 | { | ||||||
1445 | const auto aAny = m_xStyleFamily->getByName(sParentStyle); | ||||||
1446 | m_xStyleData = aAny.get<decltype(m_xStyleData)>(); | ||||||
1447 | } | ||||||
1448 | catch(...) | ||||||
1449 | { } | ||||||
1450 | return; | ||||||
1451 | } | ||||||
1452 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
1453 | if(!pBase) | ||||||
1454 | throw uno::RuntimeException(); | ||||||
1455 | rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
1456 | //make it a 'real' style - necessary for pooled styles | ||||||
1457 | xBase->GetItemSet(); | ||||||
1458 | if(xBase->GetParent() != sParentStyle) | ||||||
1459 | { | ||||||
1460 | if(!xBase->SetParent(sParentStyle)) | ||||||
1461 | throw uno::RuntimeException(); | ||||||
1462 | } | ||||||
1463 | } | ||||||
1464 | |||||||
1465 | uno::Reference<beans::XPropertySetInfo> SwXStyle::getPropertySetInfo() | ||||||
1466 | { | ||||||
1467 | if(m_bIsConditional) | ||||||
1468 | { | ||||||
1469 | assert(m_rEntry.m_eFamily == SfxStyleFamily::Para)(static_cast <bool> (m_rEntry.m_eFamily == SfxStyleFamily ::Para) ? void (0) : __assert_fail ("m_rEntry.m_eFamily == SfxStyleFamily::Para" , "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 1469, __extension__ __PRETTY_FUNCTION__)); | ||||||
1470 | static uno::Reference<beans::XPropertySetInfo> xCondParaRef; | ||||||
1471 | xCondParaRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CONDITIONAL_PARA_STYLE93)->getPropertySetInfo(); | ||||||
1472 | return xCondParaRef; | ||||||
1473 | } | ||||||
1474 | return m_rEntry.m_xPSInfo; | ||||||
1475 | } | ||||||
1476 | |||||||
1477 | void SwXStyle::ApplyDescriptorProperties() | ||||||
1478 | { | ||||||
1479 | m_bIsDescriptor = false; | ||||||
1480 | m_xStyleData.clear(); | ||||||
1481 | m_xStyleFamily.clear(); | ||||||
1482 | m_pPropertiesImpl->Apply(*this); | ||||||
1483 | } | ||||||
1484 | |||||||
1485 | namespace { | ||||||
1486 | |||||||
1487 | class SwStyleBase_Impl | ||||||
1488 | { | ||||||
1489 | private: | ||||||
1490 | SwDoc& m_rDoc; | ||||||
1491 | const SwPageDesc* m_pOldPageDesc; | ||||||
1492 | rtl::Reference<SwDocStyleSheet> m_xNewBase; | ||||||
1493 | SfxItemSet* m_pItemSet; | ||||||
1494 | std::unique_ptr<SfxItemSet> m_pMyItemSet; | ||||||
1495 | OUString m_rStyleName; | ||||||
1496 | const SwAttrSet* m_pParentStyle; | ||||||
1497 | public: | ||||||
1498 | SwStyleBase_Impl(SwDoc& rSwDoc, const OUString& rName, const SwAttrSet* pParentStyle) | ||||||
1499 | : m_rDoc(rSwDoc) | ||||||
1500 | , m_pOldPageDesc(nullptr) | ||||||
1501 | , m_pItemSet(nullptr) | ||||||
1502 | , m_rStyleName(rName) | ||||||
1503 | , m_pParentStyle(pParentStyle) | ||||||
1504 | { } | ||||||
1505 | |||||||
1506 | rtl::Reference<SwDocStyleSheet>& getNewBase() | ||||||
1507 | { | ||||||
1508 | return m_xNewBase; | ||||||
1509 | } | ||||||
1510 | |||||||
1511 | void setNewBase(SwDocStyleSheet* pNew) | ||||||
1512 | { | ||||||
1513 | m_xNewBase = pNew; | ||||||
1514 | } | ||||||
1515 | |||||||
1516 | bool HasItemSet() const | ||||||
1517 | { | ||||||
1518 | return m_xNewBase.is(); | ||||||
1519 | } | ||||||
1520 | |||||||
1521 | SfxItemSet& GetItemSet() | ||||||
1522 | { | ||||||
1523 | assert(m_xNewBase.is())(static_cast <bool> (m_xNewBase.is()) ? void (0) : __assert_fail ("m_xNewBase.is()", "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 1523, __extension__ __PRETTY_FUNCTION__)); | ||||||
1524 | if(!m_pItemSet) | ||||||
1525 | { | ||||||
1526 | m_pMyItemSet.reset(new SfxItemSet(m_xNewBase->GetItemSet())); | ||||||
1527 | m_pItemSet = m_pMyItemSet.get(); | ||||||
1528 | |||||||
1529 | // set parent style to have the correct XFillStyle setting as XFILL_NONE | ||||||
1530 | if(!m_pItemSet->GetParent() && m_pParentStyle) | ||||||
1531 | m_pItemSet->SetParent(m_pParentStyle); | ||||||
1532 | } | ||||||
1533 | return *m_pItemSet; | ||||||
1534 | } | ||||||
1535 | |||||||
1536 | const SwPageDesc* GetOldPageDesc(); | ||||||
1537 | |||||||
1538 | // still a hack, but a bit more explicit and with a proper scope | ||||||
1539 | struct ItemSetOverrider | ||||||
1540 | { | ||||||
1541 | SwStyleBase_Impl& m_rStyleBase; | ||||||
1542 | SfxItemSet* m_pOldSet; | ||||||
1543 | ItemSetOverrider(SwStyleBase_Impl& rStyleBase, SfxItemSet* pTemp) | ||||||
1544 | : m_rStyleBase(rStyleBase) | ||||||
1545 | , m_pOldSet(m_rStyleBase.m_pItemSet) | ||||||
1546 | { m_rStyleBase.m_pItemSet = pTemp; } | ||||||
1547 | ~ItemSetOverrider() | ||||||
1548 | { m_rStyleBase.m_pItemSet = m_pOldSet; }; | ||||||
1549 | }; | ||||||
1550 | }; | ||||||
1551 | |||||||
1552 | const char* STR_POOLPAGE_ARY[] = | ||||||
1553 | { | ||||||
1554 | // Page styles | ||||||
1555 | STR_POOLPAGE_STANDARDreinterpret_cast<char const *>("STR_POOLPAGE_STANDARD" "\004" u8"Default Page Style"), | ||||||
1556 | STR_POOLPAGE_FIRSTreinterpret_cast<char const *>("STR_POOLPAGE_FIRST" "\004" u8"First Page"), | ||||||
1557 | STR_POOLPAGE_LEFTreinterpret_cast<char const *>("STR_POOLPAGE_LEFT" "\004" u8"Left Page"), | ||||||
1558 | STR_POOLPAGE_RIGHTreinterpret_cast<char const *>("STR_POOLPAGE_RIGHT" "\004" u8"Right Page"), | ||||||
1559 | STR_POOLPAGE_ENVELOPEreinterpret_cast<char const *>("STR_POOLPAGE_ENVELOPE" "\004" u8"Envelope"), | ||||||
1560 | STR_POOLPAGE_REGISTERreinterpret_cast<char const *>("STR_POOLPAGE_REGISTER" "\004" u8"Index"), | ||||||
1561 | STR_POOLPAGE_HTMLreinterpret_cast<char const *>("STR_POOLPAGE_HTML" "\004" u8"HTML"), | ||||||
1562 | STR_POOLPAGE_FOOTNOTEreinterpret_cast<char const *>("STR_POOLPAGE_FOOTNOTE" "\004" u8"Footnote"), | ||||||
1563 | STR_POOLPAGE_ENDNOTEreinterpret_cast<char const *>("STR_POOLPAGE_ENDNOTE" "\004" u8"Endnote"), | ||||||
1564 | STR_POOLPAGE_LANDSCAPEreinterpret_cast<char const *>("STR_POOLPAGE_LANDSCAPE" "\004" u8"Landscape") | ||||||
1565 | }; | ||||||
1566 | } | ||||||
1567 | |||||||
1568 | const SwPageDesc* SwStyleBase_Impl::GetOldPageDesc() | ||||||
1569 | { | ||||||
1570 | if(!m_pOldPageDesc) | ||||||
1571 | { | ||||||
1572 | SwPageDesc *pd = m_rDoc.FindPageDesc(m_rStyleName); | ||||||
1573 | if(pd) | ||||||
1574 | m_pOldPageDesc = pd; | ||||||
1575 | |||||||
1576 | if(!m_pOldPageDesc) | ||||||
1577 | { | ||||||
1578 | for (size_t i = 0; i < SAL_N_ELEMENTS(STR_POOLPAGE_ARY)(sizeof(sal_n_array_size(STR_POOLPAGE_ARY))); ++i) | ||||||
1579 | { | ||||||
1580 | if (SwResId(STR_POOLPAGE_ARY[i]) == m_rStyleName) | ||||||
1581 | { | ||||||
1582 | m_pOldPageDesc = m_rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_BEGIN + i); | ||||||
1583 | break; | ||||||
1584 | } | ||||||
1585 | } | ||||||
1586 | } | ||||||
1587 | } | ||||||
1588 | return m_pOldPageDesc; | ||||||
1589 | } | ||||||
1590 | |||||||
1591 | |||||||
1592 | |||||||
1593 | static sal_uInt8 lcl_TranslateMetric(const SfxItemPropertySimpleEntry& rEntry, SwDoc* pDoc, uno::Any& o_aValue) | ||||||
1594 | { | ||||||
1595 | // check for needed metric translation | ||||||
1596 | if(!(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM)) | ||||||
1597 | return rEntry.nMemberId; | ||||||
1598 | // exception: If these ItemTypes are used, do not convert when these are negative | ||||||
1599 | // since this means they are intended as percent values | ||||||
1600 | if((XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID) | ||||||
1601 | && o_aValue.has<sal_Int32>() | ||||||
1602 | && o_aValue.get<sal_Int32>() < 0) | ||||||
1603 | return rEntry.nMemberId; | ||||||
1604 | if(!pDoc) | ||||||
1605 | return rEntry.nMemberId; | ||||||
1606 | |||||||
1607 | const SfxItemPool& rPool = pDoc->GetAttrPool(); | ||||||
1608 | const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID)); | ||||||
1609 | if(eMapUnit != MapUnit::Map100thMM) | ||||||
1610 | SvxUnoConvertFromMM(eMapUnit, o_aValue); | ||||||
1611 | return rEntry.nMemberId; | ||||||
1612 | } | ||||||
1613 | template<> | ||||||
1614 | void SwXStyle::SetPropertyValue<HINT_BEGIN>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1615 | { | ||||||
1616 | // default ItemSet handling | ||||||
1617 | SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); | ||||||
1618 | SfxItemSet aSet(*rStyleSet.GetPool(), {{rEntry.nWID, rEntry.nWID}}); | ||||||
1619 | aSet.SetParent(&rStyleSet); | ||||||
1620 | rPropSet.setPropertyValue(rEntry, rValue, aSet); | ||||||
1621 | rStyleSet.Put(aSet); | ||||||
1622 | } | ||||||
1623 | template<> | ||||||
1624 | void SwXStyle::SetPropertyValue<FN_UNO_HIDDEN((20000 + 2200) + 122)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1625 | { | ||||||
1626 | bool bHidden = false; | ||||||
1627 | if(rValue >>= bHidden) | ||||||
1628 | { | ||||||
1629 | //make it a 'real' style - necessary for pooled styles | ||||||
1630 | o_rStyleBase.getNewBase()->GetItemSet(); | ||||||
1631 | o_rStyleBase.getNewBase()->SetHidden(bHidden); | ||||||
1632 | } | ||||||
1633 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase); | ||||||
1634 | } | ||||||
1635 | template<> | ||||||
1636 | void SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG((20000 + 2200) + 123)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1637 | { | ||||||
1638 | o_rStyleBase.getNewBase()->GetItemSet(); | ||||||
1639 | o_rStyleBase.getNewBase()->SetGrabBagItem(rValue); | ||||||
1640 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase); | ||||||
1641 | } | ||||||
1642 | template<> | ||||||
1643 | void SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1644 | { | ||||||
1645 | uno::Any aValue(rValue); | ||||||
1646 | const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue)); | ||||||
1647 | if(MID_NAME16 == nMemberId) | ||||||
1648 | { | ||||||
1649 | // add set commands for FillName items | ||||||
1650 | SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); | ||||||
1651 | if(!aValue.has<OUString>()) | ||||||
1652 | throw lang::IllegalArgumentException(); | ||||||
1653 | SvxShape::SetFillAttribute(rEntry.nWID, aValue.get<OUString>(), rStyleSet); | ||||||
1654 | } | ||||||
1655 | else if(MID_BITMAP8 == nMemberId) | ||||||
1656 | { | ||||||
1657 | if(sal_uInt16(XATTR_FILLBITMAP) == rEntry.nWID) | ||||||
1658 | { | ||||||
1659 | const Graphic aNullGraphic; | ||||||
1660 | SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); | ||||||
1661 | XFillBitmapItem aXFillBitmapItem(aNullGraphic); | ||||||
1662 | aXFillBitmapItem.PutValue(aValue, nMemberId); | ||||||
1663 | rStyleSet.Put(aXFillBitmapItem); | ||||||
1664 | } | ||||||
1665 | } | ||||||
1666 | else | ||||||
1667 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase); | ||||||
1668 | } | ||||||
1669 | template<> | ||||||
1670 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1671 | { | ||||||
1672 | SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); | ||||||
1673 | const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rStyleSet, RES_BACKGROUND, true, m_pDoc->IsInXMLImport())); | ||||||
1674 | std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone()); | ||||||
1675 | |||||||
1676 | uno::Any aValue(rValue); | ||||||
1677 | const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue)); | ||||||
1678 | aChangedBrushItem->PutValue(aValue, nMemberId); | ||||||
1679 | |||||||
1680 | // 0xff is already the default - but if BackTransparent is set | ||||||
1681 | // to true, it must be applied in the item set on ODF import | ||||||
1682 | // to potentially override parent style, which is unknown yet | ||||||
1683 | if(*aChangedBrushItem == *aOriginalBrushItem && (MID_GRAPHIC_TRANSPARENT3 != nMemberId || !aValue.has<bool>() || !aValue.get<bool>())) | ||||||
1684 | return; | ||||||
1685 | |||||||
1686 | setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, rStyleSet); | ||||||
1687 | } | ||||||
1688 | template<> | ||||||
1689 | void SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE(3900 +45)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1690 | { | ||||||
1691 | drawing::BitmapMode eMode; | ||||||
1692 | if(!(rValue >>= eMode)) | ||||||
1693 | { | ||||||
1694 | if(!rValue.has<sal_Int32>()) | ||||||
1695 | throw lang::IllegalArgumentException(); | ||||||
1696 | eMode = static_cast<drawing::BitmapMode>(rValue.get<sal_Int32>()); | ||||||
1697 | } | ||||||
1698 | SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); | ||||||
1699 | rStyleSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode)); | ||||||
1700 | rStyleSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode)); | ||||||
1701 | } | ||||||
1702 | template<> | ||||||
1703 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1704 | { | ||||||
1705 | if(!rValue.has<OUString>()) | ||||||
1706 | throw lang::IllegalArgumentException(); | ||||||
1707 | SfxPrinter* pPrinter = m_pDoc->getIDocumentDeviceAccess().getPrinter(true); | ||||||
1708 | OUString sValue(rValue.get<OUString>()); | ||||||
1709 | using printeridx_t = decltype(pPrinter->GetPaperBinCount()); | ||||||
1710 | printeridx_t nBin = std::numeric_limits<printeridx_t>::max(); | ||||||
1711 | if(sValue == "[From printer settings]") | ||||||
1712 | nBin = std::numeric_limits<printeridx_t>::max()-1; | ||||||
1713 | else if(pPrinter) | ||||||
1714 | { | ||||||
1715 | for(sal_uInt16 i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i) | ||||||
1716 | { | ||||||
1717 | if (sValue == pPrinter->GetPaperBinName(i)) | ||||||
1718 | { | ||||||
1719 | nBin = i; | ||||||
1720 | break; | ||||||
1721 | } | ||||||
1722 | } | ||||||
1723 | } | ||||||
1724 | if(nBin == std::numeric_limits<printeridx_t>::max()) | ||||||
1725 | throw lang::IllegalArgumentException(); | ||||||
1726 | SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); | ||||||
1727 | SfxItemSet aSet(*rStyleSet.GetPool(), {{rEntry.nWID, rEntry.nWID}}); | ||||||
1728 | aSet.SetParent(&rStyleSet); | ||||||
1729 | rPropSet.setPropertyValue(rEntry, uno::makeAny(static_cast<sal_Int8>(nBin == std::numeric_limits<printeridx_t>::max()-1 ? -1 : nBin)), aSet); | ||||||
1730 | rStyleSet.Put(aSet); | ||||||
1731 | } | ||||||
1732 | template<> | ||||||
1733 | void SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES((20000 + 2200) + 15)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1734 | { | ||||||
1735 | if(!rValue.has<uno::Reference<container::XIndexReplace>>() || !rValue.has<uno::Reference<lang::XUnoTunnel>>()) | ||||||
1736 | throw lang::IllegalArgumentException(); | ||||||
1737 | auto xNumberTunnel(rValue.get<uno::Reference<lang::XUnoTunnel>>()); | ||||||
1738 | SwXNumberingRules* pSwXRules = reinterpret_cast<SwXNumberingRules*>(sal::static_int_cast<sal_IntPtr>(xNumberTunnel->getSomething(SwXNumberingRules::getUnoTunnelId()))); | ||||||
1739 | if(!pSwXRules) | ||||||
1740 | return; | ||||||
1741 | SwNumRule aSetRule(*pSwXRules->GetNumRule()); | ||||||
1742 | for(sal_uInt16 i = 0; i < MAXLEVEL; ++i) | ||||||
1743 | { | ||||||
1744 | const SwNumFormat* pFormat = aSetRule.GetNumFormat(i); | ||||||
1745 | if(!pFormat) | ||||||
1746 | continue; | ||||||
1747 | SwNumFormat aFormat(*pFormat); | ||||||
1748 | const auto& rCharName(pSwXRules->GetNewCharStyleNames()[i]); | ||||||
1749 | if(!rCharName.isEmpty() | ||||||
1750 | && !SwXNumberingRules::isInvalidStyle(rCharName) | ||||||
1751 | && (!pFormat->GetCharFormat() || pFormat->GetCharFormat()->GetName() != rCharName)) | ||||||
1752 | { | ||||||
1753 | auto pCharFormatIt(std::find_if(m_pDoc->GetCharFormats()->begin(), m_pDoc->GetCharFormats()->end(), | ||||||
1754 | [&rCharName] (SwCharFormat* pF) { return pF->GetName() == rCharName; })); | ||||||
1755 | if(pCharFormatIt != m_pDoc->GetCharFormats()->end()) | ||||||
1756 | aFormat.SetCharFormat(*pCharFormatIt); | ||||||
1757 | else if(m_pBasePool) | ||||||
1758 | { | ||||||
1759 | auto pBase(m_pBasePool->Find(rCharName, SfxStyleFamily::Char)); | ||||||
1760 | if(!pBase) | ||||||
1761 | pBase = &m_pBasePool->Make(rCharName, SfxStyleFamily::Char); | ||||||
1762 | aFormat.SetCharFormat(static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat()); | ||||||
1763 | } | ||||||
1764 | else | ||||||
1765 | aFormat.SetCharFormat(nullptr); | ||||||
1766 | } | ||||||
1767 | // same for fonts: | ||||||
1768 | const auto& rBulletName(pSwXRules->GetBulletFontNames()[i]); | ||||||
1769 | if(!rBulletName.isEmpty() | ||||||
1770 | && !SwXNumberingRules::isInvalidStyle(rBulletName) | ||||||
1771 | && (!pFormat->GetBulletFont() || pFormat->GetBulletFont()->GetFamilyName() != rBulletName)) | ||||||
1772 | { | ||||||
1773 | const auto pFontListItem(static_cast<const SvxFontListItem*>(m_pDoc->GetDocShell()->GetItem(SID_ATTR_CHAR_FONTLIST( 10000 + 22 )))); | ||||||
1774 | const auto pList(pFontListItem->GetFontList()); | ||||||
1775 | FontMetric aFontInfo(pList->Get(rBulletName, WEIGHT_NORMAL, ITALIC_NONE)); | ||||||
1776 | vcl::Font aFont(aFontInfo); | ||||||
1777 | aFormat.SetBulletFont(&aFont); | ||||||
1778 | } | ||||||
1779 | aSetRule.Set(i, &aFormat); | ||||||
1780 | } | ||||||
1781 | o_rStyleBase.getNewBase()->SetNumRule(aSetRule); | ||||||
1782 | } | ||||||
1783 | template<> | ||||||
1784 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1785 | { | ||||||
1786 | if(!rValue.has<sal_Int16>()) | ||||||
1787 | return; | ||||||
1788 | const auto nLevel(rValue.get<sal_Int16>()); | ||||||
1789 | if(0 <= nLevel && nLevel <= MAXLEVEL) | ||||||
1790 | o_rStyleBase.getNewBase()->GetCollection()->SetAttrOutlineLevel(nLevel); | ||||||
1791 | } | ||||||
1792 | template<> | ||||||
1793 | void SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1794 | { | ||||||
1795 | if(!rValue.has<OUString>()) | ||||||
1796 | return; | ||||||
1797 | const auto sValue(rValue.get<OUString>()); | ||||||
1798 | OUString aString; | ||||||
1799 | SwStyleNameMapper::FillUIName(sValue, aString, m_rEntry.m_aPoolId); | ||||||
1800 | o_rStyleBase.getNewBase()->SetFollow(aString); | ||||||
1801 | } | ||||||
1802 | template<> | ||||||
1803 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1804 | { | ||||||
1805 | if(MID_PAGEDESC_PAGEDESCNAME0 != rEntry.nMemberId) | ||||||
1806 | { | ||||||
1807 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase); | ||||||
1808 | return; | ||||||
1809 | } | ||||||
1810 | if(!rValue.has<OUString>()) | ||||||
1811 | throw lang::IllegalArgumentException(); | ||||||
1812 | // special handling for RES_PAGEDESC | ||||||
1813 | SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); | ||||||
1814 | std::unique_ptr<SwFormatPageDesc> pNewDesc; | ||||||
1815 | const SfxPoolItem* pItem; | ||||||
1816 | if(SfxItemState::SET == rStyleSet.GetItemState(RES_PAGEDESC, true, &pItem)) | ||||||
1817 | pNewDesc.reset(new SwFormatPageDesc(*static_cast<const SwFormatPageDesc*>(pItem))); | ||||||
1818 | else | ||||||
1819 | pNewDesc.reset(new SwFormatPageDesc); | ||||||
1820 | const auto sValue(rValue.get<OUString>()); | ||||||
1821 | OUString sDescName; | ||||||
1822 | SwStyleNameMapper::FillUIName(sValue, sDescName, SwGetPoolIdFromName::PageDesc); | ||||||
1823 | if(pNewDesc->GetPageDesc() && pNewDesc->GetPageDesc()->GetName() == sDescName) | ||||||
1824 | return; | ||||||
1825 | if(sDescName.isEmpty()) | ||||||
1826 | { | ||||||
1827 | rStyleSet.ClearItem(RES_BREAK); | ||||||
1828 | rStyleSet.Put(SwFormatPageDesc()); | ||||||
1829 | } | ||||||
1830 | else | ||||||
1831 | { | ||||||
1832 | SwPageDesc* pPageDesc(SwPageDesc::GetByName(*m_pDoc, sDescName)); | ||||||
1833 | if(!pPageDesc) | ||||||
1834 | throw lang::IllegalArgumentException(); | ||||||
1835 | pNewDesc->RegisterToPageDesc(*pPageDesc); | ||||||
1836 | rStyleSet.Put(*pNewDesc); | ||||||
1837 | } | ||||||
1838 | } | ||||||
1839 | template<> | ||||||
1840 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1841 | { | ||||||
1842 | if(m_rEntry.m_eFamily != SfxStyleFamily::Page) | ||||||
1843 | { | ||||||
1844 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase); | ||||||
1845 | return; | ||||||
1846 | } | ||||||
1847 | if(!m_pDoc || !rValue.has<drawing::TextVerticalAdjust>() || !o_rStyleBase.GetOldPageDesc()) | ||||||
1848 | return; | ||||||
1849 | SwPageDesc* pPageDesc = m_pDoc->FindPageDesc(o_rStyleBase.GetOldPageDesc()->GetName()); | ||||||
1850 | if(pPageDesc) | ||||||
1851 | pPageDesc->SetVerticalAdjustment(rValue.get<drawing::TextVerticalAdjust>()); | ||||||
1852 | } | ||||||
1853 | template<> | ||||||
1854 | void SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE((20000 + 2200) + 62)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1855 | { | ||||||
1856 | if(!rValue.has<bool>()) | ||||||
1857 | throw lang::IllegalArgumentException(); | ||||||
1858 | const bool bAuto(rValue.get<bool>()); | ||||||
1859 | if(SfxStyleFamily::Para == m_rEntry.m_eFamily) | ||||||
1860 | o_rStyleBase.getNewBase()->GetCollection()->SetAutoUpdateFormat(bAuto); | ||||||
1861 | else if(SfxStyleFamily::Frame == m_rEntry.m_eFamily) | ||||||
1862 | o_rStyleBase.getNewBase()->GetFrameFormat()->SetAutoUpdateFormat(bAuto); | ||||||
1863 | } | ||||||
1864 | template<> | ||||||
1865 | void SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS((20000 + 2200) + 100)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1866 | { | ||||||
1867 | static_assert(COND_COMMAND_COUNT28 == 28, "invalid size of command count?"); | ||||||
1868 | using expectedarg_t = uno::Sequence<beans::NamedValue>; | ||||||
1869 | if(!rValue.has<expectedarg_t>() || !m_pBasePool) | ||||||
1870 | throw lang::IllegalArgumentException(); | ||||||
1871 | SwCondCollItem aCondItem; | ||||||
1872 | const auto aNamedValues = rValue.get<expectedarg_t>(); | ||||||
1873 | for(const auto& rNamedValue : aNamedValues) | ||||||
1874 | { | ||||||
1875 | if(!rNamedValue.Value.has<OUString>()) | ||||||
1876 | throw lang::IllegalArgumentException(); | ||||||
1877 | |||||||
1878 | const OUString sValue(rNamedValue.Value.get<OUString>()); | ||||||
1879 | // get UI style name from programmatic style name | ||||||
1880 | OUString aStyleName; | ||||||
1881 | SwStyleNameMapper::FillUIName(sValue, aStyleName, lcl_GetSwEnumFromSfxEnum(m_rEntry.m_eFamily)); | ||||||
1882 | |||||||
1883 | // check for correct context and style name | ||||||
1884 | const auto nIdx(GetCommandContextIndex(rNamedValue.Name)); | ||||||
1885 | if (nIdx == -1) | ||||||
1886 | throw lang::IllegalArgumentException(); | ||||||
1887 | bool bStyleFound = false; | ||||||
1888 | for(auto pBase = m_pBasePool->First(SfxStyleFamily::Para); pBase; pBase = m_pBasePool->Next()) | ||||||
1889 | { | ||||||
1890 | bStyleFound = pBase->GetName() == aStyleName; | ||||||
1891 | if (bStyleFound) | ||||||
1892 | break; | ||||||
1893 | } | ||||||
1894 | if (!bStyleFound) | ||||||
1895 | throw lang::IllegalArgumentException(); | ||||||
1896 | aCondItem.SetStyle(&aStyleName, nIdx); | ||||||
1897 | } | ||||||
1898 | o_rStyleBase.GetItemSet().Put(aCondItem); | ||||||
1899 | } | ||||||
1900 | template<> | ||||||
1901 | void SwXStyle::SetPropertyValue<FN_UNO_CATEGORY((20000 + 2200) + 68)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1902 | { | ||||||
1903 | if(!o_rStyleBase.getNewBase()->IsUserDefined() || !rValue.has<paragraphstyle_t>()) | ||||||
1904 | throw lang::IllegalArgumentException(); | ||||||
1905 | static std::unique_ptr<std::map<paragraphstyle_t, SfxStyleSearchBits>> pUnoToCore; | ||||||
1906 | if(!pUnoToCore) | ||||||
1907 | { | ||||||
1908 | pUnoToCore.reset(new std::map<paragraphstyle_t, SfxStyleSearchBits>); | ||||||
1909 | auto pEntries = lcl_GetParagraphStyleCategoryEntries(); | ||||||
1910 | std::transform(pEntries->begin(), pEntries->end(), std::inserter(*pUnoToCore, pUnoToCore->end()), | ||||||
1911 | [] (const ParagraphStyleCategoryEntry& rEntry) { return std::pair<paragraphstyle_t, SfxStyleSearchBits>(rEntry.m_eCategory, rEntry.m_nSwStyleBits); }); | ||||||
1912 | } | ||||||
1913 | const auto pUnoToCoreIt(pUnoToCore->find(rValue.get<paragraphstyle_t>())); | ||||||
1914 | if(pUnoToCoreIt == pUnoToCore->end()) | ||||||
1915 | throw lang::IllegalArgumentException(); | ||||||
1916 | o_rStyleBase.getNewBase()->SetMask( pUnoToCoreIt->second|SfxStyleSearchBits::UserDefined ); | ||||||
1917 | } | ||||||
1918 | template<> | ||||||
1919 | void SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION( 10000 + 451 )>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1920 | { | ||||||
1921 | OUString sName; | ||||||
1922 | rValue >>= sName; | ||||||
1923 | SwRegisterItem aReg(!sName.isEmpty()); | ||||||
1924 | aReg.SetWhich(SID_SWREGISTER_MODE( 10000 + 467 )); | ||||||
1925 | o_rStyleBase.GetItemSet().Put(aReg); | ||||||
1926 | OUString aString; | ||||||
1927 | SwStyleNameMapper::FillUIName(sName, aString, SwGetPoolIdFromName::TxtColl); | ||||||
1928 | o_rStyleBase.GetItemSet().Put(SfxStringItem(SID_SWREGISTER_COLLECTION( 10000 + 451 ), aString ) ); | ||||||
1929 | } | ||||||
1930 | template<> | ||||||
1931 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1932 | { | ||||||
1933 | if(MID_RUBY_CHARSTYLE2 != rEntry.nMemberId) | ||||||
1934 | return; | ||||||
1935 | if(!rValue.has<OUString>()) | ||||||
1936 | throw lang::IllegalArgumentException(); | ||||||
1937 | const auto sValue(rValue.get<OUString>()); | ||||||
1938 | SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet()); | ||||||
1939 | std::unique_ptr<SwFormatRuby> pRuby; | ||||||
1940 | const SfxPoolItem* pItem; | ||||||
1941 | if(SfxItemState::SET == rStyleSet.GetItemState(RES_TXTATR_CJK_RUBY, true, &pItem)) | ||||||
1942 | pRuby.reset(new SwFormatRuby(*static_cast<const SwFormatRuby*>(pItem))); | ||||||
1943 | else | ||||||
1944 | pRuby.reset(new SwFormatRuby(OUString())); | ||||||
1945 | OUString sStyle; | ||||||
1946 | SwStyleNameMapper::FillUIName(sValue, sStyle, SwGetPoolIdFromName::ChrFmt); | ||||||
1947 | pRuby->SetCharFormatName(sValue); | ||||||
1948 | pRuby->SetCharFormatId(0); | ||||||
1949 | if(!sValue.isEmpty()) | ||||||
1950 | { | ||||||
1951 | const sal_uInt16 nId(SwStyleNameMapper::GetPoolIdFromUIName(sValue, SwGetPoolIdFromName::ChrFmt)); | ||||||
1952 | pRuby->SetCharFormatId(nId); | ||||||
1953 | } | ||||||
1954 | rStyleSet.Put(*pRuby); | ||||||
1955 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase); | ||||||
1956 | } | ||||||
1957 | template<> | ||||||
1958 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1959 | { | ||||||
1960 | if(MID_DROPCAP_CHAR_STYLE_NAME2 != rEntry.nMemberId) | ||||||
1961 | { | ||||||
1962 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase); | ||||||
1963 | return; | ||||||
1964 | } | ||||||
1965 | if(!rValue.has<OUString>()) | ||||||
1966 | throw lang::IllegalArgumentException(); | ||||||
1967 | SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet()); | ||||||
1968 | std::unique_ptr<SwFormatDrop> pDrop; | ||||||
1969 | const SfxPoolItem* pItem; | ||||||
1970 | if(SfxItemState::SET == rStyleSet.GetItemState(RES_PARATR_DROP, true, &pItem)) | ||||||
1971 | pDrop.reset(new SwFormatDrop(*static_cast<const SwFormatDrop*>(pItem))); | ||||||
1972 | else | ||||||
1973 | pDrop.reset(new SwFormatDrop); | ||||||
1974 | const auto sValue(rValue.get<OUString>()); | ||||||
1975 | OUString sStyle; | ||||||
1976 | SwStyleNameMapper::FillUIName(sValue, sStyle, SwGetPoolIdFromName::ChrFmt); | ||||||
1977 | auto pStyle(static_cast<SwDocStyleSheet*>(m_pDoc->GetDocShell()->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Char))); | ||||||
1978 | //default character style must not be set as default format | ||||||
1979 | if(!pStyle || pStyle->GetCharFormat() == m_pDoc->GetDfltCharFormat() ) | ||||||
1980 | { | ||||||
1981 | throw lang::IllegalArgumentException(); | ||||||
1982 | } | ||||||
1983 | pDrop->SetCharFormat(pStyle->GetCharFormat()); | ||||||
1984 | rStyleSet.Put(*pDrop); | ||||||
1985 | } | ||||||
1986 | template<> | ||||||
1987 | void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) | ||||||
1988 | { | ||||||
1989 | uno::Any aValue(rValue); | ||||||
1990 | lcl_TranslateMetric(rEntry, m_pDoc, aValue); | ||||||
1991 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase); | ||||||
1992 | // --> OD 2006-10-18 #i70223# | ||||||
1993 | if(SfxStyleFamily::Para == m_rEntry.m_eFamily && | ||||||
1994 | o_rStyleBase.getNewBase().is() && o_rStyleBase.getNewBase()->GetCollection() && | ||||||
1995 | //rBase.getNewBase()->GetCollection()->GetOutlineLevel() < MAXLEVEL /* assigned to list level of outline style */) //#outline level,removed by zhaojianwei | ||||||
1996 | o_rStyleBase.getNewBase()->GetCollection()->IsAssignedToListLevelOfOutlineStyle()) ////<-end,add by zhaojianwei | ||||||
1997 | { | ||||||
1998 | OUString sNewNumberingRuleName; | ||||||
1999 | aValue >>= sNewNumberingRuleName; | ||||||
2000 | if(sNewNumberingRuleName.isEmpty() || sNewNumberingRuleName != m_pDoc->GetOutlineNumRule()->GetName()) | ||||||
2001 | o_rStyleBase.getNewBase()->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle(); | ||||||
2002 | } | ||||||
2003 | } | ||||||
2004 | |||||||
2005 | void SwXStyle::SetStyleProperty(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase) | ||||||
2006 | { | ||||||
2007 | using propertytype_t = decltype(rEntry.nWID); | ||||||
2008 | using coresetter_t = std::function<void(SwXStyle&, const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&)>; | ||||||
2009 | static std::unique_ptr<std::map<propertytype_t, coresetter_t>> pUnoToCore; | ||||||
2010 | if(!pUnoToCore) | ||||||
2011 | { | ||||||
2012 | pUnoToCore.reset(new std::map<propertytype_t, coresetter_t> { | ||||||
2013 | // these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again | ||||||
2014 | { FN_UNO_HIDDEN((20000 + 2200) + 122), std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_HIDDEN((20000 + 2200) + 122)>) }, | ||||||
2015 | { FN_UNO_STYLE_INTEROP_GRAB_BAG((20000 + 2200) + 123), std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG((20000 + 2200) + 123)>) }, | ||||||
2016 | { XATTR_FILLGRADIENT, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) }, | ||||||
2017 | { XATTR_FILLHATCH, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) }, | ||||||
2018 | { XATTR_FILLBITMAP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) }, | ||||||
2019 | { XATTR_FILLFLOATTRANSPARENCE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) }, | ||||||
2020 | { RES_BACKGROUND, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>) }, | ||||||
2021 | { OWN_ATTR_FILLBMP_MODE(3900 +45), std::mem_fn(&SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE(3900 +45)>) }, | ||||||
2022 | { RES_PAPER_BIN, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>) }, | ||||||
2023 | { FN_UNO_NUM_RULES((20000 + 2200) + 15), std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES((20000 + 2200) + 15)>) }, | ||||||
2024 | { RES_PARATR_OUTLINELEVEL, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_OUTLINELEVEL)>) }, | ||||||
2025 | { FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59), std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59)>) }, | ||||||
2026 | { RES_PAGEDESC, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>) }, | ||||||
2027 | { RES_TEXT_VERT_ADJUST, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>) }, | ||||||
2028 | { FN_UNO_IS_AUTO_UPDATE((20000 + 2200) + 62), std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE((20000 + 2200) + 62)>) }, | ||||||
2029 | { FN_UNO_PARA_STYLE_CONDITIONS((20000 + 2200) + 100), std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS((20000 + 2200) + 100)>) }, | ||||||
2030 | { FN_UNO_CATEGORY((20000 + 2200) + 68), std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_CATEGORY((20000 + 2200) + 68)>) }, | ||||||
2031 | { SID_SWREGISTER_COLLECTION( 10000 + 451 ), std::mem_fn(&SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION( 10000 + 451 )>) }, | ||||||
2032 | { RES_TXTATR_CJK_RUBY, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>) }, | ||||||
2033 | { RES_PARATR_DROP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>) }, | ||||||
2034 | { RES_PARATR_NUMRULE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>) } | ||||||
2035 | }); | ||||||
2036 | } | ||||||
2037 | const auto pUnoToCoreIt(pUnoToCore->find(rEntry.nWID)); | ||||||
2038 | if(pUnoToCoreIt != pUnoToCore->end()) | ||||||
2039 | pUnoToCoreIt->second(*this, rEntry, rPropSet, rValue, rBase); | ||||||
2040 | else | ||||||
2041 | { | ||||||
2042 | // adapted switch logic to a more readable state; removed goto's and made | ||||||
2043 | // execution of standard setting of property in ItemSet dependent of this variable | ||||||
2044 | uno::Any aValue(rValue); | ||||||
2045 | lcl_TranslateMetric(rEntry, m_pDoc, aValue); | ||||||
2046 | SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, rBase); | ||||||
2047 | } | ||||||
2048 | } | ||||||
2049 | |||||||
2050 | void SwXStyle::SetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues) | ||||||
2051 | { | ||||||
2052 | if(!m_pDoc) | ||||||
2053 | throw uno::RuntimeException(); | ||||||
2054 | sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE93 : m_rEntry.m_nPropMapType; | ||||||
2055 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
2056 | const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap(); | ||||||
2057 | if(rPropertyNames.getLength() != rValues.getLength()) | ||||||
2058 | throw lang::IllegalArgumentException(); | ||||||
2059 | |||||||
2060 | SwStyleBase_Impl aBaseImpl(*m_pDoc, m_sStyleName, &GetDoc()->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent | ||||||
2061 | if(m_pBasePool) | ||||||
2062 | { | ||||||
2063 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
2064 | SAL_WARN_IF(!pBase, "sw.uno", "where is the style?")do { if (true && (!pBase)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "where is the style?" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2064" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2064" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "where is the style?") == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2064" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2064" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2065 | if(!pBase) | ||||||
2066 | throw uno::RuntimeException(); | ||||||
2067 | aBaseImpl.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
2068 | } | ||||||
2069 | if(!aBaseImpl.getNewBase().is() && !m_bIsDescriptor) | ||||||
2070 | throw uno::RuntimeException(); | ||||||
2071 | |||||||
2072 | const OUString* pNames = rPropertyNames.getConstArray(); | ||||||
2073 | const uno::Any* pValues = rValues.getConstArray(); | ||||||
2074 | for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp) | ||||||
2075 | { | ||||||
2076 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(pNames[nProp]); | ||||||
2077 | if(!pEntry || (!m_bIsConditional && pNames[nProp] == UNO_NAME_PARA_STYLE_CONDITIONS"ParaStyleConditions")) | ||||||
2078 | throw beans::UnknownPropertyException("Unknown property: " + pNames[nProp], static_cast<cppu::OWeakObject*>(this)); | ||||||
2079 | if(pEntry->nFlags & beans::PropertyAttribute::READONLY) | ||||||
2080 | throw beans::PropertyVetoException ("Property is read-only: " + pNames[nProp], static_cast<cppu::OWeakObject*>(this)); | ||||||
2081 | if(aBaseImpl.getNewBase().is()) | ||||||
2082 | SetStyleProperty(*pEntry, *pPropSet, pValues[nProp], aBaseImpl); | ||||||
2083 | else if(!m_pPropertiesImpl->SetProperty(pNames[nProp], pValues[nProp])) | ||||||
2084 | throw lang::IllegalArgumentException(); | ||||||
2085 | } | ||||||
2086 | |||||||
2087 | if(aBaseImpl.HasItemSet()) | ||||||
2088 | aBaseImpl.getNewBase()->SetItemSet(aBaseImpl.GetItemSet()); | ||||||
2089 | } | ||||||
2090 | |||||||
2091 | void SwXStyle::setPropertyValues(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues) | ||||||
2092 | { | ||||||
2093 | SolarMutexGuard aGuard; | ||||||
2094 | // workaround for bad designed API | ||||||
2095 | try | ||||||
2096 | { | ||||||
2097 | SetPropertyValues_Impl( rPropertyNames, rValues ); | ||||||
2098 | } | ||||||
2099 | catch (const beans::UnknownPropertyException &rException) | ||||||
2100 | { | ||||||
2101 | // wrap the original (here not allowed) exception in | ||||||
2102 | // a lang::WrappedTargetException that gets thrown instead. | ||||||
2103 | lang::WrappedTargetException aWExc; | ||||||
2104 | aWExc.TargetException <<= rException; | ||||||
2105 | throw aWExc; | ||||||
2106 | } | ||||||
2107 | } | ||||||
2108 | |||||||
2109 | SfxStyleSheetBase* SwXStyle::GetStyleSheetBase() | ||||||
2110 | { | ||||||
2111 | if(!m_pBasePool) | ||||||
2112 | return nullptr; | ||||||
2113 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
2114 | return pBase; | ||||||
2115 | } | ||||||
2116 | void SwXStyle::PrepareStyleBase(SwStyleBase_Impl& rBase) | ||||||
2117 | { | ||||||
2118 | SfxStyleSheetBase* pBase(GetStyleSheetBase()); | ||||||
2119 | if(!pBase) | ||||||
2120 | throw uno::RuntimeException(); | ||||||
2121 | if(!rBase.getNewBase().is()) | ||||||
2122 | rBase.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
2123 | } | ||||||
2124 | |||||||
2125 | template<> | ||||||
2126 | uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase); | ||||||
2127 | template<> | ||||||
2128 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL((20000 + 2200) + 61)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&) | ||||||
2129 | { | ||||||
2130 | SfxStyleSheetBase* pBase(GetStyleSheetBase()); | ||||||
2131 | if(!pBase) | ||||||
2132 | return uno::makeAny(false); | ||||||
2133 | bool bPhys = static_cast<SwDocStyleSheet*>(pBase)->IsPhysical(); | ||||||
2134 | // The standard character format is not existing physically | ||||||
2135 | if( bPhys && SfxStyleFamily::Char == GetFamily() && | ||||||
2136 | static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat() && | ||||||
2137 | static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat()->IsDefault() ) | ||||||
2138 | bPhys = false; | ||||||
2139 | return uno::makeAny<bool>(bPhys); | ||||||
2140 | } | ||||||
2141 | template<> | ||||||
2142 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_HIDDEN((20000 + 2200) + 122)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&) | ||||||
2143 | { | ||||||
2144 | SfxStyleSheetBase* pBase(GetStyleSheetBase()); | ||||||
2145 | if(!pBase) | ||||||
2146 | return uno::makeAny(false); | ||||||
2147 | rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
2148 | return uno::makeAny(xBase->IsHidden()); | ||||||
2149 | } | ||||||
2150 | template<> | ||||||
2151 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG((20000 + 2200) + 123)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&) | ||||||
2152 | { | ||||||
2153 | SfxStyleSheetBase* pBase(GetStyleSheetBase()); | ||||||
2154 | if(!pBase) | ||||||
2155 | return uno::Any(); | ||||||
2156 | uno::Any aRet; | ||||||
2157 | rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
2158 | xBase->GetGrabBagItem(aRet); | ||||||
2159 | return aRet; | ||||||
2160 | } | ||||||
2161 | template<> | ||||||
2162 | uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase) | ||||||
2163 | { | ||||||
2164 | PrepareStyleBase(rBase); | ||||||
2165 | SfxItemSet& rSet = rBase.GetItemSet(); | ||||||
2166 | uno::Any aValue; | ||||||
2167 | rPropSet.getPropertyValue(rEntry, rSet, aValue); | ||||||
2168 | sal_Int8 nBin(aValue.get<sal_Int8>()); | ||||||
2169 | if(nBin == -1) | ||||||
2170 | return uno::makeAny<OUString>("[From printer settings]"); | ||||||
2171 | SfxPrinter* pPrinter = GetDoc()->getIDocumentDeviceAccess().getPrinter(false); | ||||||
2172 | if(!pPrinter) | ||||||
2173 | return uno::Any(); | ||||||
2174 | return uno::makeAny(pPrinter->GetPaperBinName(nBin)); | ||||||
2175 | } | ||||||
2176 | template<> | ||||||
2177 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES((20000 + 2200) + 15)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2178 | { | ||||||
2179 | PrepareStyleBase(rBase); | ||||||
2180 | const SwNumRule* pRule = rBase.getNewBase()->GetNumRule(); | ||||||
2181 | assert(pRule && "Where is the NumRule?")(static_cast <bool> (pRule && "Where is the NumRule?" ) ? void (0) : __assert_fail ("pRule && \"Where is the NumRule?\"" , "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 2181, __extension__ __PRETTY_FUNCTION__)); | ||||||
2182 | uno::Reference<container::XIndexReplace> xRules(new SwXNumberingRules(*pRule, GetDoc())); | ||||||
2183 | return uno::makeAny<uno::Reference<container::XIndexReplace>>(xRules); | ||||||
2184 | } | ||||||
2185 | template<> | ||||||
2186 | uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2187 | { | ||||||
2188 | PrepareStyleBase(rBase); | ||||||
2189 | SAL_WARN_IF(SfxStyleFamily::Para != GetFamily(), "sw.uno", "only paras")do { if (true && (SfxStyleFamily::Para != GetFamily() )) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "only paras") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2189" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "only paras"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "only paras"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ( "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2189" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "only paras") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2189" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "only paras"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "only paras"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ( "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2189" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2190 | return uno::makeAny<sal_Int16>(rBase.getNewBase()->GetCollection()->GetAttrOutlineLevel()); | ||||||
2191 | } | ||||||
2192 | template<> | ||||||
2193 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2194 | { | ||||||
2195 | PrepareStyleBase(rBase); | ||||||
2196 | OUString aString; | ||||||
2197 | SwStyleNameMapper::FillProgName(rBase.getNewBase()->GetFollow(), aString, lcl_GetSwEnumFromSfxEnum(GetFamily())); | ||||||
2198 | return uno::makeAny(aString); | ||||||
2199 | } | ||||||
2200 | template<> | ||||||
2201 | uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase) | ||||||
2202 | { | ||||||
2203 | PrepareStyleBase(rBase); | ||||||
2204 | if(MID_PAGEDESC_PAGEDESCNAME0 != rEntry.nMemberId) | ||||||
2205 | return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase); | ||||||
2206 | // special handling for RES_PAGEDESC | ||||||
2207 | const SfxPoolItem* pItem; | ||||||
2208 | if(SfxItemState::SET != rBase.GetItemSet().GetItemState(RES_PAGEDESC, true, &pItem)) | ||||||
2209 | return uno::Any(); | ||||||
2210 | const SwPageDesc* pDesc = static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc(); | ||||||
2211 | if(!pDesc) | ||||||
2212 | return uno::Any(); | ||||||
2213 | OUString aString; | ||||||
2214 | SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc); | ||||||
2215 | return uno::makeAny(aString); | ||||||
2216 | } | ||||||
2217 | template<> | ||||||
2218 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE((20000 + 2200) + 62)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2219 | { | ||||||
2220 | PrepareStyleBase(rBase); | ||||||
2221 | switch(GetFamily()) | ||||||
2222 | { | ||||||
2223 | case SfxStyleFamily::Para : return uno::makeAny<bool>(rBase.getNewBase()->GetCollection()->IsAutoUpdateFormat()); | ||||||
2224 | case SfxStyleFamily::Frame: return uno::makeAny<bool>(rBase.getNewBase()->GetFrameFormat()->IsAutoUpdateFormat()); | ||||||
2225 | default: return uno::Any(); | ||||||
2226 | } | ||||||
2227 | } | ||||||
2228 | template<> | ||||||
2229 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME((20000 + 2200) + 63)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2230 | { | ||||||
2231 | PrepareStyleBase(rBase); | ||||||
2232 | return uno::makeAny(rBase.getNewBase()->GetName()); | ||||||
2233 | } | ||||||
2234 | template<> | ||||||
2235 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS((20000 + 2200) + 100)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2236 | { | ||||||
2237 | PrepareStyleBase(rBase); | ||||||
2238 | static_assert(COND_COMMAND_COUNT28 == 28, "invalid size of command count?"); | ||||||
2239 | uno::Sequence<beans::NamedValue> aSeq(COND_COMMAND_COUNT28); | ||||||
2240 | sal_uInt16 nIndex = 0; | ||||||
2241 | for(auto& rNV : aSeq) | ||||||
2242 | { | ||||||
2243 | rNV.Name = GetCommandContextByIndex(nIndex++); | ||||||
2244 | rNV.Value <<= OUString(); | ||||||
2245 | } | ||||||
2246 | SwFormat* pFormat = static_cast<SwDocStyleSheet*>(GetStyleSheetBase())->GetCollection(); | ||||||
2247 | if(pFormat && RES_CONDTXTFMTCOLL == pFormat->Which()) | ||||||
2248 | { | ||||||
2249 | const CommandStruct* pCmds = SwCondCollItem::GetCmds(); | ||||||
2250 | beans::NamedValue* pSeq = aSeq.getArray(); | ||||||
2251 | for(sal_uInt16 n = 0; n < COND_COMMAND_COUNT28; ++n) | ||||||
2252 | { | ||||||
2253 | const SwCollCondition* pCond = static_cast<SwConditionTextFormatColl*>(pFormat)->HasCondition(SwCollCondition(nullptr, pCmds[n].nCnd, pCmds[n].nSubCond)); | ||||||
2254 | if(!pCond || !pCond->GetTextFormatColl()) | ||||||
2255 | continue; | ||||||
2256 | // get programmatic style name from UI style name | ||||||
2257 | OUString aStyleName = pCond->GetTextFormatColl()->GetName(); | ||||||
2258 | SwStyleNameMapper::FillProgName(aStyleName, aStyleName, lcl_GetSwEnumFromSfxEnum(GetFamily())); | ||||||
2259 | pSeq[n].Value <<= aStyleName; | ||||||
2260 | } | ||||||
2261 | } | ||||||
2262 | return uno::makeAny(aSeq); | ||||||
2263 | } | ||||||
2264 | template<> | ||||||
2265 | uno::Any SwXStyle::GetStyleProperty<FN_UNO_CATEGORY((20000 + 2200) + 68)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2266 | { | ||||||
2267 | PrepareStyleBase(rBase); | ||||||
2268 | static std::unique_ptr<std::map<collectionbits_t, paragraphstyle_t>> pUnoToCore; | ||||||
2269 | if(!pUnoToCore) | ||||||
2270 | { | ||||||
2271 | pUnoToCore.reset(new std::map<collectionbits_t, paragraphstyle_t>); | ||||||
2272 | auto pEntries = lcl_GetParagraphStyleCategoryEntries(); | ||||||
2273 | std::transform(pEntries->begin(), pEntries->end(), std::inserter(*pUnoToCore, pUnoToCore->end()), | ||||||
2274 | [] (const ParagraphStyleCategoryEntry& rEntry) { return std::pair<collectionbits_t, paragraphstyle_t>(rEntry.m_nCollectionBits, rEntry.m_eCategory); }); | ||||||
2275 | } | ||||||
2276 | const sal_uInt16 nPoolId = rBase.getNewBase()->GetCollection()->GetPoolFormatId(); | ||||||
2277 | const auto pUnoToCoreIt(pUnoToCore->find(COLL_GET_RANGE_BITS & nPoolId)); | ||||||
2278 | if(pUnoToCoreIt == pUnoToCore->end()) | ||||||
2279 | return uno::makeAny<sal_Int16>(-1); | ||||||
2280 | return uno::makeAny(pUnoToCoreIt->second); | ||||||
2281 | } | ||||||
2282 | template<> | ||||||
2283 | uno::Any SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION( 10000 + 451 )>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2284 | { | ||||||
2285 | PrepareStyleBase(rBase); | ||||||
2286 | const SwPageDesc *pPageDesc = rBase.getNewBase()->GetPageDesc(); | ||||||
2287 | if(!pPageDesc) | ||||||
2288 | return uno::makeAny(OUString()); | ||||||
2289 | const SwTextFormatColl* pCol = pPageDesc->GetRegisterFormatColl(); | ||||||
2290 | if(!pCol) | ||||||
2291 | return uno::makeAny(OUString()); | ||||||
2292 | OUString aName; | ||||||
2293 | SwStyleNameMapper::FillProgName(pCol->GetName(), aName, SwGetPoolIdFromName::TxtColl); | ||||||
2294 | return uno::makeAny(aName); | ||||||
2295 | } | ||||||
2296 | template<> | ||||||
2297 | uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2298 | { | ||||||
2299 | PrepareStyleBase(rBase); | ||||||
2300 | const SfxItemSet& rSet = rBase.GetItemSet(); | ||||||
2301 | const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND)); | ||||||
2302 | uno::Any aResult; | ||||||
2303 | if(!aOriginalBrushItem->QueryValue(aResult, rEntry.nMemberId)) | ||||||
2304 | SAL_WARN("sw.uno", "error getting attribute from RES_BACKGROUND.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "error getting attribute from RES_BACKGROUND." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2304" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "error getting attribute from RES_BACKGROUND." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "error getting attribute from RES_BACKGROUND."; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2304" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "error getting attribute from RES_BACKGROUND.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2304" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "error getting attribute from RES_BACKGROUND." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "error getting attribute from RES_BACKGROUND."; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2304" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2305 | return aResult; | ||||||
2306 | } | ||||||
2307 | template<> | ||||||
2308 | uno::Any SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE(3900 +45)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase) | ||||||
2309 | { | ||||||
2310 | PrepareStyleBase(rBase); | ||||||
2311 | const SfxItemSet& rSet = rBase.GetItemSet(); | ||||||
2312 | if (rSet.Get(XATTR_FILLBMP_TILE).GetValue()) | ||||||
2313 | return uno::makeAny(drawing::BitmapMode_REPEAT); | ||||||
2314 | if (rSet.Get(XATTR_FILLBMP_STRETCH).GetValue()) | ||||||
2315 | return uno::makeAny(drawing::BitmapMode_STRETCH); | ||||||
2316 | return uno::makeAny(drawing::BitmapMode_NO_REPEAT); | ||||||
2317 | } | ||||||
2318 | template<> | ||||||
2319 | uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase) | ||||||
2320 | { | ||||||
2321 | PrepareStyleBase(rBase); | ||||||
2322 | SfxItemSet& rSet = rBase.GetItemSet(); | ||||||
2323 | uno::Any aResult; | ||||||
2324 | rPropSet.getPropertyValue(rEntry, rSet, aResult); | ||||||
2325 | // | ||||||
2326 | // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here | ||||||
2327 | if(rEntry.aType == cppu::UnoType<sal_Int16>::get() && aResult.getValueType() == cppu::UnoType<sal_Int32>::get()) | ||||||
2328 | aResult <<= static_cast<sal_Int16>(aResult.get<sal_Int32>()); | ||||||
2329 | // check for needed metric translation | ||||||
2330 | if(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM && GetDoc()) | ||||||
2331 | { | ||||||
2332 | const SfxItemPool& rPool = GetDoc()->GetAttrPool(); | ||||||
2333 | const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID)); | ||||||
2334 | bool bAllowedConvert(true); | ||||||
2335 | // exception: If these ItemTypes are used, do not convert when these are negative | ||||||
2336 | // since this means they are intended as percent values | ||||||
2337 | if(XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID) | ||||||
2338 | bAllowedConvert = !aResult.has<sal_Int32>() || aResult.get<sal_Int32>() > 0; | ||||||
2339 | if(eMapUnit != MapUnit::Map100thMM && bAllowedConvert) | ||||||
2340 | SvxUnoConvertToMM(eMapUnit, aResult); | ||||||
2341 | } | ||||||
2342 | return aResult; | ||||||
2343 | } | ||||||
2344 | |||||||
2345 | uno::Any SwXStyle::GetStyleProperty_Impl(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase) | ||||||
2346 | { | ||||||
2347 | using propertytype_t = decltype(rEntry.nWID); | ||||||
2348 | using coresetter_t = std::function<uno::Any(SwXStyle&, const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)>; | ||||||
2349 | static std::unique_ptr<std::map<propertytype_t, coresetter_t>> pUnoToCore; | ||||||
2350 | if(!pUnoToCore) | ||||||
2351 | { | ||||||
2352 | pUnoToCore.reset(new std::map<propertytype_t, coresetter_t> { | ||||||
2353 | // these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again | ||||||
2354 | { FN_UNO_IS_PHYSICAL((20000 + 2200) + 61), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL((20000 + 2200) + 61)>) }, | ||||||
2355 | { FN_UNO_HIDDEN((20000 + 2200) + 122), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_HIDDEN((20000 + 2200) + 122)>) }, | ||||||
2356 | { FN_UNO_STYLE_INTEROP_GRAB_BAG((20000 + 2200) + 123), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG((20000 + 2200) + 123)>) }, | ||||||
2357 | { RES_PAPER_BIN, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>) }, | ||||||
2358 | { FN_UNO_NUM_RULES((20000 + 2200) + 15), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES((20000 + 2200) + 15)>) }, | ||||||
2359 | { RES_PARATR_OUTLINELEVEL, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>) }, | ||||||
2360 | { FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59)>) }, | ||||||
2361 | { RES_PAGEDESC, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>) }, | ||||||
2362 | { FN_UNO_IS_AUTO_UPDATE((20000 + 2200) + 62), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE((20000 + 2200) + 62)>) }, | ||||||
2363 | { FN_UNO_DISPLAY_NAME((20000 + 2200) + 63), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME((20000 + 2200) + 63)>) }, | ||||||
2364 | { FN_UNO_PARA_STYLE_CONDITIONS((20000 + 2200) + 100), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS((20000 + 2200) + 100)>) }, | ||||||
2365 | { FN_UNO_CATEGORY((20000 + 2200) + 68), std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_CATEGORY((20000 + 2200) + 68)>) }, | ||||||
2366 | { SID_SWREGISTER_COLLECTION( 10000 + 451 ), std::mem_fn(&SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION( 10000 + 451 )>) }, | ||||||
2367 | { RES_BACKGROUND, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>) }, | ||||||
2368 | { OWN_ATTR_FILLBMP_MODE(3900 +45), std::mem_fn(&SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE(3900 +45)>) } | ||||||
2369 | }); | ||||||
2370 | } | ||||||
2371 | const auto pUnoToCoreIt(pUnoToCore->find(rEntry.nWID)); | ||||||
2372 | if(pUnoToCoreIt != pUnoToCore->end()) | ||||||
2373 | return pUnoToCoreIt->second(*this, rEntry, rPropSet, rBase); | ||||||
2374 | return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase); | ||||||
2375 | } | ||||||
2376 | |||||||
2377 | uno::Any SwXStyle::GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName) | ||||||
2378 | { | ||||||
2379 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
2380 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropertyName); | ||||||
2381 | if(!pEntry || (!m_bIsConditional
| ||||||
2382 | throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject*>(this)); | ||||||
2383 | if(m_pBasePool
| ||||||
2384 | return GetStyleProperty_Impl(*pEntry, *pPropSet, rBase); | ||||||
2385 | const uno::Any* pAny = nullptr; | ||||||
2386 | m_pPropertiesImpl->GetProperty(rPropertyName, pAny); | ||||||
2387 | if(pAny->hasValue()) | ||||||
| |||||||
2388 | return *pAny; | ||||||
2389 | uno::Any aValue; | ||||||
2390 | switch(m_rEntry.m_eFamily) | ||||||
2391 | { | ||||||
2392 | case SfxStyleFamily::Pseudo: | ||||||
2393 | throw uno::RuntimeException("No default value for: " + rPropertyName); | ||||||
2394 | break; | ||||||
2395 | case SfxStyleFamily::Para: | ||||||
2396 | case SfxStyleFamily::Page: | ||||||
2397 | SwStyleProperties_Impl::GetProperty(rPropertyName, m_xStyleData, aValue); | ||||||
2398 | break; | ||||||
2399 | case SfxStyleFamily::Char: | ||||||
2400 | case SfxStyleFamily::Frame: | ||||||
2401 | { | ||||||
2402 | if(pEntry->nWID < POOLATTR_BEGIN || pEntry->nWID >= RES_UNKNOWNATR_END) | ||||||
2403 | throw uno::RuntimeException("No default value for: " + rPropertyName); | ||||||
2404 | SwFormat* pFormat; | ||||||
2405 | if(m_rEntry.m_eFamily == SfxStyleFamily::Char) | ||||||
2406 | pFormat = m_pDoc->GetDfltCharFormat(); | ||||||
2407 | else | ||||||
2408 | pFormat = m_pDoc->GetDfltFrameFormat(); | ||||||
2409 | const SwAttrPool* pPool = pFormat->GetAttrSet().GetPool(); | ||||||
2410 | const SfxPoolItem& rItem = pPool->GetDefaultItem(pEntry->nWID); | ||||||
2411 | rItem.QueryValue(aValue, pEntry->nMemberId); | ||||||
2412 | } | ||||||
2413 | break; | ||||||
2414 | default: | ||||||
2415 | ; | ||||||
2416 | } | ||||||
2417 | return aValue; | ||||||
2418 | } | ||||||
2419 | |||||||
2420 | uno::Any SwXStyle::getPropertyValue(const OUString& rPropertyName) | ||||||
2421 | { | ||||||
2422 | SolarMutexGuard aGuard; | ||||||
2423 | if(!m_pDoc) | ||||||
| |||||||
2424 | throw uno::RuntimeException(); | ||||||
2425 | if(!m_pBasePool && !m_bIsDescriptor) | ||||||
2426 | throw uno::RuntimeException(); | ||||||
2427 | sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE93 : m_rEntry.m_nPropMapType; | ||||||
2428 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
2429 | SwStyleBase_Impl aBase(*m_pDoc, m_sStyleName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent | ||||||
2430 | return GetPropertyValue_Impl(pPropSet, aBase, rPropertyName); | ||||||
2431 | } | ||||||
2432 | |||||||
2433 | uno::Sequence<uno::Any> SwXStyle::getPropertyValues(const uno::Sequence<OUString>& rPropertyNames) | ||||||
2434 | { | ||||||
2435 | SolarMutexGuard aGuard; | ||||||
2436 | if(!m_pDoc) | ||||||
2437 | throw uno::RuntimeException(); | ||||||
2438 | if(!m_pBasePool && !m_bIsDescriptor) | ||||||
2439 | throw uno::RuntimeException(); | ||||||
2440 | sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE93 : m_rEntry.m_nPropMapType; | ||||||
2441 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
2442 | SwStyleBase_Impl aBase(*m_pDoc, m_sStyleName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent | ||||||
2443 | uno::Sequence<uno::Any> aValues(rPropertyNames.getLength()); | ||||||
2444 | // workaround for bad designed API | ||||||
2445 | try | ||||||
2446 | { | ||||||
2447 | for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp) | ||||||
2448 | aValues[nProp] = GetPropertyValue_Impl(pPropSet, aBase, rPropertyNames[nProp]); | ||||||
2449 | } | ||||||
2450 | catch(beans::UnknownPropertyException&) | ||||||
2451 | { | ||||||
2452 | css::uno::Any anyEx = cppu::getCaughtException(); | ||||||
2453 | throw css::lang::WrappedTargetRuntimeException("Unknown property exception caught", | ||||||
2454 | static_cast < cppu::OWeakObject * > ( this ), anyEx ); | ||||||
2455 | } | ||||||
2456 | catch(lang::WrappedTargetException&) | ||||||
2457 | { | ||||||
2458 | css::uno::Any anyEx = cppu::getCaughtException(); | ||||||
2459 | throw lang::WrappedTargetRuntimeException("WrappedTargetException caught", | ||||||
2460 | static_cast < cppu::OWeakObject * > ( this ), anyEx ); | ||||||
2461 | } | ||||||
2462 | return aValues; | ||||||
2463 | } | ||||||
2464 | |||||||
2465 | void SwXStyle::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue) | ||||||
2466 | { | ||||||
2467 | SolarMutexGuard aGuard; | ||||||
2468 | const uno::Sequence<OUString> aProperties(&rPropertyName, 1); | ||||||
2469 | const uno::Sequence<uno::Any> aValues(&rValue, 1); | ||||||
2470 | SetPropertyValues_Impl(aProperties, aValues); | ||||||
2471 | } | ||||||
2472 | |||||||
2473 | beans::PropertyState SwXStyle::getPropertyState(const OUString& rPropertyName) | ||||||
2474 | { | ||||||
2475 | SolarMutexGuard aGuard; | ||||||
2476 | uno::Sequence<OUString> aNames{rPropertyName}; | ||||||
2477 | uno::Sequence<beans::PropertyState> aStates = getPropertyStates(aNames); | ||||||
2478 | return aStates.getConstArray()[0]; | ||||||
2479 | } | ||||||
2480 | |||||||
2481 | // allow to retarget the SfxItemSet working on, default correctly. Only | ||||||
2482 | // use pSourceSet below this point (except in header/footer processing) | ||||||
2483 | static const SfxItemSet* lcl_GetItemsetForProperty(const SfxItemSet& rSet, SfxStyleFamily eFamily, const OUString& rPropertyName) | ||||||
2484 | { | ||||||
2485 | if(eFamily != SfxStyleFamily::Page) | ||||||
2486 | return &rSet; | ||||||
2487 | const bool isFooter = rPropertyName.startsWith("Footer"); | ||||||
2488 | if(!isFooter && !rPropertyName.startsWith("Header") && rPropertyName != UNO_NAME_FIRST_IS_SHARED"FirstIsShared") | ||||||
2489 | return &rSet; | ||||||
2490 | const SvxSetItem* pSetItem; | ||||||
2491 | if(!lcl_GetHeaderFooterItem(rSet, rPropertyName, isFooter, pSetItem)) | ||||||
2492 | return nullptr; | ||||||
2493 | return &pSetItem->GetItemSet(); | ||||||
2494 | } | ||||||
2495 | uno::Sequence<beans::PropertyState> SwXStyle::getPropertyStates(const uno::Sequence<OUString>& rPropertyNames) | ||||||
2496 | { | ||||||
2497 | SolarMutexGuard aGuard; | ||||||
2498 | uno::Sequence<beans::PropertyState> aRet(rPropertyNames.getLength()); | ||||||
2499 | beans::PropertyState* pStates = aRet.getArray(); | ||||||
2500 | |||||||
2501 | if(!m_pBasePool) | ||||||
2502 | throw uno::RuntimeException(); | ||||||
2503 | SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
2504 | |||||||
2505 | SAL_WARN_IF(!pBase, "sw.uno", "where is the style?")do { if (true && (!pBase)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "where is the style?" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2505" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2505" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "where is the style?") == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2505" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "where is the style?"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "where is the style?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "2505" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2506 | if(!pBase) | ||||||
2507 | throw uno::RuntimeException(); | ||||||
2508 | |||||||
2509 | const OUString* pNames = rPropertyNames.getConstArray(); | ||||||
2510 | rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
2511 | sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE93 : m_rEntry.m_nPropMapType; | ||||||
2512 | |||||||
2513 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
2514 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
2515 | const SfxItemSet& rSet = xStyle->GetItemSet(); | ||||||
2516 | |||||||
2517 | for(sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i) | ||||||
2518 | { | ||||||
2519 | const OUString sPropName = pNames[i]; | ||||||
2520 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(sPropName); | ||||||
2521 | |||||||
2522 | if(!pEntry) | ||||||
2523 | throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast<cppu::OWeakObject*>(this)); | ||||||
2524 | |||||||
2525 | if(FN_UNO_NUM_RULES((20000 + 2200) + 15) == pEntry->nWID || FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59) == pEntry->nWID) | ||||||
2526 | { | ||||||
2527 | // handle NumRules first, done | ||||||
2528 | pStates[i] = beans::PropertyState_DIRECT_VALUE; | ||||||
2529 | continue; | ||||||
2530 | } | ||||||
2531 | const SfxItemSet* pSourceSet = lcl_GetItemsetForProperty(rSet, m_rEntry.m_eFamily, sPropName); | ||||||
2532 | if(!pSourceSet) | ||||||
2533 | { | ||||||
2534 | // if no SetItem, value is ambiguous and we are done | ||||||
2535 | pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE; | ||||||
2536 | continue; | ||||||
2537 | } | ||||||
2538 | switch(pEntry->nWID) | ||||||
2539 | { | ||||||
2540 | case OWN_ATTR_FILLBMP_MODE(3900 +45): | ||||||
2541 | { | ||||||
2542 | if(SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_STRETCH, false) | ||||||
2543 | || SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_TILE, false)) | ||||||
2544 | { | ||||||
2545 | pStates[i] = beans::PropertyState_DIRECT_VALUE; | ||||||
2546 | } | ||||||
2547 | else | ||||||
2548 | { | ||||||
2549 | pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE; | ||||||
2550 | } | ||||||
2551 | } | ||||||
2552 | break; | ||||||
2553 | case RES_BACKGROUND: | ||||||
2554 | { | ||||||
2555 | // for FlyFrames we need to mark the used properties from type RES_BACKGROUND | ||||||
2556 | // as beans::PropertyState_DIRECT_VALUE to let users of this property call | ||||||
2557 | // getPropertyValue where the member properties will be mapped from the | ||||||
2558 | // fill attributes to the according SvxBrushItem entries | ||||||
2559 | if (SWUnoHelper::needToMapFillItemsToSvxBrushItemTypes(*pSourceSet, pEntry->nMemberId)) | ||||||
2560 | { | ||||||
2561 | pStates[i] = beans::PropertyState_DIRECT_VALUE; | ||||||
2562 | } | ||||||
2563 | else | ||||||
2564 | { | ||||||
2565 | pStates[i] = beans::PropertyState_DEFAULT_VALUE; | ||||||
2566 | } | ||||||
2567 | } | ||||||
2568 | break; | ||||||
2569 | default: | ||||||
2570 | { | ||||||
2571 | pStates[i] = pPropSet->getPropertyState(*pEntry, *pSourceSet); | ||||||
2572 | |||||||
2573 | if(SfxStyleFamily::Page == m_rEntry.m_eFamily && SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ) == pEntry->nWID && beans::PropertyState_DIRECT_VALUE == pStates[i]) | ||||||
2574 | { | ||||||
2575 | const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 )); | ||||||
2576 | sal_uInt8 nMemberId = pEntry->nMemberId & 0x7f; | ||||||
2577 | |||||||
2578 | if((LONG_MAX9223372036854775807L == rSize.GetSize().Width() && (MID_SIZE_WIDTH1 == nMemberId || MID_SIZE_SIZE0 == nMemberId)) || | ||||||
2579 | (LONG_MAX9223372036854775807L == rSize.GetSize().Height() && MID_SIZE_HEIGHT2 == nMemberId)) | ||||||
2580 | { | ||||||
2581 | pStates[i] = beans::PropertyState_DEFAULT_VALUE; | ||||||
2582 | } | ||||||
2583 | } | ||||||
2584 | } | ||||||
2585 | } | ||||||
2586 | } | ||||||
2587 | return aRet; | ||||||
2588 | } | ||||||
2589 | |||||||
2590 | void SwXStyle::setPropertyToDefault(const OUString& rPropertyName) | ||||||
2591 | { | ||||||
2592 | const uno::Sequence<OUString> aSequence(&rPropertyName, 1); | ||||||
2593 | setPropertiesToDefault(aSequence); | ||||||
2594 | } | ||||||
2595 | |||||||
2596 | static SwFormat* lcl_GetFormatForStyle(SwDoc const * pDoc, const rtl::Reference<SwDocStyleSheet>& xStyle, const SfxStyleFamily eFamily) | ||||||
2597 | { | ||||||
2598 | if(!xStyle.is()) | ||||||
2599 | return nullptr; | ||||||
2600 | switch(eFamily) | ||||||
2601 | { | ||||||
2602 | case SfxStyleFamily::Char: return xStyle->GetCharFormat(); | ||||||
2603 | case SfxStyleFamily::Para: return xStyle->GetCollection(); | ||||||
2604 | case SfxStyleFamily::Frame: return xStyle->GetFrameFormat(); | ||||||
2605 | case SfxStyleFamily::Page: | ||||||
2606 | { | ||||||
2607 | SwPageDesc* pDesc(pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName())); | ||||||
2608 | if(pDesc) | ||||||
2609 | return &pDesc->GetMaster(); | ||||||
2610 | } | ||||||
2611 | break; | ||||||
2612 | default: ; | ||||||
2613 | } | ||||||
2614 | return nullptr; | ||||||
2615 | } | ||||||
2616 | |||||||
2617 | void SAL_CALL SwXStyle::setPropertiesToDefault(const uno::Sequence<OUString>& aPropertyNames) | ||||||
2618 | { | ||||||
2619 | SolarMutexGuard aGuard; | ||||||
2620 | const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase()))); | ||||||
2621 | SwFormat* pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.m_eFamily); | ||||||
2622 | if(!pTargetFormat) | ||||||
2623 | { | ||||||
2624 | if(!m_bIsDescriptor) | ||||||
2625 | return; | ||||||
2626 | for(const auto& rName : aPropertyNames) | ||||||
2627 | m_pPropertiesImpl->ClearProperty(rName); | ||||||
2628 | return; | ||||||
2629 | } | ||||||
2630 | const sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE93 : m_rEntry.m_nPropMapType; | ||||||
2631 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
2632 | const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap(); | ||||||
2633 | for(const auto& rName : aPropertyNames) | ||||||
2634 | { | ||||||
2635 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rName); | ||||||
2636 | if(!pEntry) | ||||||
2637 | throw beans::UnknownPropertyException("Unknown property: " + rName, static_cast<cppu::OWeakObject*>(this)); | ||||||
2638 | if(pEntry->nWID == FN_UNO_FOLLOW_STYLE((20000 + 2200) + 59) || pEntry->nWID == FN_UNO_NUM_RULES((20000 + 2200) + 15)) | ||||||
2639 | throw uno::RuntimeException("Cannot reset: " + rName, static_cast<cppu::OWeakObject*>(this)); | ||||||
2640 | if(pEntry->nFlags & beans::PropertyAttribute::READONLY) | ||||||
2641 | throw uno::RuntimeException("setPropertiesToDefault: property is read-only: " + rName, static_cast<cppu::OWeakObject*>(this)); | ||||||
2642 | if(pEntry->nWID == RES_PARATR_OUTLINELEVEL) | ||||||
2643 | { | ||||||
2644 | static_cast<SwTextFormatColl*>(pTargetFormat)->DeleteAssignmentToListLevelOfOutlineStyle(); | ||||||
2645 | continue; | ||||||
2646 | } | ||||||
2647 | pTargetFormat->ResetFormatAttr(pEntry->nWID); | ||||||
2648 | if(OWN_ATTR_FILLBMP_MODE(3900 +45) == pEntry->nWID) | ||||||
2649 | { | ||||||
2650 | // | ||||||
2651 | SwDoc* pDoc = pTargetFormat->GetDoc(); | ||||||
2652 | SfxItemSet aSet(pDoc->GetAttrPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{}); | ||||||
2653 | aSet.SetParent(&pTargetFormat->GetAttrSet()); | ||||||
2654 | |||||||
2655 | aSet.ClearItem(XATTR_FILLBMP_STRETCH); | ||||||
2656 | aSet.ClearItem(XATTR_FILLBMP_TILE); | ||||||
2657 | |||||||
2658 | pTargetFormat->SetFormatAttr(aSet); | ||||||
2659 | } | ||||||
2660 | } | ||||||
2661 | } | ||||||
2662 | |||||||
2663 | void SAL_CALL SwXStyle::setAllPropertiesToDefault() | ||||||
2664 | { | ||||||
2665 | SolarMutexGuard aGuard; | ||||||
2666 | if(!m_pBasePool) | ||||||
2667 | { | ||||||
2668 | if(!m_bIsDescriptor) | ||||||
2669 | throw uno::RuntimeException(); | ||||||
2670 | m_pPropertiesImpl->ClearAllProperties(); | ||||||
2671 | return; | ||||||
2672 | } | ||||||
2673 | const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase()))); | ||||||
2674 | if(!xStyle.is()) | ||||||
2675 | throw uno::RuntimeException(); | ||||||
2676 | if(SfxStyleFamily::Page == m_rEntry.m_eFamily) | ||||||
2677 | { | ||||||
2678 | size_t nPgDscPos(0); | ||||||
2679 | SwPageDesc* pDesc = m_pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName(), &nPgDscPos); | ||||||
2680 | SwFormat* pPageFormat(nullptr); | ||||||
2681 | if(pDesc) | ||||||
2682 | { | ||||||
2683 | pPageFormat = &pDesc->GetMaster(); | ||||||
2684 | pDesc->SetUseOn(UseOnPage::All); | ||||||
2685 | } | ||||||
2686 | else | ||||||
2687 | pPageFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.m_eFamily); | ||||||
2688 | SwPageDesc& rPageDesc = m_pDoc->GetPageDesc(nPgDscPos); | ||||||
2689 | rPageDesc.ResetAllMasterAttr(); | ||||||
2690 | |||||||
2691 | SvxLRSpaceItem aLR(RES_LR_SPACE); | ||||||
2692 | sal_Int32 nSize = GetMetricVal(CM_10) * 2; | ||||||
2693 | aLR.SetLeft(nSize); | ||||||
2694 | aLR.SetLeft(nSize); | ||||||
2695 | SvxULSpaceItem aUL(RES_UL_SPACE); | ||||||
2696 | aUL.SetUpper(static_cast<sal_uInt16>(nSize)); | ||||||
2697 | aUL.SetLower(static_cast<sal_uInt16>(nSize)); | ||||||
2698 | pPageFormat->SetFormatAttr(aLR); | ||||||
2699 | pPageFormat->SetFormatAttr(aUL); | ||||||
2700 | SwPageDesc* pStdPgDsc = m_pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD); | ||||||
2701 | std::shared_ptr<SwFormatFrameSize> aFrameSz(std::make_shared<SwFormatFrameSize>(SwFrameSize::Fixed)); | ||||||
2702 | |||||||
2703 | if(RES_POOLPAGE_STANDARD == rPageDesc.GetPoolFormatId()) | ||||||
2704 | { | ||||||
2705 | if(m_pDoc->getIDocumentDeviceAccess().getPrinter(false)) | ||||||
2706 | { | ||||||
2707 | const Size aPhysSize( SvxPaperInfo::GetPaperSize( | ||||||
2708 | static_cast<Printer*>(m_pDoc->getIDocumentDeviceAccess().getPrinter(false)))); | ||||||
2709 | aFrameSz->SetSize(aPhysSize); | ||||||
2710 | } | ||||||
2711 | else | ||||||
2712 | { | ||||||
2713 | aFrameSz->SetSize(SvxPaperInfo::GetDefaultPaperSize()); | ||||||
2714 | } | ||||||
2715 | |||||||
2716 | } | ||||||
2717 | else | ||||||
2718 | { | ||||||
2719 | aFrameSz.reset(pStdPgDsc->GetMaster().GetFrameSize().Clone()); | ||||||
2720 | } | ||||||
2721 | |||||||
2722 | if(pStdPgDsc->GetLandscape()) | ||||||
2723 | { | ||||||
2724 | SwTwips nTmp = aFrameSz->GetHeight(); | ||||||
2725 | aFrameSz->SetHeight(aFrameSz->GetWidth()); | ||||||
2726 | aFrameSz->SetWidth(nTmp); | ||||||
2727 | } | ||||||
2728 | |||||||
2729 | pPageFormat->SetFormatAttr(*aFrameSz); | ||||||
2730 | m_pDoc->ChgPageDesc(nPgDscPos, m_pDoc->GetPageDesc(nPgDscPos)); | ||||||
2731 | return; | ||||||
2732 | } | ||||||
2733 | if(SfxStyleFamily::Para == m_rEntry.m_eFamily) | ||||||
2734 | { | ||||||
2735 | if(xStyle->GetCollection()) | ||||||
2736 | xStyle->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle(); | ||||||
2737 | } | ||||||
2738 | SwFormat* const pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.m_eFamily); | ||||||
2739 | if(!pTargetFormat) | ||||||
2740 | return; | ||||||
2741 | pTargetFormat->ResetAllFormatAttr(); | ||||||
2742 | } | ||||||
2743 | |||||||
2744 | uno::Sequence<uno::Any> SAL_CALL SwXStyle::getPropertyDefaults(const uno::Sequence<OUString>& aPropertyNames) | ||||||
2745 | { | ||||||
2746 | SolarMutexGuard aGuard; | ||||||
2747 | sal_Int32 nCount = aPropertyNames.getLength(); | ||||||
2748 | uno::Sequence<uno::Any> aRet(nCount); | ||||||
2749 | if(!nCount) | ||||||
2750 | return aRet; | ||||||
2751 | SfxStyleSheetBase* pBase = GetStyleSheetBase(); | ||||||
2752 | if(!pBase) | ||||||
2753 | throw uno::RuntimeException(); | ||||||
2754 | rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
2755 | const sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE93 : m_rEntry.m_nPropMapType; | ||||||
2756 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
2757 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
2758 | |||||||
2759 | const SfxItemSet &rSet = xStyle->GetItemSet(), *pParentSet = rSet.GetParent(); | ||||||
2760 | for(sal_Int32 i = 0; i < nCount; ++i) | ||||||
2761 | { | ||||||
2762 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(aPropertyNames[i]); | ||||||
2763 | |||||||
2764 | if(!pEntry) | ||||||
2765 | throw beans::UnknownPropertyException("Unknown property: " + aPropertyNames[i], static_cast < cppu::OWeakObject * >(this)); | ||||||
2766 | // these cannot be in an item set, especially not the | ||||||
2767 | // parent set, so the default value is void | ||||||
2768 | if (pEntry->nWID >= RES_UNKNOWNATR_END) | ||||||
2769 | continue; | ||||||
2770 | |||||||
2771 | if(pParentSet) | ||||||
2772 | { | ||||||
2773 | aSwMapProvider.GetPropertySet(nPropSetId)->getPropertyValue(aPropertyNames[i], *pParentSet, aRet[i]); | ||||||
2774 | } | ||||||
2775 | else if(pEntry->nWID != rSet.GetPool()->GetSlotId(pEntry->nWID)) | ||||||
2776 | { | ||||||
2777 | const SfxPoolItem& rItem = rSet.GetPool()->GetDefaultItem(pEntry->nWID); | ||||||
2778 | rItem.QueryValue(aRet[i], pEntry->nMemberId); | ||||||
2779 | } | ||||||
2780 | } | ||||||
2781 | return aRet; | ||||||
2782 | } | ||||||
2783 | |||||||
2784 | uno::Any SwXStyle::getPropertyDefault(const OUString& rPropertyName) | ||||||
2785 | { | ||||||
2786 | const uno::Sequence<OUString> aSequence(&rPropertyName, 1); | ||||||
2787 | return getPropertyDefaults(aSequence)[0]; | ||||||
2788 | } | ||||||
2789 | |||||||
2790 | void SwXStyle::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) | ||||||
2791 | { | ||||||
2792 | if((rHint.GetId() == SfxHintId::Dying) || (rHint.GetId() == SfxHintId::StyleSheetErased)) | ||||||
2793 | { | ||||||
2794 | m_pBasePool = nullptr; | ||||||
2795 | SfxListener::EndListening(rBC); | ||||||
2796 | } | ||||||
2797 | else if(rHint.GetId() == SfxHintId::StyleSheetChanged) | ||||||
2798 | { | ||||||
2799 | SfxStyleSheetBasePool& rBP = static_cast<SfxStyleSheetBasePool&>(rBC); | ||||||
2800 | SfxStyleSheetBase* pOwnBase = rBP.Find(m_sStyleName, m_rEntry.m_eFamily); | ||||||
2801 | if(!pOwnBase) | ||||||
2802 | { | ||||||
2803 | SfxListener::EndListening(rBC); | ||||||
2804 | Invalidate(); | ||||||
2805 | } | ||||||
2806 | } | ||||||
2807 | } | ||||||
2808 | |||||||
2809 | void SwXStyle::Invalidate() | ||||||
2810 | { | ||||||
2811 | m_sStyleName.clear(); | ||||||
2812 | m_pBasePool = nullptr; | ||||||
2813 | m_pDoc = nullptr; | ||||||
2814 | m_xStyleData.clear(); | ||||||
2815 | m_xStyleFamily.clear(); | ||||||
2816 | } | ||||||
2817 | |||||||
2818 | SwXPageStyle::SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName) | ||||||
2819 | : SwXStyle(&rPool, SfxStyleFamily::Page, pDocSh->GetDoc(), rStyleName) | ||||||
2820 | { } | ||||||
2821 | |||||||
2822 | SwXPageStyle::SwXPageStyle(SwDocShell* pDocSh) | ||||||
2823 | : SwXStyle(pDocSh->GetDoc(), SfxStyleFamily::Page) | ||||||
2824 | { } | ||||||
2825 | |||||||
2826 | void SwXStyle::PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertySimpleEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl) | ||||||
2827 | { | ||||||
2828 | // create a new SvxSetItem and get it's ItemSet as new target | ||||||
2829 | const std::unique_ptr<SvxSetItem> pNewSetItem(pSetItem->Clone()); | ||||||
2830 | SfxItemSet& rSetSet = pNewSetItem->GetItemSet(); | ||||||
2831 | |||||||
2832 | // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem | ||||||
2833 | rSetSet.SetParent(&m_pDoc->GetDfltFrameFormat()->GetAttrSet()); | ||||||
2834 | |||||||
2835 | // replace the used SfxItemSet at the SwStyleBase_Impl temporarily and use the | ||||||
2836 | // default method to set the property | ||||||
2837 | { | ||||||
2838 | SwStyleBase_Impl::ItemSetOverrider o(rBaseImpl, &rSetSet); | ||||||
2839 | SetStyleProperty(rEntry, rPropSet, rVal, rBaseImpl); | ||||||
2840 | } | ||||||
2841 | |||||||
2842 | // reset parent at ItemSet from SetItem | ||||||
2843 | rSetSet.SetParent(nullptr); | ||||||
2844 | |||||||
2845 | // set the new SvxSetItem at the real target and delete it | ||||||
2846 | rBaseImpl.GetItemSet().Put(*pNewSetItem); | ||||||
2847 | } | ||||||
2848 | |||||||
2849 | void SwXPageStyle::SetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues) | ||||||
2850 | { | ||||||
2851 | if(!GetDoc()) | ||||||
2852 | throw uno::RuntimeException(); | ||||||
2853 | |||||||
2854 | if(rPropertyNames.getLength() != rValues.getLength()) | ||||||
2855 | throw lang::IllegalArgumentException(); | ||||||
2856 | |||||||
2857 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PAGE_STYLE4); | ||||||
2858 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
2859 | SwStyleBase_Impl aBaseImpl(*GetDoc(), GetStyleName(), &GetDoc()->GetDfltFrameFormat()->GetAttrSet()); // add pDfltFrameFormat as parent | ||||||
2860 | if(!m_pBasePool) | ||||||
2861 | { | ||||||
2862 | if(!IsDescriptor()) | ||||||
2863 | throw uno::RuntimeException(); | ||||||
2864 | for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp) | ||||||
2865 | if(!m_pPropertiesImpl->SetProperty(rPropertyNames[nProp], rValues[nProp])) | ||||||
2866 | throw lang::IllegalArgumentException(); | ||||||
2867 | return; | ||||||
2868 | } | ||||||
2869 | SfxStyleSheetBase* pBase = GetStyleSheetBase(); | ||||||
2870 | if(!pBase) | ||||||
2871 | throw uno::RuntimeException(); | ||||||
2872 | aBaseImpl.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
2873 | for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp) | ||||||
2874 | { | ||||||
2875 | const OUString& rPropName = rPropertyNames[nProp]; | ||||||
2876 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropName); | ||||||
2877 | |||||||
2878 | if(!pEntry) | ||||||
2879 | throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast<cppu::OWeakObject*>(this)); | ||||||
2880 | if(pEntry->nFlags & beans::PropertyAttribute::READONLY) | ||||||
2881 | throw beans::PropertyVetoException("Property is read-only: " + rPropName, static_cast<cppu::OWeakObject*>(this)); | ||||||
2882 | |||||||
2883 | const bool bHeader(rPropName.startsWith("Header")); | ||||||
2884 | const bool bFooter(rPropName.startsWith("Footer")); | ||||||
2885 | const bool bFirstIsShared(rPropName == UNO_NAME_FIRST_IS_SHARED"FirstIsShared"); | ||||||
2886 | if(bHeader || bFooter || bFirstIsShared) | ||||||
2887 | { | ||||||
2888 | switch(pEntry->nWID) | ||||||
2889 | { | ||||||
2890 | case SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 ): | ||||||
2891 | case RES_BACKGROUND: | ||||||
2892 | case RES_BOX: | ||||||
2893 | case RES_LR_SPACE: | ||||||
2894 | case RES_SHADOW: | ||||||
2895 | case RES_UL_SPACE: | ||||||
2896 | case SID_ATTR_PAGE_DYNAMICTypedWhichId<SfxBoolItem>( 10000 + 60 ): | ||||||
2897 | case SID_ATTR_PAGE_SHAREDTypedWhichId<SfxBoolItem>( 10000 + 61 ): | ||||||
2898 | case SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 ): | ||||||
2899 | case SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ): | ||||||
2900 | case RES_HEADER_FOOTER_EAT_SPACING: | ||||||
2901 | { | ||||||
2902 | // it is a Header/Footer entry, access the SvxSetItem containing it's information | ||||||
2903 | const SvxSetItem* pSetItem = nullptr; | ||||||
2904 | if (lcl_GetHeaderFooterItem(aBaseImpl.GetItemSet(), rPropName, bFooter, pSetItem)) | ||||||
2905 | { | ||||||
2906 | PutItemToSet(pSetItem, *pPropSet, *pEntry, rValues[nProp], aBaseImpl); | ||||||
2907 | |||||||
2908 | if (pEntry->nWID == SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 )) | ||||||
2909 | { | ||||||
2910 | // Need to add this to the other as well | ||||||
2911 | if (SfxItemState::SET == aBaseImpl.GetItemSet().GetItemState( | ||||||
2912 | bFooter ? SID_ATTR_PAGE_HEADERSETTypedWhichId<SvxSetItem>( 10000 + 57 ) : SID_ATTR_PAGE_FOOTERSETTypedWhichId<SvxSetItem>( 10000 + 58 ), | ||||||
2913 | false, reinterpret_cast<const SfxPoolItem**>(&pSetItem))) | ||||||
2914 | { | ||||||
2915 | PutItemToSet(pSetItem, *pPropSet, *pEntry, rValues[nProp], aBaseImpl); | ||||||
2916 | } | ||||||
2917 | } | ||||||
2918 | } | ||||||
2919 | else if(pEntry->nWID == SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 ) && rValues[nProp].get<bool>()) | ||||||
2920 | { | ||||||
2921 | // Header/footer gets switched on, create defaults and the needed SfxSetItem | ||||||
2922 | SfxItemSet aTempSet(*aBaseImpl.GetItemSet().GetPool(), | ||||||
2923 | svl::Items<RES_FRMATR_BEGIN,RES_FRMATR_END - 1, // [82 | ||||||
2924 | |||||||
2925 | // FillAttribute support | ||||||
2926 | XATTR_FILL_FIRST, XATTR_FILL_LAST, // [1014 | ||||||
2927 | |||||||
2928 | SID_ATTR_BORDER_INNERTypedWhichId<SvxBoxInfoItem>( 10000 + 23 ),SID_ATTR_BORDER_INNERTypedWhichId<SvxBoxInfoItem>( 10000 + 23 ), // [10023 | ||||||
2929 | SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ),SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ), // [10051 | ||||||
2930 | SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 ),SID_ATTR_PAGE_SHAREDTypedWhichId<SfxBoolItem>( 10000 + 61 ), // [10060 | ||||||
2931 | SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 ),SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 )>{}); | ||||||
2932 | |||||||
2933 | // set correct parent to get the XFILL_NONE FillStyle as needed | ||||||
2934 | aTempSet.SetParent(&GetDoc()->GetDfltFrameFormat()->GetAttrSet()); | ||||||
2935 | |||||||
2936 | aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 ), true)); | ||||||
2937 | aTempSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ), Size(MM50283, MM50283))); | ||||||
2938 | aTempSet.Put(SvxLRSpaceItem(RES_LR_SPACE)); | ||||||
2939 | aTempSet.Put(SvxULSpaceItem(RES_UL_SPACE)); | ||||||
2940 | aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_SHAREDTypedWhichId<SfxBoolItem>( 10000 + 61 ), true)); | ||||||
2941 | aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 ), true)); | ||||||
2942 | aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_DYNAMICTypedWhichId<SfxBoolItem>( 10000 + 60 ), true)); | ||||||
2943 | |||||||
2944 | SvxSetItem aNewSetItem(bFooter ? SID_ATTR_PAGE_FOOTERSETTypedWhichId<SvxSetItem>( 10000 + 58 ) : SID_ATTR_PAGE_HEADERSETTypedWhichId<SvxSetItem>( 10000 + 57 ), aTempSet); | ||||||
2945 | aBaseImpl.GetItemSet().Put(aNewSetItem); | ||||||
2946 | } | ||||||
2947 | } | ||||||
2948 | continue; | ||||||
2949 | case XATTR_FILLBMP_SIZELOG: | ||||||
2950 | case XATTR_FILLBMP_TILEOFFSETX: | ||||||
2951 | case XATTR_FILLBMP_TILEOFFSETY: | ||||||
2952 | case XATTR_FILLBMP_POSOFFSETX: | ||||||
2953 | case XATTR_FILLBMP_POSOFFSETY: | ||||||
2954 | case XATTR_FILLBMP_POS: | ||||||
2955 | case XATTR_FILLBMP_SIZEX: | ||||||
2956 | case XATTR_FILLBMP_SIZEY: | ||||||
2957 | case XATTR_FILLBMP_STRETCH: | ||||||
2958 | case XATTR_FILLBMP_TILE: | ||||||
2959 | case OWN_ATTR_FILLBMP_MODE(3900 +45): | ||||||
2960 | case XATTR_FILLCOLOR: | ||||||
2961 | case XATTR_FILLBACKGROUND: | ||||||
2962 | case XATTR_FILLBITMAP: | ||||||
2963 | case XATTR_GRADIENTSTEPCOUNT: | ||||||
2964 | case XATTR_FILLGRADIENT: | ||||||
2965 | case XATTR_FILLHATCH: | ||||||
2966 | case XATTR_FILLSTYLE: | ||||||
2967 | case XATTR_FILLTRANSPARENCE: | ||||||
2968 | case XATTR_FILLFLOATTRANSPARENCE: | ||||||
2969 | case XATTR_SECONDARYFILLCOLOR: | ||||||
2970 | if(bFirstIsShared) // only special handling for headers/footers here | ||||||
2971 | break; | ||||||
2972 | { | ||||||
2973 | const SvxSetItem* pSetItem = nullptr; | ||||||
2974 | |||||||
2975 | if(SfxItemState::SET == aBaseImpl.GetItemSet().GetItemState(bFooter ? SID_ATTR_PAGE_FOOTERSETTypedWhichId<SvxSetItem>( 10000 + 58 ) : SID_ATTR_PAGE_HEADERSETTypedWhichId<SvxSetItem>( 10000 + 57 ), false, reinterpret_cast<const SfxPoolItem**>(&pSetItem))) | ||||||
2976 | { | ||||||
2977 | // create a new SvxSetItem and get it's ItemSet as new target | ||||||
2978 | std::unique_ptr<SvxSetItem> pNewSetItem(pSetItem->Clone()); | ||||||
2979 | SfxItemSet& rSetSet = pNewSetItem->GetItemSet(); | ||||||
2980 | |||||||
2981 | // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem | ||||||
2982 | rSetSet.SetParent(&GetDoc()->GetDfltFrameFormat()->GetAttrSet()); | ||||||
2983 | |||||||
2984 | // replace the used SfxItemSet at the SwStyleBase_Impl temporarily and use the | ||||||
2985 | // default method to set the property | ||||||
2986 | { | ||||||
2987 | SwStyleBase_Impl::ItemSetOverrider o(aBaseImpl, &rSetSet); | ||||||
2988 | SetStyleProperty(*pEntry, *pPropSet, rValues[nProp], aBaseImpl); | ||||||
2989 | } | ||||||
2990 | |||||||
2991 | // reset paret at ItemSet from SetItem | ||||||
2992 | rSetSet.SetParent(nullptr); | ||||||
2993 | |||||||
2994 | // set the new SvxSetItem at the real target and delete it | ||||||
2995 | aBaseImpl.GetItemSet().Put(*pNewSetItem); | ||||||
2996 | } | ||||||
2997 | } | ||||||
2998 | continue; | ||||||
2999 | default: ; | ||||||
3000 | } | ||||||
3001 | } | ||||||
3002 | switch(pEntry->nWID) | ||||||
3003 | { | ||||||
3004 | case SID_ATTR_PAGE_DYNAMICTypedWhichId<SfxBoolItem>( 10000 + 60 ): | ||||||
3005 | case SID_ATTR_PAGE_SHAREDTypedWhichId<SfxBoolItem>( 10000 + 61 ): | ||||||
3006 | case SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 ): | ||||||
3007 | case SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 ): | ||||||
3008 | case RES_HEADER_FOOTER_EAT_SPACING: | ||||||
3009 | // these slots are exclusive to Header/Footer, thus this is an error | ||||||
3010 | throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast<cppu::OWeakObject*>(this)); | ||||||
3011 | case FN_UNO_HEADER((20000 + 2200) + 35): | ||||||
3012 | case FN_UNO_HEADER_LEFT((20000 + 2200) + 36): | ||||||
3013 | case FN_UNO_HEADER_RIGHT((20000 + 2200) + 37): | ||||||
3014 | case FN_UNO_HEADER_FIRST((20000 + 2200) + 118): | ||||||
3015 | case FN_UNO_FOOTER((20000 + 2200) + 38): | ||||||
3016 | case FN_UNO_FOOTER_LEFT((20000 + 2200) + 39): | ||||||
3017 | case FN_UNO_FOOTER_RIGHT((20000 + 2200) + 40): | ||||||
3018 | case FN_UNO_FOOTER_FIRST((20000 + 2200) + 119): | ||||||
3019 | throw lang::IllegalArgumentException(); | ||||||
3020 | case FN_PARAM_FTN_INFO((20000 + 1100)+23): | ||||||
3021 | { | ||||||
3022 | const SfxPoolItem& rItem = aBaseImpl.GetItemSet().Get(FN_PARAM_FTN_INFO((20000 + 1100)+23)); | ||||||
3023 | std::unique_ptr<SfxPoolItem> pNewFootnoteItem(rItem.Clone()); | ||||||
3024 | if(!pNewFootnoteItem->PutValue(rValues[nProp], pEntry->nMemberId)) | ||||||
3025 | throw lang::IllegalArgumentException(); | ||||||
3026 | aBaseImpl.GetItemSet().Put(std::move(pNewFootnoteItem)); | ||||||
3027 | break; | ||||||
3028 | } | ||||||
3029 | default: | ||||||
3030 | { | ||||||
3031 | SetStyleProperty(*pEntry, *pPropSet, rValues[nProp], aBaseImpl); | ||||||
3032 | break; | ||||||
3033 | } | ||||||
3034 | } | ||||||
3035 | } | ||||||
3036 | |||||||
3037 | if(aBaseImpl.HasItemSet()) | ||||||
3038 | { | ||||||
3039 | ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo()); | ||||||
3040 | |||||||
3041 | if (undoGuard.UndoWasEnabled()) | ||||||
3042 | { | ||||||
3043 | // Fix i64460: as long as Undo of page styles with header/footer causes trouble... | ||||||
3044 | GetDoc()->GetIDocumentUndoRedo().DelAllUndoObj(); | ||||||
3045 | } | ||||||
3046 | |||||||
3047 | aBaseImpl.getNewBase()->SetItemSet(aBaseImpl.GetItemSet()); | ||||||
3048 | } | ||||||
3049 | } | ||||||
3050 | |||||||
3051 | void SwXPageStyle::setPropertyValues(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues) | ||||||
3052 | { | ||||||
3053 | SolarMutexGuard aGuard; | ||||||
3054 | |||||||
3055 | // workaround for bad designed API | ||||||
3056 | try | ||||||
3057 | { | ||||||
3058 | SetPropertyValues_Impl(rPropertyNames, rValues); | ||||||
3059 | } | ||||||
3060 | catch (const beans::UnknownPropertyException &rException) | ||||||
3061 | { | ||||||
3062 | // wrap the original (here not allowed) exception in | ||||||
3063 | // a lang::WrappedTargetException that gets thrown instead. | ||||||
3064 | lang::WrappedTargetException aWExc; | ||||||
3065 | aWExc.TargetException <<= rException; | ||||||
3066 | throw aWExc; | ||||||
3067 | } | ||||||
3068 | } | ||||||
3069 | |||||||
3070 | static uno::Reference<text::XText> lcl_makeHeaderFooter(const sal_uInt16 nRes, const bool bHeader, SwFrameFormat const*const pFrameFormat) | ||||||
3071 | { | ||||||
3072 | if (!pFrameFormat) | ||||||
3073 | return nullptr; | ||||||
3074 | const SfxItemSet& rSet = pFrameFormat->GetAttrSet(); | ||||||
3075 | const SfxPoolItem* pItem; | ||||||
3076 | if(SfxItemState::SET != rSet.GetItemState(nRes, true, &pItem)) | ||||||
3077 | return nullptr; | ||||||
3078 | SwFrameFormat* const pHeadFootFormat = bHeader | ||||||
3079 | ? static_cast<SwFormatHeader*>(const_cast<SfxPoolItem*>(pItem))->GetHeaderFormat() | ||||||
3080 | : static_cast<SwFormatFooter*>(const_cast<SfxPoolItem*>(pItem))->GetFooterFormat(); | ||||||
3081 | if(!pHeadFootFormat) | ||||||
3082 | return nullptr; | ||||||
3083 | return SwXHeadFootText::CreateXHeadFootText(*pHeadFootFormat, bHeader); | ||||||
3084 | } | ||||||
3085 | |||||||
3086 | uno::Sequence<uno::Any> SwXPageStyle::GetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames) | ||||||
3087 | { | ||||||
3088 | if(!GetDoc()) | ||||||
3089 | throw uno::RuntimeException(); | ||||||
3090 | |||||||
3091 | sal_Int32 nLength = rPropertyNames.getLength(); | ||||||
3092 | uno::Sequence<uno::Any> aRet (nLength); | ||||||
3093 | if(!m_pBasePool) | ||||||
3094 | { | ||||||
3095 | if(!IsDescriptor()) | ||||||
3096 | throw uno::RuntimeException(); | ||||||
3097 | for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp) | ||||||
3098 | { | ||||||
3099 | const uno::Any* pAny = nullptr; | ||||||
3100 | m_pPropertiesImpl->GetProperty(rPropertyNames[nProp], pAny); | ||||||
3101 | if (!pAny->hasValue()) | ||||||
3102 | SwStyleProperties_Impl::GetProperty(rPropertyNames[nProp], m_xStyleData, aRet[nProp]); | ||||||
3103 | else | ||||||
3104 | aRet[nProp] = *pAny; | ||||||
3105 | } | ||||||
3106 | return aRet; | ||||||
3107 | } | ||||||
3108 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PAGE_STYLE4); | ||||||
3109 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
3110 | SwStyleBase_Impl aBase(*GetDoc(), GetStyleName(), &GetDoc()->GetDfltFrameFormat()->GetAttrSet()); // add pDfltFrameFormat as parent | ||||||
3111 | SfxStyleSheetBase* pBase = GetStyleSheetBase(); | ||||||
3112 | if(!pBase) | ||||||
3113 | throw uno::RuntimeException(); | ||||||
3114 | for(sal_Int32 nProp = 0; nProp < nLength; ++nProp) | ||||||
3115 | { | ||||||
3116 | const OUString& rPropName = rPropertyNames[nProp]; | ||||||
3117 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropName); | ||||||
3118 | |||||||
3119 | if (!pEntry) | ||||||
3120 | throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast < cppu::OWeakObject * > ( this ) ); | ||||||
3121 | const bool bHeader(rPropName.startsWith("Header")); | ||||||
3122 | const bool bFooter(rPropName.startsWith("Footer")); | ||||||
3123 | const bool bFirstIsShared(rPropName == UNO_NAME_FIRST_IS_SHARED"FirstIsShared"); | ||||||
3124 | if(bHeader || bFooter || bFirstIsShared) | ||||||
3125 | { | ||||||
3126 | switch(pEntry->nWID) | ||||||
3127 | { | ||||||
3128 | case SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 ): | ||||||
3129 | case RES_BACKGROUND: | ||||||
3130 | case RES_BOX: | ||||||
3131 | case RES_LR_SPACE: | ||||||
3132 | case RES_SHADOW: | ||||||
3133 | case RES_UL_SPACE: | ||||||
3134 | case SID_ATTR_PAGE_DYNAMICTypedWhichId<SfxBoolItem>( 10000 + 60 ): | ||||||
3135 | case SID_ATTR_PAGE_SHAREDTypedWhichId<SfxBoolItem>( 10000 + 61 ): | ||||||
3136 | case SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 ): | ||||||
3137 | case SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ): | ||||||
3138 | case RES_HEADER_FOOTER_EAT_SPACING: | ||||||
3139 | { | ||||||
3140 | // slot is a Header/Footer slot | ||||||
3141 | rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pBase) ) ); | ||||||
3142 | const SfxItemSet& rSet = xStyle->GetItemSet(); | ||||||
3143 | const SvxSetItem* pSetItem; | ||||||
3144 | |||||||
3145 | if (lcl_GetHeaderFooterItem(rSet, rPropName, bFooter, pSetItem)) | ||||||
3146 | { | ||||||
3147 | // get from SfxItemSet of the corresponding SfxSetItem | ||||||
3148 | const SfxItemSet& rSetSet = pSetItem->GetItemSet(); | ||||||
3149 | { | ||||||
3150 | SwStyleBase_Impl::ItemSetOverrider o(aBase, &const_cast< SfxItemSet& >(rSetSet)); | ||||||
3151 | aRet[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase); | ||||||
3152 | } | ||||||
3153 | } | ||||||
3154 | else if(pEntry->nWID == SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 )) | ||||||
3155 | { | ||||||
3156 | // header/footer is not available, thus off. Default is <false>, though | ||||||
3157 | aRet[nProp] <<= false; | ||||||
3158 | } | ||||||
3159 | } | ||||||
3160 | continue; | ||||||
3161 | case XATTR_FILLBMP_SIZELOG: | ||||||
3162 | case XATTR_FILLBMP_TILEOFFSETX: | ||||||
3163 | case XATTR_FILLBMP_TILEOFFSETY: | ||||||
3164 | case XATTR_FILLBMP_POSOFFSETX: | ||||||
3165 | case XATTR_FILLBMP_POSOFFSETY: | ||||||
3166 | case XATTR_FILLBMP_POS: | ||||||
3167 | case XATTR_FILLBMP_SIZEX: | ||||||
3168 | case XATTR_FILLBMP_SIZEY: | ||||||
3169 | case XATTR_FILLBMP_STRETCH: | ||||||
3170 | case XATTR_FILLBMP_TILE: | ||||||
3171 | case OWN_ATTR_FILLBMP_MODE(3900 +45): | ||||||
3172 | case XATTR_FILLCOLOR: | ||||||
3173 | case XATTR_FILLBACKGROUND: | ||||||
3174 | case XATTR_FILLBITMAP: | ||||||
3175 | case XATTR_GRADIENTSTEPCOUNT: | ||||||
3176 | case XATTR_FILLGRADIENT: | ||||||
3177 | case XATTR_FILLHATCH: | ||||||
3178 | case XATTR_FILLSTYLE: | ||||||
3179 | case XATTR_FILLTRANSPARENCE: | ||||||
3180 | case XATTR_FILLFLOATTRANSPARENCE: | ||||||
3181 | case XATTR_SECONDARYFILLCOLOR: | ||||||
3182 | if(bFirstIsShared) // only special handling for headers/footers here | ||||||
3183 | break; | ||||||
3184 | { | ||||||
3185 | rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pBase) ) ); | ||||||
3186 | const SfxItemSet& rSet = xStyle->GetItemSet(); | ||||||
3187 | const SvxSetItem* pSetItem; | ||||||
3188 | if(SfxItemState::SET == rSet.GetItemState(bFooter ? SID_ATTR_PAGE_FOOTERSETTypedWhichId<SvxSetItem>( 10000 + 58 ) : SID_ATTR_PAGE_HEADERSETTypedWhichId<SvxSetItem>( 10000 + 57 ), false, reinterpret_cast<const SfxPoolItem**>(&pSetItem))) | ||||||
3189 | { | ||||||
3190 | // set at SfxItemSet of the corresponding SfxSetItem | ||||||
3191 | const SfxItemSet& rSetSet = pSetItem->GetItemSet(); | ||||||
3192 | { | ||||||
3193 | SwStyleBase_Impl::ItemSetOverrider o(aBase, &const_cast<SfxItemSet&>(rSetSet)); | ||||||
3194 | aRet[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase); | ||||||
3195 | } | ||||||
3196 | } | ||||||
3197 | } | ||||||
3198 | continue; | ||||||
3199 | default: ; | ||||||
3200 | } | ||||||
3201 | } | ||||||
3202 | switch(pEntry->nWID) | ||||||
3203 | { | ||||||
3204 | // these slots are exclusive to Header/Footer, thus this is an error | ||||||
3205 | case SID_ATTR_PAGE_DYNAMICTypedWhichId<SfxBoolItem>( 10000 + 60 ): | ||||||
3206 | case SID_ATTR_PAGE_SHAREDTypedWhichId<SfxBoolItem>( 10000 + 61 ): | ||||||
3207 | case SID_ATTR_PAGE_SHARED_FIRST( 10000 + 1114 ): | ||||||
3208 | case SID_ATTR_PAGE_ONTypedWhichId<SfxBoolItem>( 10000 + 59 ): | ||||||
3209 | case RES_HEADER_FOOTER_EAT_SPACING: | ||||||
3210 | throw beans::UnknownPropertyException( "Unknown property: " + rPropName, static_cast < cppu::OWeakObject * > ( this ) ); | ||||||
3211 | case FN_UNO_HEADER((20000 + 2200) + 35): | ||||||
3212 | case FN_UNO_HEADER_LEFT((20000 + 2200) + 36): | ||||||
3213 | case FN_UNO_HEADER_FIRST((20000 + 2200) + 118): | ||||||
3214 | case FN_UNO_HEADER_RIGHT((20000 + 2200) + 37): | ||||||
3215 | case FN_UNO_FOOTER((20000 + 2200) + 38): | ||||||
3216 | case FN_UNO_FOOTER_LEFT((20000 + 2200) + 39): | ||||||
3217 | case FN_UNO_FOOTER_FIRST((20000 + 2200) + 119): | ||||||
3218 | case FN_UNO_FOOTER_RIGHT((20000 + 2200) + 40): | ||||||
3219 | { | ||||||
3220 | bool bLeft(false); | ||||||
3221 | bool bFirst(false); | ||||||
3222 | sal_uInt16 nRes = 0; | ||||||
3223 | switch(pEntry->nWID) | ||||||
3224 | { | ||||||
3225 | case FN_UNO_HEADER((20000 + 2200) + 35): nRes = RES_HEADER; break; | ||||||
3226 | case FN_UNO_HEADER_LEFT((20000 + 2200) + 36): nRes = RES_HEADER; bLeft = true; break; | ||||||
3227 | case FN_UNO_HEADER_FIRST((20000 + 2200) + 118): nRes = RES_HEADER; bFirst = true; break; | ||||||
3228 | case FN_UNO_HEADER_RIGHT((20000 + 2200) + 37): nRes = RES_HEADER; break; | ||||||
3229 | case FN_UNO_FOOTER((20000 + 2200) + 38): nRes = RES_FOOTER; break; | ||||||
3230 | case FN_UNO_FOOTER_LEFT((20000 + 2200) + 39): nRes = RES_FOOTER; bLeft = true; break; | ||||||
3231 | case FN_UNO_FOOTER_FIRST((20000 + 2200) + 119): nRes = RES_FOOTER; bFirst = true; break; | ||||||
3232 | case FN_UNO_FOOTER_RIGHT((20000 + 2200) + 40): nRes = RES_FOOTER; break; | ||||||
3233 | default: ; | ||||||
3234 | } | ||||||
3235 | |||||||
3236 | const SwPageDesc* pDesc = aBase.GetOldPageDesc(); | ||||||
3237 | assert(pDesc)(static_cast <bool> (pDesc) ? void (0) : __assert_fail ( "pDesc", "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 3237, __extension__ __PRETTY_FUNCTION__)); | ||||||
3238 | const SwFrameFormat* pFrameFormat = nullptr; | ||||||
3239 | bool bShare = (nRes == RES_HEADER && pDesc->IsHeaderShared()) || (nRes == RES_FOOTER && pDesc->IsFooterShared()); | ||||||
3240 | bool bShareFirst = pDesc->IsFirstShared(); | ||||||
3241 | // TextLeft returns the left content if there is one, | ||||||
3242 | // Text and TextRight return the master content. | ||||||
3243 | // TextRight does the same as Text and is for | ||||||
3244 | // compatibility only. | ||||||
3245 | if(bLeft && !bShare) | ||||||
3246 | pFrameFormat = &pDesc->GetLeft(); | ||||||
3247 | else if(bFirst && !bShareFirst) | ||||||
3248 | { | ||||||
3249 | pFrameFormat = &pDesc->GetFirstMaster(); | ||||||
3250 | // no need to make GetFirstLeft() accessible | ||||||
3251 | // since it is always shared | ||||||
3252 | } | ||||||
3253 | else | ||||||
3254 | pFrameFormat = &pDesc->GetMaster(); | ||||||
3255 | const uno::Reference<text::XText> xRet = lcl_makeHeaderFooter(nRes, nRes == RES_HEADER, pFrameFormat); | ||||||
3256 | if (xRet.is()) | ||||||
3257 | aRet[nProp] <<= xRet; | ||||||
3258 | } | ||||||
3259 | break; | ||||||
3260 | case FN_PARAM_FTN_INFO((20000 + 1100)+23): | ||||||
3261 | { | ||||||
3262 | rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
3263 | const SfxItemSet& rSet = xStyle->GetItemSet(); | ||||||
3264 | const SfxPoolItem& rItem = rSet.Get(FN_PARAM_FTN_INFO((20000 + 1100)+23)); | ||||||
3265 | rItem.QueryValue(aRet[nProp], pEntry->nMemberId); | ||||||
3266 | } | ||||||
3267 | break; | ||||||
3268 | default: | ||||||
3269 | aRet[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase); | ||||||
3270 | } | ||||||
3271 | } | ||||||
3272 | return aRet; | ||||||
3273 | } | ||||||
3274 | |||||||
3275 | uno::Sequence<uno::Any> SwXPageStyle::getPropertyValues(const uno::Sequence<OUString>& rPropertyNames) | ||||||
3276 | { | ||||||
3277 | SolarMutexGuard aGuard; | ||||||
3278 | uno::Sequence<uno::Any> aValues; | ||||||
3279 | |||||||
3280 | // workaround for bad designed API | ||||||
3281 | try | ||||||
3282 | { | ||||||
3283 | aValues = GetPropertyValues_Impl(rPropertyNames); | ||||||
3284 | } | ||||||
3285 | catch(beans::UnknownPropertyException &) | ||||||
3286 | { | ||||||
3287 | css::uno::Any anyEx = cppu::getCaughtException(); | ||||||
3288 | throw lang::WrappedTargetRuntimeException("Unknown property exception caught", | ||||||
3289 | static_cast < cppu::OWeakObject * > ( this ), anyEx ); | ||||||
3290 | } | ||||||
3291 | catch(lang::WrappedTargetException &) | ||||||
3292 | { | ||||||
3293 | css::uno::Any anyEx = cppu::getCaughtException(); | ||||||
3294 | throw lang::WrappedTargetRuntimeException("WrappedTargetException caught", | ||||||
3295 | static_cast < cppu::OWeakObject * > ( this ), anyEx ); | ||||||
3296 | } | ||||||
3297 | |||||||
3298 | return aValues; | ||||||
3299 | } | ||||||
3300 | |||||||
3301 | uno::Any SwXPageStyle::getPropertyValue(const OUString& rPropertyName) | ||||||
3302 | { | ||||||
3303 | SolarMutexGuard aGuard; | ||||||
3304 | const uno::Sequence<OUString> aProperties(&rPropertyName, 1); | ||||||
3305 | return GetPropertyValues_Impl(aProperties)[0]; | ||||||
3306 | } | ||||||
3307 | |||||||
3308 | void SwXPageStyle::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue) | ||||||
3309 | { | ||||||
3310 | SolarMutexGuard aGuard; | ||||||
3311 | const uno::Sequence<OUString> aProperties(&rPropertyName, 1); | ||||||
3312 | const uno::Sequence<uno::Any> aValues(&rValue, 1); | ||||||
3313 | SetPropertyValues_Impl(aProperties, aValues); | ||||||
3314 | } | ||||||
3315 | |||||||
3316 | SwXFrameStyle::SwXFrameStyle(SwDoc *pDoc) | ||||||
3317 | : SwXStyle(pDoc, SfxStyleFamily::Frame, false) | ||||||
3318 | { } | ||||||
3319 | |||||||
3320 | void SwXFrameStyle::SetItem(sal_uInt16 eAtr, const SfxPoolItem& rItem) | ||||||
3321 | { | ||||||
3322 | assert(eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END)(static_cast <bool> (eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END) ? void (0) : __assert_fail ("eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END" , "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 3322, __extension__ __PRETTY_FUNCTION__)); | ||||||
3323 | SfxStyleSheetBase* pBase = GetStyleSheetBase(); | ||||||
3324 | if(!pBase) | ||||||
3325 | return; | ||||||
3326 | rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
3327 | SfxItemSet& rStyleSet = xStyle->GetItemSet(); | ||||||
3328 | SfxItemSet aSet(*rStyleSet.GetPool(), {{sal_uInt16(eAtr), sal_uInt16(eAtr)}}); | ||||||
3329 | aSet.Put(rItem); | ||||||
3330 | xStyle->SetItemSet(aSet); | ||||||
3331 | } | ||||||
3332 | |||||||
3333 | const SfxPoolItem* SwXFrameStyle::GetItem(sal_uInt16 eAtr) | ||||||
3334 | { | ||||||
3335 | assert(eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END)(static_cast <bool> (eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END) ? void (0) : __assert_fail ("eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END" , "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 3335, __extension__ __PRETTY_FUNCTION__)); | ||||||
3336 | SfxStyleSheetBase* pBase = GetStyleSheetBase(); | ||||||
3337 | if(!pBase) | ||||||
3338 | return nullptr; | ||||||
3339 | rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase))); | ||||||
3340 | return &xStyle->GetItemSet().Get(eAtr); | ||||||
3341 | } | ||||||
3342 | |||||||
3343 | uno::Sequence<uno::Type> SwXFrameStyle::getTypes() | ||||||
3344 | { | ||||||
3345 | return cppu::OTypeCollection( | ||||||
3346 | cppu::UnoType<XEventsSupplier>::get(), | ||||||
3347 | SwXStyle::getTypes() | ||||||
3348 | ).getTypes(); | ||||||
3349 | } | ||||||
3350 | |||||||
3351 | uno::Any SwXFrameStyle::queryInterface(const uno::Type& rType) | ||||||
3352 | { | ||||||
3353 | if(rType == cppu::UnoType<XEventsSupplier>::get()) | ||||||
3354 | return uno::makeAny(uno::Reference<XEventsSupplier>(this)); | ||||||
3355 | return SwXStyle::queryInterface(rType); | ||||||
3356 | } | ||||||
3357 | |||||||
3358 | uno::Reference<container::XNameReplace> SwXFrameStyle::getEvents() | ||||||
3359 | { | ||||||
3360 | return new SwFrameStyleEventDescriptor(*this); | ||||||
3361 | } | ||||||
3362 | |||||||
3363 | // Already implemented autostyle families: 3 | ||||||
3364 | #define AUTOSTYLE_FAMILY_COUNT3 3 | ||||||
3365 | const IStyleAccess::SwAutoStyleFamily aAutoStyleByIndex[] = | ||||||
3366 | { | ||||||
3367 | IStyleAccess::AUTO_STYLE_CHAR, | ||||||
3368 | IStyleAccess::AUTO_STYLE_RUBY, | ||||||
3369 | IStyleAccess::AUTO_STYLE_PARA | ||||||
3370 | }; | ||||||
3371 | |||||||
3372 | class SwAutoStylesEnumImpl | ||||||
3373 | { | ||||||
3374 | std::vector<std::shared_ptr<SfxItemSet>> mAutoStyles; | ||||||
3375 | std::vector<std::shared_ptr<SfxItemSet>>::iterator aIter; | ||||||
3376 | SwDoc& rDoc; | ||||||
3377 | IStyleAccess::SwAutoStyleFamily eFamily; | ||||||
3378 | public: | ||||||
3379 | SwAutoStylesEnumImpl( SwDoc& rInitDoc, IStyleAccess::SwAutoStyleFamily eFam ); | ||||||
3380 | bool hasMoreElements() { return aIter != mAutoStyles.end(); } | ||||||
3381 | std::shared_ptr<SfxItemSet> const & nextElement() { return *(aIter++); } | ||||||
3382 | IStyleAccess::SwAutoStyleFamily getFamily() const { return eFamily; } | ||||||
3383 | SwDoc& getDoc() const { return rDoc; } | ||||||
3384 | }; | ||||||
3385 | |||||||
3386 | SwXAutoStyles::SwXAutoStyles(SwDocShell& rDocShell) : | ||||||
3387 | SwUnoCollection(rDocShell.GetDoc()), m_pDocShell( &rDocShell ) | ||||||
3388 | { | ||||||
3389 | } | ||||||
3390 | |||||||
3391 | SwXAutoStyles::~SwXAutoStyles() | ||||||
3392 | { | ||||||
3393 | } | ||||||
3394 | |||||||
3395 | sal_Int32 SwXAutoStyles::getCount() | ||||||
3396 | { | ||||||
3397 | return AUTOSTYLE_FAMILY_COUNT3; | ||||||
3398 | } | ||||||
3399 | |||||||
3400 | uno::Any SwXAutoStyles::getByIndex(sal_Int32 nIndex) | ||||||
3401 | { | ||||||
3402 | SolarMutexGuard aGuard; | ||||||
3403 | uno::Any aRet; | ||||||
3404 | if(nIndex < 0 || nIndex >= AUTOSTYLE_FAMILY_COUNT3) | ||||||
3405 | throw lang::IndexOutOfBoundsException(); | ||||||
3406 | if(!IsValid()) | ||||||
3407 | throw uno::RuntimeException(); | ||||||
3408 | |||||||
3409 | uno::Reference< style::XAutoStyleFamily > aRef; | ||||||
3410 | IStyleAccess::SwAutoStyleFamily nType = aAutoStyleByIndex[nIndex]; | ||||||
3411 | switch( nType ) | ||||||
3412 | { | ||||||
3413 | case IStyleAccess::AUTO_STYLE_CHAR: | ||||||
3414 | { | ||||||
3415 | if(!m_xAutoCharStyles.is()) | ||||||
3416 | m_xAutoCharStyles = new SwXAutoStyleFamily(m_pDocShell, nType); | ||||||
3417 | aRef = m_xAutoCharStyles; | ||||||
3418 | } | ||||||
3419 | break; | ||||||
3420 | case IStyleAccess::AUTO_STYLE_RUBY: | ||||||
3421 | { | ||||||
3422 | if(!m_xAutoRubyStyles.is()) | ||||||
3423 | m_xAutoRubyStyles = new SwXAutoStyleFamily(m_pDocShell, nType ); | ||||||
3424 | aRef = m_xAutoRubyStyles; | ||||||
3425 | } | ||||||
3426 | break; | ||||||
3427 | case IStyleAccess::AUTO_STYLE_PARA: | ||||||
3428 | { | ||||||
3429 | if(!m_xAutoParaStyles.is()) | ||||||
3430 | m_xAutoParaStyles = new SwXAutoStyleFamily(m_pDocShell, nType ); | ||||||
3431 | aRef = m_xAutoParaStyles; | ||||||
3432 | } | ||||||
3433 | break; | ||||||
3434 | |||||||
3435 | default: | ||||||
3436 | ; | ||||||
3437 | } | ||||||
3438 | aRet <<= aRef; | ||||||
3439 | |||||||
3440 | return aRet; | ||||||
3441 | } | ||||||
3442 | |||||||
3443 | uno::Type SwXAutoStyles::getElementType( ) | ||||||
3444 | { | ||||||
3445 | return cppu::UnoType<style::XAutoStyleFamily>::get(); | ||||||
3446 | } | ||||||
3447 | |||||||
3448 | sal_Bool SwXAutoStyles::hasElements( ) | ||||||
3449 | { | ||||||
3450 | return true; | ||||||
3451 | } | ||||||
3452 | |||||||
3453 | uno::Any SwXAutoStyles::getByName(const OUString& Name) | ||||||
3454 | { | ||||||
3455 | uno::Any aRet; | ||||||
3456 | if(Name == "CharacterStyles") | ||||||
3457 | aRet = getByIndex(0); | ||||||
3458 | else if(Name == "RubyStyles") | ||||||
3459 | aRet = getByIndex(1); | ||||||
3460 | else if(Name == "ParagraphStyles") | ||||||
3461 | aRet = getByIndex(2); | ||||||
3462 | else | ||||||
3463 | throw container::NoSuchElementException(); | ||||||
3464 | return aRet; | ||||||
3465 | } | ||||||
3466 | |||||||
3467 | uno::Sequence< OUString > SwXAutoStyles::getElementNames() | ||||||
3468 | { | ||||||
3469 | uno::Sequence< OUString > aNames(AUTOSTYLE_FAMILY_COUNT3); | ||||||
3470 | OUString* pNames = aNames.getArray(); | ||||||
3471 | pNames[0] = "CharacterStyles"; | ||||||
3472 | pNames[1] = "RubyStyles"; | ||||||
3473 | pNames[2] = "ParagraphStyles"; | ||||||
3474 | return aNames; | ||||||
3475 | } | ||||||
3476 | |||||||
3477 | sal_Bool SwXAutoStyles::hasByName(const OUString& Name) | ||||||
3478 | { | ||||||
3479 | if( Name == "CharacterStyles" || | ||||||
3480 | Name == "RubyStyles" || | ||||||
3481 | Name == "ParagraphStyles" ) | ||||||
3482 | return true; | ||||||
3483 | else | ||||||
3484 | return false; | ||||||
3485 | } | ||||||
3486 | |||||||
3487 | SwXAutoStyleFamily::SwXAutoStyleFamily(SwDocShell* pDocSh, IStyleAccess::SwAutoStyleFamily nFamily) : | ||||||
3488 | m_pDocShell( pDocSh ), m_eFamily(nFamily) | ||||||
3489 | { | ||||||
3490 | // Register ourselves as a listener to the document (via the page descriptor) | ||||||
3491 | StartListening(pDocSh->GetDoc()->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier()); | ||||||
3492 | } | ||||||
3493 | |||||||
3494 | SwXAutoStyleFamily::~SwXAutoStyleFamily() | ||||||
3495 | { | ||||||
3496 | } | ||||||
3497 | |||||||
3498 | void SwXAutoStyleFamily::Notify(const SfxHint& rHint) | ||||||
3499 | { | ||||||
3500 | if(rHint.GetId() == SfxHintId::Dying) | ||||||
3501 | m_pDocShell = nullptr; | ||||||
3502 | } | ||||||
3503 | |||||||
3504 | uno::Reference< style::XAutoStyle > SwXAutoStyleFamily::insertStyle( | ||||||
3505 | const uno::Sequence< beans::PropertyValue >& Values ) | ||||||
3506 | { | ||||||
3507 | if (!m_pDocShell) | ||||||
3508 | { | ||||||
3509 | throw uno::RuntimeException(); | ||||||
3510 | } | ||||||
3511 | |||||||
3512 | const sal_uInt16* pRange = nullptr; | ||||||
3513 | const SfxItemPropertySet* pPropSet = nullptr; | ||||||
3514 | switch( m_eFamily ) | ||||||
3515 | { | ||||||
3516 | case IStyleAccess::AUTO_STYLE_CHAR: | ||||||
3517 | { | ||||||
3518 | pRange = aCharAutoFormatSetRange; | ||||||
3519 | pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE94); | ||||||
3520 | break; | ||||||
3521 | } | ||||||
3522 | case IStyleAccess::AUTO_STYLE_RUBY: | ||||||
3523 | { | ||||||
3524 | pRange = nullptr;//aTextNodeSetRange; | ||||||
3525 | pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_RUBY_AUTO_STYLE95); | ||||||
3526 | break; | ||||||
3527 | } | ||||||
3528 | case IStyleAccess::AUTO_STYLE_PARA: | ||||||
3529 | { | ||||||
3530 | pRange = aTextNodeSetRange; // checked, already added support for [XATTR_FILL_FIRST, XATTR_FILL_LAST] | ||||||
3531 | pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE96); | ||||||
3532 | break; | ||||||
3533 | } | ||||||
3534 | default: ; | ||||||
3535 | } | ||||||
3536 | |||||||
3537 | if( !pPropSet) | ||||||
3538 | throw uno::RuntimeException(); | ||||||
3539 | |||||||
3540 | SwAttrSet aSet( m_pDocShell->GetDoc()->GetAttrPool(), pRange ); | ||||||
3541 | const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == m_eFamily); | ||||||
3542 | |||||||
3543 | if(!bTakeCareOfDrawingLayerFillStyle) | ||||||
3544 | { | ||||||
3545 | for( const beans::PropertyValue& rValue : Values ) | ||||||
3546 | { | ||||||
3547 | try | ||||||
3548 | { | ||||||
3549 | pPropSet->setPropertyValue( rValue.Name, rValue.Value, aSet ); | ||||||
3550 | } | ||||||
3551 | catch (const beans::UnknownPropertyException &) | ||||||
3552 | { | ||||||
3553 | OSL_FAIL( "Unknown property" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3553" ": "), "%s", "Unknown property"); } } while (false ); | ||||||
3554 | } | ||||||
3555 | catch (const lang::IllegalArgumentException &) | ||||||
3556 | { | ||||||
3557 | OSL_FAIL( "Illegal argument" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3557" ": "), "%s", "Illegal argument"); } } while (false ); | ||||||
3558 | } | ||||||
3559 | } | ||||||
3560 | } | ||||||
3561 | else | ||||||
3562 | { | ||||||
3563 | // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem | ||||||
3564 | // to make cases in RES_BACKGROUND work correct; target *is* a style | ||||||
3565 | // where this is the case | ||||||
3566 | aSet.SetParent(&m_pDocShell->GetDoc()->GetDfltTextFormatColl()->GetAttrSet()); | ||||||
3567 | |||||||
3568 | // here the used DrawingLayer FillStyles are imported when family is | ||||||
3569 | // equal to IStyleAccess::AUTO_STYLE_PARA, thus we will need to serve the | ||||||
3570 | // used slots functionality here to do this correctly | ||||||
3571 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
3572 | |||||||
3573 | for( const beans::PropertyValue& rValue : Values ) | ||||||
3574 | { | ||||||
3575 | const OUString& rPropName = rValue.Name; | ||||||
3576 | uno::Any aValue(rValue.Value); | ||||||
3577 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropName); | ||||||
3578 | |||||||
3579 | if (!pEntry) | ||||||
3580 | { | ||||||
3581 | SAL_WARN("sw.core", "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.core")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3581" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3581" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3581" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3581" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3582 | continue; | ||||||
3583 | } | ||||||
3584 | |||||||
3585 | const sal_uInt8 nMemberId(pEntry->nMemberId); | ||||||
3586 | bool bDone(false); | ||||||
3587 | |||||||
3588 | // check for needed metric translation | ||||||
3589 | if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM) | ||||||
3590 | { | ||||||
3591 | bool bDoIt(true); | ||||||
3592 | |||||||
3593 | if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID) | ||||||
3594 | { | ||||||
3595 | // exception: If these ItemTypes are used, do not convert when these are negative | ||||||
3596 | // since this means they are intended as percent values | ||||||
3597 | sal_Int32 nValue = 0; | ||||||
3598 | |||||||
3599 | if(aValue >>= nValue) | ||||||
3600 | { | ||||||
3601 | bDoIt = nValue > 0; | ||||||
3602 | } | ||||||
3603 | } | ||||||
3604 | |||||||
3605 | if(bDoIt) | ||||||
3606 | { | ||||||
3607 | const SfxItemPool& rPool = m_pDocShell->GetDoc()->GetAttrPool(); | ||||||
3608 | const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID)); | ||||||
3609 | |||||||
3610 | if(eMapUnit != MapUnit::Map100thMM) | ||||||
3611 | { | ||||||
3612 | SvxUnoConvertFromMM(eMapUnit, aValue); | ||||||
3613 | } | ||||||
3614 | } | ||||||
3615 | } | ||||||
3616 | |||||||
3617 | switch(pEntry->nWID) | ||||||
3618 | { | ||||||
3619 | case XATTR_FILLGRADIENT: | ||||||
3620 | case XATTR_FILLHATCH: | ||||||
3621 | case XATTR_FILLBITMAP: | ||||||
3622 | case XATTR_FILLFLOATTRANSPARENCE: | ||||||
3623 | // not yet needed; activate when LineStyle support may be added | ||||||
3624 | // case XATTR_LINESTART: | ||||||
3625 | // case XATTR_LINEEND: | ||||||
3626 | // case XATTR_LINEDASH: | ||||||
3627 | { | ||||||
3628 | if(MID_NAME16 == nMemberId) | ||||||
3629 | { | ||||||
3630 | // add set commands for FillName items | ||||||
3631 | OUString aTempName; | ||||||
3632 | |||||||
3633 | if(!(aValue >>= aTempName)) | ||||||
3634 | { | ||||||
3635 | throw lang::IllegalArgumentException(); | ||||||
3636 | } | ||||||
3637 | |||||||
3638 | SvxShape::SetFillAttribute(pEntry->nWID, aTempName, aSet); | ||||||
3639 | bDone = true; | ||||||
3640 | } | ||||||
3641 | else if (MID_BITMAP8 == nMemberId) | ||||||
3642 | { | ||||||
3643 | if(XATTR_FILLBITMAP == pEntry->nWID) | ||||||
3644 | { | ||||||
3645 | const Graphic aNullGraphic; | ||||||
3646 | XFillBitmapItem aXFillBitmapItem(aNullGraphic); | ||||||
3647 | |||||||
3648 | aXFillBitmapItem.PutValue(aValue, nMemberId); | ||||||
3649 | aSet.Put(aXFillBitmapItem); | ||||||
3650 | bDone = true; | ||||||
3651 | } | ||||||
3652 | } | ||||||
3653 | |||||||
3654 | break; | ||||||
3655 | } | ||||||
3656 | case RES_BACKGROUND: | ||||||
3657 | { | ||||||
3658 | const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(aSet, RES_BACKGROUND, true, m_pDocShell->GetDoc()->IsInXMLImport())); | ||||||
3659 | std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone()); | ||||||
3660 | |||||||
3661 | aChangedBrushItem->PutValue(aValue, nMemberId); | ||||||
3662 | |||||||
3663 | if(*aChangedBrushItem != *aOriginalBrushItem) | ||||||
3664 | { | ||||||
3665 | setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, aSet); | ||||||
3666 | } | ||||||
3667 | |||||||
3668 | bDone = true; | ||||||
3669 | break; | ||||||
3670 | } | ||||||
3671 | case OWN_ATTR_FILLBMP_MODE(3900 +45): | ||||||
3672 | { | ||||||
3673 | drawing::BitmapMode eMode; | ||||||
3674 | |||||||
3675 | if(!(aValue >>= eMode)) | ||||||
3676 | { | ||||||
3677 | sal_Int32 nMode = 0; | ||||||
3678 | |||||||
3679 | if(!(aValue >>= nMode)) | ||||||
3680 | { | ||||||
3681 | throw lang::IllegalArgumentException(); | ||||||
3682 | } | ||||||
3683 | |||||||
3684 | eMode = static_cast<drawing::BitmapMode>(nMode); | ||||||
3685 | } | ||||||
3686 | |||||||
3687 | aSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode)); | ||||||
3688 | aSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode)); | ||||||
3689 | |||||||
3690 | bDone = true; | ||||||
3691 | break; | ||||||
3692 | } | ||||||
3693 | default: break; | ||||||
3694 | } | ||||||
3695 | |||||||
3696 | if(!bDone) | ||||||
3697 | { | ||||||
3698 | try | ||||||
3699 | { | ||||||
3700 | pPropSet->setPropertyValue( rPropName, aValue, aSet ); | ||||||
3701 | } | ||||||
3702 | catch (const beans::UnknownPropertyException &) | ||||||
3703 | { | ||||||
3704 | OSL_FAIL( "Unknown property" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3704" ": "), "%s", "Unknown property"); } } while (false ); | ||||||
3705 | } | ||||||
3706 | catch (const lang::IllegalArgumentException &) | ||||||
3707 | { | ||||||
3708 | OSL_FAIL( "Illegal argument" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3708" ": "), "%s", "Illegal argument"); } } while (false ); | ||||||
3709 | } | ||||||
3710 | } | ||||||
3711 | } | ||||||
3712 | |||||||
3713 | // clear parent again | ||||||
3714 | aSet.SetParent(nullptr); | ||||||
3715 | } | ||||||
3716 | |||||||
3717 | // need to ensure uniqueness of evtl. added NameOrIndex items | ||||||
3718 | // currently in principle only needed when bTakeCareOfDrawingLayerFillStyle, | ||||||
3719 | // but does not hurt and is easily forgotten later eventually, so keep it | ||||||
3720 | // as common case | ||||||
3721 | m_pDocShell->GetDoc()->CheckForUniqueItemForLineFillNameOrIndex(aSet); | ||||||
3722 | |||||||
3723 | // AutomaticStyle creation | ||||||
3724 | std::shared_ptr<SfxItemSet> pSet = m_pDocShell->GetDoc()->GetIStyleAccess().cacheAutomaticStyle( aSet, m_eFamily ); | ||||||
3725 | uno::Reference<style::XAutoStyle> xRet = new SwXAutoStyle(m_pDocShell->GetDoc(), pSet, m_eFamily); | ||||||
3726 | |||||||
3727 | return xRet; | ||||||
3728 | } | ||||||
3729 | |||||||
3730 | uno::Reference< container::XEnumeration > SwXAutoStyleFamily::createEnumeration( ) | ||||||
3731 | { | ||||||
3732 | if( !m_pDocShell ) | ||||||
3733 | throw uno::RuntimeException(); | ||||||
3734 | return uno::Reference< container::XEnumeration > | ||||||
3735 | (new SwXAutoStylesEnumerator( *m_pDocShell->GetDoc(), m_eFamily )); | ||||||
3736 | } | ||||||
3737 | |||||||
3738 | uno::Type SwXAutoStyleFamily::getElementType( ) | ||||||
3739 | { | ||||||
3740 | return cppu::UnoType<style::XAutoStyle>::get(); | ||||||
3741 | } | ||||||
3742 | |||||||
3743 | sal_Bool SwXAutoStyleFamily::hasElements( ) | ||||||
3744 | { | ||||||
3745 | return false; | ||||||
3746 | } | ||||||
3747 | |||||||
3748 | SwAutoStylesEnumImpl::SwAutoStylesEnumImpl( SwDoc& rInitDoc, IStyleAccess::SwAutoStyleFamily eFam ) | ||||||
3749 | : rDoc( rInitDoc ), eFamily( eFam ) | ||||||
3750 | { | ||||||
3751 | // special case for ruby auto styles: | ||||||
3752 | if ( IStyleAccess::AUTO_STYLE_RUBY == eFam ) | ||||||
3753 | { | ||||||
3754 | std::set< std::pair< sal_uInt16, text::RubyAdjust > > aRubyMap; | ||||||
3755 | SwAttrPool& rAttrPool = rDoc.GetAttrPool(); | ||||||
3756 | |||||||
3757 | // do this in two phases otherwise we invalidate the iterators when we insert into the pool | ||||||
3758 | std::vector<const SwFormatRuby*> vRubyItems; | ||||||
3759 | for (const SfxPoolItem* pItem : rAttrPool.GetItemSurrogates(RES_TXTATR_CJK_RUBY)) | ||||||
3760 | { | ||||||
3761 | auto pRubyItem = dynamic_cast<const SwFormatRuby*>(pItem); | ||||||
3762 | if ( pRubyItem && pRubyItem->GetTextRuby() ) | ||||||
3763 | vRubyItems.push_back(pRubyItem); | ||||||
3764 | } | ||||||
3765 | for (const SwFormatRuby* pRubyItem : vRubyItems) | ||||||
3766 | { | ||||||
3767 | std::pair< sal_uInt16, text::RubyAdjust > aPair( pRubyItem->GetPosition(), pRubyItem->GetAdjustment() ); | ||||||
3768 | if ( aRubyMap.insert( aPair ).second ) | ||||||
3769 | { | ||||||
3770 | auto pItemSet = std::make_shared<SfxItemSet>( rAttrPool, svl::Items<RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY>{} ); | ||||||
3771 | pItemSet->Put( *pRubyItem ); | ||||||
3772 | mAutoStyles.push_back( pItemSet ); | ||||||
3773 | } | ||||||
3774 | } | ||||||
3775 | } | ||||||
3776 | else | ||||||
3777 | { | ||||||
3778 | rDoc.GetIStyleAccess().getAllStyles( mAutoStyles, eFamily ); | ||||||
3779 | } | ||||||
3780 | |||||||
3781 | aIter = mAutoStyles.begin(); | ||||||
3782 | } | ||||||
3783 | |||||||
3784 | SwXAutoStylesEnumerator::SwXAutoStylesEnumerator( SwDoc& rDoc, IStyleAccess::SwAutoStyleFamily eFam ) | ||||||
3785 | : m_pImpl( new SwAutoStylesEnumImpl( rDoc, eFam ) ) | ||||||
3786 | { | ||||||
3787 | // Register ourselves as a listener to the document (via the page descriptor) | ||||||
3788 | StartListening(rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier()); | ||||||
3789 | } | ||||||
3790 | |||||||
3791 | SwXAutoStylesEnumerator::~SwXAutoStylesEnumerator() | ||||||
3792 | { | ||||||
3793 | } | ||||||
3794 | |||||||
3795 | void SwXAutoStylesEnumerator::Notify( const SfxHint& rHint) | ||||||
3796 | { | ||||||
3797 | if(rHint.GetId() == SfxHintId::Dying) | ||||||
3798 | m_pImpl.reset(); | ||||||
3799 | } | ||||||
3800 | |||||||
3801 | sal_Bool SwXAutoStylesEnumerator::hasMoreElements( ) | ||||||
3802 | { | ||||||
3803 | if( !m_pImpl ) | ||||||
3804 | throw uno::RuntimeException(); | ||||||
3805 | return m_pImpl->hasMoreElements(); | ||||||
3806 | } | ||||||
3807 | |||||||
3808 | uno::Any SwXAutoStylesEnumerator::nextElement( ) | ||||||
3809 | { | ||||||
3810 | if( !m_pImpl ) | ||||||
3811 | throw uno::RuntimeException(); | ||||||
3812 | uno::Any aRet; | ||||||
3813 | if( m_pImpl->hasMoreElements() ) | ||||||
3814 | { | ||||||
3815 | std::shared_ptr<SfxItemSet> pNextSet = m_pImpl->nextElement(); | ||||||
3816 | uno::Reference< style::XAutoStyle > xAutoStyle = new SwXAutoStyle(&m_pImpl->getDoc(), | ||||||
3817 | pNextSet, m_pImpl->getFamily()); | ||||||
3818 | aRet <<= xAutoStyle; | ||||||
3819 | } | ||||||
3820 | return aRet; | ||||||
3821 | } | ||||||
3822 | |||||||
3823 | // SwXAutoStyle with the family IStyleAccess::AUTO_STYLE_PARA (or | ||||||
3824 | // PROPERTY_MAP_PARA_AUTO_STYLE) now uses DrawingLayer FillStyles to allow | ||||||
3825 | // unified paragraph background fill, thus the UNO API implementation has to | ||||||
3826 | // support the needed slots for these. This seems to be used only for reading | ||||||
3827 | // (no setPropertyValue implementation here), so maybe specialized for saving | ||||||
3828 | // the Writer Doc to ODF | ||||||
3829 | |||||||
3830 | SwXAutoStyle::SwXAutoStyle( | ||||||
3831 | SwDoc* pDoc, | ||||||
3832 | std::shared_ptr<SfxItemSet> const & pInitSet, | ||||||
3833 | IStyleAccess::SwAutoStyleFamily eFam) | ||||||
3834 | : mpSet(pInitSet), | ||||||
3835 | meFamily(eFam), | ||||||
3836 | mrDoc(*pDoc) | ||||||
3837 | { | ||||||
3838 | // Register ourselves as a listener to the document (via the page descriptor) | ||||||
3839 | //StartListening(mrDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier()); | ||||||
3840 | } | ||||||
3841 | |||||||
3842 | SwXAutoStyle::~SwXAutoStyle() | ||||||
3843 | { | ||||||
3844 | } | ||||||
3845 | |||||||
3846 | void SwXAutoStyle::Notify(const SfxHint& rHint) | ||||||
3847 | { | ||||||
3848 | if(rHint.GetId() == SfxHintId::Dying) | ||||||
3849 | mpSet.reset(); | ||||||
3850 | } | ||||||
3851 | |||||||
3852 | uno::Reference< beans::XPropertySetInfo > SwXAutoStyle::getPropertySetInfo( ) | ||||||
3853 | { | ||||||
3854 | uno::Reference< beans::XPropertySetInfo > xRet; | ||||||
3855 | switch( meFamily ) | ||||||
3856 | { | ||||||
3857 | case IStyleAccess::AUTO_STYLE_CHAR: | ||||||
3858 | { | ||||||
3859 | static uno::Reference< beans::XPropertySetInfo > xCharRef; | ||||||
3860 | if(!xCharRef.is()) | ||||||
3861 | { | ||||||
3862 | xCharRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE94)->getPropertySetInfo(); | ||||||
3863 | } | ||||||
3864 | xRet = xCharRef; | ||||||
3865 | } | ||||||
3866 | break; | ||||||
3867 | case IStyleAccess::AUTO_STYLE_RUBY: | ||||||
3868 | { | ||||||
3869 | static uno::Reference< beans::XPropertySetInfo > xRubyRef; | ||||||
3870 | if(!xRubyRef.is()) | ||||||
3871 | { | ||||||
3872 | const sal_uInt16 nMapId = PROPERTY_MAP_RUBY_AUTO_STYLE95; | ||||||
3873 | xRubyRef = aSwMapProvider.GetPropertySet(nMapId)->getPropertySetInfo(); | ||||||
3874 | } | ||||||
3875 | xRet = xRubyRef; | ||||||
3876 | } | ||||||
3877 | break; | ||||||
3878 | case IStyleAccess::AUTO_STYLE_PARA: | ||||||
3879 | { | ||||||
3880 | static uno::Reference< beans::XPropertySetInfo > xParaRef; | ||||||
3881 | if(!xParaRef.is()) | ||||||
3882 | { | ||||||
3883 | const sal_uInt16 nMapId = PROPERTY_MAP_PARA_AUTO_STYLE96; | ||||||
3884 | xParaRef = aSwMapProvider.GetPropertySet(nMapId)->getPropertySetInfo(); | ||||||
3885 | } | ||||||
3886 | xRet = xParaRef; | ||||||
3887 | } | ||||||
3888 | break; | ||||||
3889 | |||||||
3890 | default: | ||||||
3891 | ; | ||||||
3892 | } | ||||||
3893 | |||||||
3894 | return xRet; | ||||||
3895 | } | ||||||
3896 | |||||||
3897 | void SwXAutoStyle::setPropertyValue( const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ ) | ||||||
3898 | { | ||||||
3899 | } | ||||||
3900 | |||||||
3901 | uno::Any SwXAutoStyle::getPropertyValue( const OUString& rPropertyName ) | ||||||
3902 | { | ||||||
3903 | SolarMutexGuard aGuard; | ||||||
3904 | const uno::Sequence<OUString> aProperties(&rPropertyName, 1); | ||||||
3905 | return GetPropertyValues_Impl(aProperties).getConstArray()[0]; | ||||||
3906 | } | ||||||
3907 | |||||||
3908 | void SwXAutoStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/, | ||||||
3909 | const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ ) | ||||||
3910 | { | ||||||
3911 | } | ||||||
3912 | |||||||
3913 | void SwXAutoStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/, | ||||||
3914 | const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ ) | ||||||
3915 | { | ||||||
3916 | } | ||||||
3917 | |||||||
3918 | void SwXAutoStyle::addVetoableChangeListener( const OUString& /*PropertyName*/, | ||||||
3919 | const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) | ||||||
3920 | { | ||||||
3921 | } | ||||||
3922 | |||||||
3923 | void SwXAutoStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/, | ||||||
3924 | const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) | ||||||
3925 | { | ||||||
3926 | } | ||||||
3927 | |||||||
3928 | void SwXAutoStyle::setPropertyValues( | ||||||
3929 | const uno::Sequence< OUString >& /*aPropertyNames*/, | ||||||
3930 | const uno::Sequence< uno::Any >& /*aValues*/ ) | ||||||
3931 | { | ||||||
3932 | } | ||||||
3933 | |||||||
3934 | uno::Sequence< uno::Any > SwXAutoStyle::GetPropertyValues_Impl( | ||||||
3935 | const uno::Sequence< OUString > & rPropertyNames ) | ||||||
3936 | { | ||||||
3937 | if( !mpSet ) | ||||||
3938 | { | ||||||
3939 | throw uno::RuntimeException(); | ||||||
3940 | } | ||||||
3941 | |||||||
3942 | // query_item | ||||||
3943 | sal_Int8 nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE94; | ||||||
3944 | switch(meFamily) | ||||||
3945 | { | ||||||
3946 | case IStyleAccess::AUTO_STYLE_CHAR : nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE94; break; | ||||||
3947 | case IStyleAccess::AUTO_STYLE_RUBY : nPropSetId = PROPERTY_MAP_RUBY_AUTO_STYLE95; break; | ||||||
3948 | case IStyleAccess::AUTO_STYLE_PARA : nPropSetId = PROPERTY_MAP_PARA_AUTO_STYLE96; break; | ||||||
3949 | default: ; | ||||||
3950 | } | ||||||
3951 | |||||||
3952 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
3953 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
3954 | const OUString* pNames = rPropertyNames.getConstArray(); | ||||||
3955 | |||||||
3956 | const sal_Int32 nLen(rPropertyNames.getLength()); | ||||||
3957 | uno::Sequence< uno::Any > aRet( nLen ); | ||||||
3958 | uno::Any* pValues = aRet.getArray(); | ||||||
3959 | const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == meFamily); | ||||||
3960 | |||||||
3961 | for( sal_Int32 i = 0; i < nLen; ++i ) | ||||||
3962 | { | ||||||
3963 | const OUString sPropName = pNames[i]; | ||||||
3964 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(sPropName); | ||||||
3965 | if(!pEntry) | ||||||
3966 | { | ||||||
3967 | throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast < cppu::OWeakObject * > ( this ) ); | ||||||
3968 | } | ||||||
3969 | |||||||
3970 | uno::Any aTarget; | ||||||
3971 | bool bDone(false); | ||||||
3972 | |||||||
3973 | if ( RES_TXTATR_AUTOFMT == pEntry->nWID || RES_AUTO_STYLE == pEntry->nWID ) | ||||||
3974 | { | ||||||
3975 | OUString sName(StylePool::nameOf( mpSet )); | ||||||
3976 | aTarget <<= sName; | ||||||
3977 | bDone = true; | ||||||
3978 | } | ||||||
3979 | else if(bTakeCareOfDrawingLayerFillStyle) | ||||||
3980 | { | ||||||
3981 | // add support for DrawingLayer FillStyle slots | ||||||
3982 | switch(pEntry->nWID) | ||||||
3983 | { | ||||||
3984 | case RES_BACKGROUND: | ||||||
3985 | { | ||||||
3986 | const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(*mpSet, RES_BACKGROUND)); | ||||||
3987 | |||||||
3988 | if(!aOriginalBrushItem->QueryValue(aTarget, pEntry->nMemberId)) | ||||||
3989 | { | ||||||
3990 | OSL_ENSURE(false, "Error getting attribute from RES_BACKGROUND (!)")do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "3990" ": "), "%s", "Error getting attribute from RES_BACKGROUND (!)" ); } } while (false); | ||||||
3991 | } | ||||||
3992 | |||||||
3993 | bDone = true; | ||||||
3994 | break; | ||||||
3995 | } | ||||||
3996 | case OWN_ATTR_FILLBMP_MODE(3900 +45): | ||||||
3997 | { | ||||||
3998 | if (mpSet->Get(XATTR_FILLBMP_TILE).GetValue()) | ||||||
3999 | { | ||||||
4000 | aTarget <<= drawing::BitmapMode_REPEAT; | ||||||
4001 | } | ||||||
4002 | else if (mpSet->Get(XATTR_FILLBMP_STRETCH).GetValue()) | ||||||
4003 | { | ||||||
4004 | aTarget <<= drawing::BitmapMode_STRETCH; | ||||||
4005 | } | ||||||
4006 | else | ||||||
4007 | { | ||||||
4008 | aTarget <<= drawing::BitmapMode_NO_REPEAT; | ||||||
4009 | } | ||||||
4010 | |||||||
4011 | bDone = true; | ||||||
4012 | break; | ||||||
4013 | } | ||||||
4014 | } | ||||||
4015 | } | ||||||
4016 | |||||||
4017 | if(!bDone) | ||||||
4018 | { | ||||||
4019 | pPropSet->getPropertyValue( *pEntry, *mpSet, aTarget ); | ||||||
4020 | } | ||||||
4021 | |||||||
4022 | if(bTakeCareOfDrawingLayerFillStyle) | ||||||
4023 | { | ||||||
4024 | if(pEntry->aType == cppu::UnoType<sal_Int16>::get() && pEntry->aType != aTarget.getValueType()) | ||||||
4025 | { | ||||||
4026 | // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here | ||||||
4027 | sal_Int32 nValue = 0; | ||||||
4028 | if (aTarget >>= nValue) | ||||||
4029 | { | ||||||
4030 | aTarget <<= static_cast<sal_Int16>(nValue); | ||||||
4031 | } | ||||||
4032 | } | ||||||
4033 | |||||||
4034 | // check for needed metric translation | ||||||
4035 | if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM) | ||||||
4036 | { | ||||||
4037 | bool bDoIt(true); | ||||||
4038 | |||||||
4039 | if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID) | ||||||
4040 | { | ||||||
4041 | // exception: If these ItemTypes are used, do not convert when these are negative | ||||||
4042 | // since this means they are intended as percent values | ||||||
4043 | sal_Int32 nValue = 0; | ||||||
4044 | |||||||
4045 | if(aTarget >>= nValue) | ||||||
4046 | { | ||||||
4047 | bDoIt = nValue > 0; | ||||||
4048 | } | ||||||
4049 | } | ||||||
4050 | |||||||
4051 | if(bDoIt) | ||||||
4052 | { | ||||||
4053 | const SfxItemPool& rPool = mrDoc.GetAttrPool(); | ||||||
4054 | const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID)); | ||||||
4055 | |||||||
4056 | if(eMapUnit != MapUnit::Map100thMM) | ||||||
4057 | { | ||||||
4058 | SvxUnoConvertToMM(eMapUnit, aTarget); | ||||||
4059 | } | ||||||
4060 | } | ||||||
4061 | } | ||||||
4062 | } | ||||||
4063 | |||||||
4064 | // add value | ||||||
4065 | pValues[i] = aTarget; | ||||||
4066 | } | ||||||
4067 | |||||||
4068 | return aRet; | ||||||
4069 | } | ||||||
4070 | |||||||
4071 | uno::Sequence< uno::Any > SwXAutoStyle::getPropertyValues ( | ||||||
4072 | const uno::Sequence< OUString >& rPropertyNames ) | ||||||
4073 | { | ||||||
4074 | SolarMutexGuard aGuard; | ||||||
4075 | uno::Sequence< uno::Any > aValues; | ||||||
4076 | |||||||
4077 | // workaround for bad designed API | ||||||
4078 | try | ||||||
4079 | { | ||||||
4080 | aValues = GetPropertyValues_Impl( rPropertyNames ); | ||||||
4081 | } | ||||||
4082 | catch (beans::UnknownPropertyException &) | ||||||
4083 | { | ||||||
4084 | css::uno::Any exc = cppu::getCaughtException(); | ||||||
4085 | throw lang::WrappedTargetRuntimeException("Unknown property exception caught", static_cast < cppu::OWeakObject * > ( this ), exc ); | ||||||
4086 | } | ||||||
4087 | catch (lang::WrappedTargetException &) | ||||||
4088 | { | ||||||
4089 | css::uno::Any exc = cppu::getCaughtException(); | ||||||
4090 | throw lang::WrappedTargetRuntimeException("WrappedTargetException caught", static_cast < cppu::OWeakObject * > ( this ), exc ); | ||||||
4091 | } | ||||||
4092 | |||||||
4093 | return aValues; | ||||||
4094 | } | ||||||
4095 | |||||||
4096 | void SwXAutoStyle::addPropertiesChangeListener( | ||||||
4097 | const uno::Sequence< OUString >& /*aPropertyNames*/, | ||||||
4098 | const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ ) | ||||||
4099 | { | ||||||
4100 | } | ||||||
4101 | |||||||
4102 | void SwXAutoStyle::removePropertiesChangeListener( | ||||||
4103 | const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ ) | ||||||
4104 | { | ||||||
4105 | } | ||||||
4106 | |||||||
4107 | void SwXAutoStyle::firePropertiesChangeEvent( | ||||||
4108 | const uno::Sequence< OUString >& /*aPropertyNames*/, | ||||||
4109 | const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ ) | ||||||
4110 | { | ||||||
4111 | } | ||||||
4112 | |||||||
4113 | beans::PropertyState SwXAutoStyle::getPropertyState( const OUString& rPropertyName ) | ||||||
4114 | { | ||||||
4115 | SolarMutexGuard aGuard; | ||||||
4116 | |||||||
4117 | uno::Sequence< OUString > aNames { rPropertyName }; | ||||||
4118 | uno::Sequence< beans::PropertyState > aStates = getPropertyStates(aNames); | ||||||
4119 | return aStates.getConstArray()[0]; | ||||||
4120 | } | ||||||
4121 | |||||||
4122 | void SwXAutoStyle::setPropertyToDefault( const OUString& /*PropertyName*/ ) | ||||||
4123 | { | ||||||
4124 | } | ||||||
4125 | |||||||
4126 | uno::Any SwXAutoStyle::getPropertyDefault( const OUString& rPropertyName ) | ||||||
4127 | { | ||||||
4128 | const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 ); | ||||||
4129 | return getPropertyDefaults ( aSequence ).getConstArray()[0]; | ||||||
4130 | } | ||||||
4131 | |||||||
4132 | uno::Sequence< beans::PropertyState > SwXAutoStyle::getPropertyStates( | ||||||
4133 | const uno::Sequence< OUString >& rPropertyNames ) | ||||||
4134 | { | ||||||
4135 | if (!mpSet) | ||||||
4136 | { | ||||||
4137 | throw uno::RuntimeException(); | ||||||
4138 | } | ||||||
4139 | |||||||
4140 | SolarMutexGuard aGuard; | ||||||
4141 | uno::Sequence< beans::PropertyState > aRet(rPropertyNames.getLength()); | ||||||
4142 | beans::PropertyState* pStates = aRet.getArray(); | ||||||
4143 | const OUString* pNames = rPropertyNames.getConstArray(); | ||||||
4144 | |||||||
4145 | sal_Int8 nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE94; | ||||||
4146 | switch(meFamily) | ||||||
4147 | { | ||||||
4148 | case IStyleAccess::AUTO_STYLE_CHAR : nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE94; break; | ||||||
4149 | case IStyleAccess::AUTO_STYLE_RUBY : nPropSetId = PROPERTY_MAP_RUBY_AUTO_STYLE95; break; | ||||||
4150 | case IStyleAccess::AUTO_STYLE_PARA : nPropSetId = PROPERTY_MAP_PARA_AUTO_STYLE96; break; | ||||||
4151 | default: ; | ||||||
4152 | } | ||||||
4153 | |||||||
4154 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
4155 | const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap(); | ||||||
4156 | const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == meFamily); | ||||||
4157 | |||||||
4158 | for(sal_Int32 i = 0; i < rPropertyNames.getLength(); i++) | ||||||
4159 | { | ||||||
4160 | const OUString sPropName = pNames[i]; | ||||||
4161 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(sPropName); | ||||||
4162 | if(!pEntry) | ||||||
4163 | { | ||||||
4164 | throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast < cppu::OWeakObject * > ( this ) ); | ||||||
4165 | } | ||||||
4166 | |||||||
4167 | bool bDone(false); | ||||||
4168 | |||||||
4169 | if(bTakeCareOfDrawingLayerFillStyle) | ||||||
4170 | { | ||||||
4171 | // DrawingLayer PropertyStyle support | ||||||
4172 | switch(pEntry->nWID) | ||||||
4173 | { | ||||||
4174 | case OWN_ATTR_FILLBMP_MODE(3900 +45): | ||||||
4175 | { | ||||||
4176 | if(SfxItemState::SET == mpSet->GetItemState(XATTR_FILLBMP_STRETCH, false) | ||||||
4177 | || SfxItemState::SET == mpSet->GetItemState(XATTR_FILLBMP_TILE, false)) | ||||||
4178 | { | ||||||
4179 | pStates[i] = beans::PropertyState_DIRECT_VALUE; | ||||||
4180 | } | ||||||
4181 | else | ||||||
4182 | { | ||||||
4183 | pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE; | ||||||
4184 | } | ||||||
4185 | |||||||
4186 | bDone = true; | ||||||
4187 | break; | ||||||
4188 | } | ||||||
4189 | case RES_BACKGROUND: | ||||||
4190 | { | ||||||
4191 | if (SWUnoHelper::needToMapFillItemsToSvxBrushItemTypes(*mpSet, | ||||||
4192 | pEntry->nMemberId)) | ||||||
4193 | { | ||||||
4194 | pStates[i] = beans::PropertyState_DIRECT_VALUE; | ||||||
4195 | } | ||||||
4196 | else | ||||||
4197 | { | ||||||
4198 | pStates[i] = beans::PropertyState_DEFAULT_VALUE; | ||||||
4199 | } | ||||||
4200 | bDone = true; | ||||||
4201 | |||||||
4202 | break; | ||||||
4203 | } | ||||||
4204 | } | ||||||
4205 | } | ||||||
4206 | |||||||
4207 | if(!bDone) | ||||||
4208 | { | ||||||
4209 | pStates[i] = pPropSet->getPropertyState(*pEntry, *mpSet ); | ||||||
4210 | } | ||||||
4211 | } | ||||||
4212 | |||||||
4213 | return aRet; | ||||||
4214 | } | ||||||
4215 | |||||||
4216 | void SwXAutoStyle::setAllPropertiesToDefault( ) | ||||||
4217 | { | ||||||
4218 | } | ||||||
4219 | |||||||
4220 | void SwXAutoStyle::setPropertiesToDefault( | ||||||
4221 | const uno::Sequence< OUString >& /*rPropertyNames*/ ) | ||||||
4222 | { | ||||||
4223 | } | ||||||
4224 | |||||||
4225 | uno::Sequence< uno::Any > SwXAutoStyle::getPropertyDefaults( | ||||||
4226 | const uno::Sequence< OUString >& /*aPropertyNames*/ ) | ||||||
4227 | { | ||||||
4228 | uno::Sequence< uno::Any > aRet(0); | ||||||
4229 | return aRet; | ||||||
4230 | } | ||||||
4231 | |||||||
4232 | uno::Sequence< beans::PropertyValue > SwXAutoStyle::getProperties() | ||||||
4233 | { | ||||||
4234 | if( !mpSet ) | ||||||
4235 | throw uno::RuntimeException(); | ||||||
4236 | SolarMutexGuard aGuard; | ||||||
4237 | std::vector< beans::PropertyValue > aPropertyVector; | ||||||
4238 | |||||||
4239 | sal_Int8 nPropSetId = 0; | ||||||
4240 | switch(meFamily) | ||||||
4241 | { | ||||||
4242 | case IStyleAccess::AUTO_STYLE_CHAR : nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE94; break; | ||||||
4243 | case IStyleAccess::AUTO_STYLE_RUBY : nPropSetId = PROPERTY_MAP_RUBY_AUTO_STYLE95; break; | ||||||
4244 | case IStyleAccess::AUTO_STYLE_PARA : nPropSetId = PROPERTY_MAP_PARA_AUTO_STYLE96; break; | ||||||
4245 | default: ; | ||||||
4246 | } | ||||||
4247 | |||||||
4248 | const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId); | ||||||
4249 | const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap(); | ||||||
4250 | PropertyEntryVector_t aPropVector = rMap.getPropertyEntries(); | ||||||
4251 | |||||||
4252 | SfxItemSet& rSet = *mpSet; | ||||||
4253 | SfxItemIter aIter(rSet); | ||||||
4254 | |||||||
4255 | for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem()) | ||||||
4256 | { | ||||||
4257 | const sal_uInt16 nWID = pItem->Which(); | ||||||
4258 | |||||||
4259 | // TODO: Optimize - and fix! the old iteration filled each WhichId | ||||||
4260 | // only once but there are more properties than WhichIds | ||||||
4261 | for( const auto& rProp : aPropVector ) | ||||||
4262 | { | ||||||
4263 | if ( rProp.nWID == nWID ) | ||||||
4264 | { | ||||||
4265 | beans::PropertyValue aPropertyValue; | ||||||
4266 | aPropertyValue.Name = rProp.sName; | ||||||
4267 | pItem->QueryValue( aPropertyValue.Value, rProp.nMemberId ); | ||||||
4268 | aPropertyVector.push_back( aPropertyValue ); | ||||||
4269 | } | ||||||
4270 | } | ||||||
4271 | } | ||||||
4272 | |||||||
4273 | const sal_Int32 nCount = aPropertyVector.size(); | ||||||
4274 | uno::Sequence< beans::PropertyValue > aRet( nCount ); | ||||||
4275 | beans::PropertyValue* pProps = aRet.getArray(); | ||||||
4276 | |||||||
4277 | for ( int i = 0; i < nCount; ++i, pProps++ ) | ||||||
4278 | { | ||||||
4279 | *pProps = aPropertyVector[i]; | ||||||
4280 | } | ||||||
4281 | |||||||
4282 | return aRet; | ||||||
4283 | } | ||||||
4284 | |||||||
4285 | SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, SwTableAutoFormat* pTableAutoFormat) : | ||||||
4286 | m_pDocShell(pDocShell), m_pTableAutoFormat(pTableAutoFormat), m_bPhysical(true) | ||||||
4287 | { | ||||||
4288 | UpdateCellStylesMapping(); | ||||||
4289 | } | ||||||
4290 | |||||||
4291 | SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName) : | ||||||
4292 | m_pDocShell(pDocShell), m_pTableAutoFormat_Impl(new SwTableAutoFormat(rTableAutoFormatName)), m_bPhysical(false) | ||||||
4293 | { | ||||||
4294 | m_pTableAutoFormat = m_pTableAutoFormat_Impl.get(); | ||||||
4295 | UpdateCellStylesMapping(); | ||||||
4296 | } | ||||||
4297 | |||||||
4298 | uno::Reference<style::XStyle> SwXTextTableStyle::CreateXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName) | ||||||
4299 | { | ||||||
4300 | SolarMutexGuard aGuard; | ||||||
4301 | uno::Reference<style::XStyle> xTextTableStyle; | ||||||
4302 | SwTableAutoFormat* pAutoFormat = GetTableAutoFormat(pDocShell, rTableAutoFormatName); | ||||||
4303 | if (pAutoFormat && pAutoFormat->GetName() == rTableAutoFormatName) | ||||||
4304 | { | ||||||
4305 | xTextTableStyle.set(pAutoFormat->GetXObject(), uno::UNO_QUERY); | ||||||
4306 | if (!xTextTableStyle.is()) | ||||||
4307 | { | ||||||
4308 | xTextTableStyle.set(new SwXTextTableStyle(pDocShell, pAutoFormat)); | ||||||
4309 | pAutoFormat->SetXObject(xTextTableStyle); | ||||||
4310 | } | ||||||
4311 | } | ||||||
4312 | |||||||
4313 | // If corresponding AutoFormat doesn't exist create a non physical style. | ||||||
4314 | if (!xTextTableStyle.is()) | ||||||
4315 | { | ||||||
4316 | xTextTableStyle.set(new SwXTextTableStyle(pDocShell, rTableAutoFormatName)); | ||||||
4317 | SAL_INFO("sw.uno", "creating SwXTextTableStyle for non existing SwTableAutoFormat")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "creating SwXTextTableStyle for non existing SwTableAutoFormat" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4317" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "creating SwXTextTableStyle for non existing SwTableAutoFormat" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "creating SwXTextTableStyle for non existing SwTableAutoFormat" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4317" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "creating SwXTextTableStyle for non existing SwTableAutoFormat" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4317" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "creating SwXTextTableStyle for non existing SwTableAutoFormat" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "creating SwXTextTableStyle for non existing SwTableAutoFormat" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4317" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4318 | } | ||||||
4319 | |||||||
4320 | return xTextTableStyle; | ||||||
4321 | } | ||||||
4322 | |||||||
4323 | void SwXTextTableStyle::UpdateCellStylesMapping() | ||||||
4324 | { | ||||||
4325 | const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap(); | ||||||
4326 | assert(aTableTemplateMap.size() == STYLE_COUNT && "can not map SwTableAutoFormat to a SwXTextTableStyle")(static_cast <bool> (aTableTemplateMap.size() == STYLE_COUNT && "can not map SwTableAutoFormat to a SwXTextTableStyle" ) ? void (0) : __assert_fail ("aTableTemplateMap.size() == STYLE_COUNT && \"can not map SwTableAutoFormat to a SwXTextTableStyle\"" , "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" , 4326, __extension__ __PRETTY_FUNCTION__)); | ||||||
4327 | for (sal_Int32 i=0; i<STYLE_COUNT; ++i) | ||||||
4328 | { | ||||||
4329 | SwBoxAutoFormat* pBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]); | ||||||
4330 | uno::Reference<style::XStyle> xCellStyle(pBoxFormat->GetXObject(), uno::UNO_QUERY); | ||||||
4331 | if (!xCellStyle.is()) | ||||||
4332 | { | ||||||
4333 | xCellStyle.set(new SwXTextCellStyle(m_pDocShell, pBoxFormat, m_pTableAutoFormat->GetName())); | ||||||
4334 | pBoxFormat->SetXObject(xCellStyle); | ||||||
4335 | } | ||||||
4336 | m_aCellStyles[i] = xCellStyle; | ||||||
4337 | } | ||||||
4338 | } | ||||||
4339 | |||||||
4340 | const CellStyleNameMap& SwXTextTableStyle::GetCellStyleNameMap() | ||||||
4341 | { | ||||||
4342 | static CellStyleNameMap const aMap | ||||||
4343 | { | ||||||
4344 | { "first-row" , FIRST_ROW_STYLE }, | ||||||
4345 | { "last-row" , LAST_ROW_STYLE }, | ||||||
4346 | { "first-column" , FIRST_COLUMN_STYLE }, | ||||||
4347 | { "last-column" , LAST_COLUMN_STYLE }, | ||||||
4348 | { "body" , BODY_STYLE }, | ||||||
4349 | { "even-rows" , EVEN_ROWS_STYLE }, | ||||||
4350 | { "odd-rows" , ODD_ROWS_STYLE }, | ||||||
4351 | { "even-columns" , EVEN_COLUMNS_STYLE }, | ||||||
4352 | { "odd-columns" , ODD_COLUMNS_STYLE }, | ||||||
4353 | { "background" , BACKGROUND_STYLE }, | ||||||
4354 | // loext namespace | ||||||
4355 | { "first-row-start-column" , FIRST_ROW_START_COLUMN_STYLE }, | ||||||
4356 | { "first-row-end-column" , FIRST_ROW_END_COLUMN_STYLE }, | ||||||
4357 | { "last-row-start-column" , LAST_ROW_START_COLUMN_STYLE }, | ||||||
4358 | { "last-row-end-column" , LAST_ROW_END_COLUMN_STYLE }, | ||||||
4359 | { "first-row-even-column" , FIRST_ROW_EVEN_COLUMN_STYLE }, | ||||||
4360 | { "last-row-even-column" , LAST_ROW_EVEN_COLUMN_STYLE }, | ||||||
4361 | }; | ||||||
4362 | return aMap; | ||||||
4363 | } | ||||||
4364 | |||||||
4365 | SwTableAutoFormat* SwXTextTableStyle::GetTableFormat() | ||||||
4366 | { | ||||||
4367 | return m_pTableAutoFormat; | ||||||
4368 | } | ||||||
4369 | |||||||
4370 | SwTableAutoFormat* SwXTextTableStyle::GetTableAutoFormat(SwDocShell* pDocShell, const OUString& sName) | ||||||
4371 | { | ||||||
4372 | const size_t nStyles = pDocShell->GetDoc()->GetTableStyles().size(); | ||||||
4373 | for(size_t i=0; i < nStyles; ++i) | ||||||
4374 | { | ||||||
4375 | SwTableAutoFormat* pAutoFormat = &pDocShell->GetDoc()->GetTableStyles()[i]; | ||||||
4376 | if (pAutoFormat->GetName() == sName) | ||||||
4377 | { | ||||||
4378 | return pAutoFormat; | ||||||
4379 | } | ||||||
4380 | } | ||||||
4381 | // not found | ||||||
4382 | return nullptr; | ||||||
4383 | } | ||||||
4384 | |||||||
4385 | void SwXTextTableStyle::SetPhysical() | ||||||
4386 | { | ||||||
4387 | if (!m_bPhysical) | ||||||
4388 | { | ||||||
4389 | // find table format in doc | ||||||
4390 | SwTableAutoFormat* pTableAutoFormat = GetTableAutoFormat(m_pDocShell, m_pTableAutoFormat->GetName()); | ||||||
4391 | if (pTableAutoFormat) | ||||||
4392 | { | ||||||
4393 | m_bPhysical = true; | ||||||
4394 | /// take care of children, make SwXTextCellStyles use new core SwBoxAutoFormats | ||||||
4395 | const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap(); | ||||||
4396 | for (size_t i=0; i<aTableTemplateMap.size(); ++i) | ||||||
4397 | { | ||||||
4398 | SwBoxAutoFormat* pOldBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]); | ||||||
4399 | uno::Reference<style::XStyle> xCellStyle(pOldBoxFormat->GetXObject(), uno::UNO_QUERY); | ||||||
4400 | if (!xCellStyle.is()) | ||||||
4401 | continue; | ||||||
4402 | SwXTextCellStyle& rStyle = dynamic_cast<SwXTextCellStyle&>(*xCellStyle); | ||||||
4403 | SwBoxAutoFormat& rNewBoxFormat = pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]); | ||||||
4404 | rStyle.SetBoxFormat(&rNewBoxFormat); | ||||||
4405 | rNewBoxFormat.SetXObject(xCellStyle); | ||||||
4406 | } | ||||||
4407 | m_pTableAutoFormat_Impl = nullptr; | ||||||
4408 | m_pTableAutoFormat = pTableAutoFormat; | ||||||
4409 | m_pTableAutoFormat->SetXObject(uno::Reference<style::XStyle>(this)); | ||||||
4410 | } | ||||||
4411 | else | ||||||
4412 | SAL_WARN("sw.uno", "setting style physical, but SwTableAutoFormat in document not found")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "setting style physical, but SwTableAutoFormat in document not found" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4412" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "setting style physical, but SwTableAutoFormat in document not found" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "setting style physical, but SwTableAutoFormat in document not found" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4412" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "setting style physical, but SwTableAutoFormat in document not found" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4412" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "setting style physical, but SwTableAutoFormat in document not found" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "setting style physical, but SwTableAutoFormat in document not found" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4412" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4413 | } | ||||||
4414 | else | ||||||
4415 | SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextTableStyle")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "calling SetPhysical on a physical SwXTextTableStyle" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4415" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "calling SetPhysical on a physical SwXTextTableStyle" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "calling SetPhysical on a physical SwXTextTableStyle" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4415" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "calling SetPhysical on a physical SwXTextTableStyle" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4415" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "calling SetPhysical on a physical SwXTextTableStyle" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "calling SetPhysical on a physical SwXTextTableStyle" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4415" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4416 | } | ||||||
4417 | |||||||
4418 | // XStyle | ||||||
4419 | sal_Bool SAL_CALL SwXTextTableStyle::isUserDefined() | ||||||
4420 | { | ||||||
4421 | SolarMutexGuard aGuard; | ||||||
4422 | // only first style is not user defined | ||||||
4423 | if (m_pDocShell->GetDoc()->GetTableStyles()[0].GetName() == m_pTableAutoFormat->GetName()) | ||||||
4424 | return false; | ||||||
4425 | |||||||
4426 | return true; | ||||||
4427 | } | ||||||
4428 | |||||||
4429 | sal_Bool SAL_CALL SwXTextTableStyle::isInUse() | ||||||
4430 | { | ||||||
4431 | SolarMutexGuard aGuard; | ||||||
4432 | if (!m_bPhysical) | ||||||
4433 | return false; | ||||||
4434 | |||||||
4435 | SwAutoFormatGetDocNode aGetHt( &m_pDocShell->GetDoc()->GetNodes() ); | ||||||
4436 | |||||||
4437 | for (SwFrameFormat* const & pFormat : *m_pDocShell->GetDoc()->GetTableFrameFormats()) | ||||||
4438 | { | ||||||
4439 | if (!pFormat->GetInfo(aGetHt)) | ||||||
4440 | { | ||||||
4441 | SwTable* pTable = SwTable::FindTable(pFormat); | ||||||
4442 | if (pTable->GetTableStyleName() == m_pTableAutoFormat->GetName()) | ||||||
4443 | return true; | ||||||
4444 | } | ||||||
4445 | } | ||||||
4446 | |||||||
4447 | return false; | ||||||
4448 | } | ||||||
4449 | |||||||
4450 | OUString SAL_CALL SwXTextTableStyle::getParentStyle() | ||||||
4451 | { | ||||||
4452 | return OUString(); | ||||||
4453 | } | ||||||
4454 | |||||||
4455 | void SAL_CALL SwXTextTableStyle::setParentStyle(const OUString& /*aParentStyle*/) | ||||||
4456 | { } | ||||||
4457 | |||||||
4458 | //XNamed | ||||||
4459 | OUString SAL_CALL SwXTextTableStyle::getName() | ||||||
4460 | { | ||||||
4461 | SolarMutexGuard aGuard; | ||||||
4462 | OUString sProgName; | ||||||
4463 | SwStyleNameMapper::FillProgName(m_pTableAutoFormat->GetName(), sProgName, SwGetPoolIdFromName::TabStyle); | ||||||
4464 | return sProgName; | ||||||
4465 | } | ||||||
4466 | |||||||
4467 | void SAL_CALL SwXTextTableStyle::setName(const OUString& rName) | ||||||
4468 | { | ||||||
4469 | SolarMutexGuard aGuard; | ||||||
4470 | m_pTableAutoFormat->SetName(rName); | ||||||
4471 | } | ||||||
4472 | |||||||
4473 | //XPropertySet | ||||||
4474 | css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextTableStyle::getPropertySetInfo() | ||||||
4475 | { | ||||||
4476 | static uno::Reference<beans::XPropertySetInfo> xRef(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_STYLE100)->getPropertySetInfo()); | ||||||
4477 | return xRef; | ||||||
4478 | } | ||||||
4479 | |||||||
4480 | void SAL_CALL SwXTextTableStyle::setPropertyValue(const OUString& /*rPropertyName*/, const css::uno::Any& /*aValue*/) | ||||||
4481 | { | ||||||
4482 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4482" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4482" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4482" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4482" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4483 | } | ||||||
4484 | |||||||
4485 | css::uno::Any SAL_CALL SwXTextTableStyle::getPropertyValue(const OUString& rPropertyName) | ||||||
4486 | { | ||||||
4487 | SolarMutexGuard aGuard; | ||||||
4488 | bool bIsRow = false; | ||||||
4489 | |||||||
4490 | if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_END_COLUMN"FirstRowEndColumn") | ||||||
4491 | bIsRow = m_pTableAutoFormat->FirstRowEndColumnIsRow(); | ||||||
4492 | else if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_START_COLUMN"FirstRowStartColumn") | ||||||
4493 | bIsRow = m_pTableAutoFormat->FirstRowStartColumnIsRow(); | ||||||
4494 | else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_END_COLUMN"LastRowEndColumn") | ||||||
4495 | bIsRow = m_pTableAutoFormat->LastRowEndColumnIsRow(); | ||||||
4496 | else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_START_COLUMN"LastRowStartColumn") | ||||||
4497 | bIsRow = m_pTableAutoFormat->LastRowStartColumnIsRow(); | ||||||
4498 | else if (rPropertyName == UNO_NAME_DISPLAY_NAME"DisplayName") | ||||||
4499 | return uno::makeAny(m_pTableAutoFormat->GetName()); | ||||||
4500 | else | ||||||
4501 | throw css::beans::UnknownPropertyException(rPropertyName); | ||||||
4502 | |||||||
4503 | return uno::makeAny(bIsRow ? OUString("row") : OUString("column")); | ||||||
4504 | } | ||||||
4505 | |||||||
4506 | void SAL_CALL SwXTextTableStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*xListener*/ ) | ||||||
4507 | { | ||||||
4508 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4508" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4508" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4508" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4508" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4509 | } | ||||||
4510 | |||||||
4511 | void SAL_CALL SwXTextTableStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*aListener*/ ) | ||||||
4512 | { | ||||||
4513 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4513" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4513" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4513" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4513" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4514 | } | ||||||
4515 | |||||||
4516 | void SAL_CALL SwXTextTableStyle::addVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ ) | ||||||
4517 | { | ||||||
4518 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4518" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4518" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4518" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4518" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4519 | } | ||||||
4520 | |||||||
4521 | void SAL_CALL SwXTextTableStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ ) | ||||||
4522 | { | ||||||
4523 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4523" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4523" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4523" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4523" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4524 | } | ||||||
4525 | |||||||
4526 | //XNameAccess | ||||||
4527 | uno::Any SAL_CALL SwXTextTableStyle::getByName(const OUString& rName) | ||||||
4528 | { | ||||||
4529 | SolarMutexGuard aGuard; | ||||||
4530 | const CellStyleNameMap& rMap = GetCellStyleNameMap(); | ||||||
4531 | CellStyleNameMap::const_iterator iter = rMap.find(rName); | ||||||
4532 | if(iter == rMap.end()) | ||||||
4533 | throw css::container::NoSuchElementException(); | ||||||
4534 | |||||||
4535 | return css::uno::Any(m_aCellStyles[(*iter).second]); | ||||||
4536 | } | ||||||
4537 | |||||||
4538 | css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getElementNames() | ||||||
4539 | { | ||||||
4540 | SolarMutexGuard aGuard; | ||||||
4541 | return comphelper::mapKeysToSequence(GetCellStyleNameMap()); | ||||||
4542 | } | ||||||
4543 | |||||||
4544 | sal_Bool SAL_CALL SwXTextTableStyle::hasByName(const OUString& rName) | ||||||
4545 | { | ||||||
4546 | SolarMutexGuard aGuard; | ||||||
4547 | const CellStyleNameMap& rMap = GetCellStyleNameMap(); | ||||||
4548 | CellStyleNameMap::const_iterator iter = rMap.find(rName); | ||||||
4549 | return iter != rMap.end(); | ||||||
4550 | } | ||||||
4551 | |||||||
4552 | //XNameContainer | ||||||
4553 | void SAL_CALL SwXTextTableStyle::insertByName(const OUString& /*Name*/, const uno::Any& /*Element*/) | ||||||
4554 | { | ||||||
4555 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4555" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4555" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4555" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4555" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4556 | } | ||||||
4557 | |||||||
4558 | void SAL_CALL SwXTextTableStyle::replaceByName(const OUString& rName, const uno::Any& rElement) | ||||||
4559 | { | ||||||
4560 | SolarMutexGuard aGuard; | ||||||
4561 | const CellStyleNameMap& rMap = GetCellStyleNameMap(); | ||||||
4562 | CellStyleNameMap::const_iterator iter = rMap.find(rName); | ||||||
4563 | if(iter == rMap.end()) | ||||||
4564 | throw container::NoSuchElementException(); | ||||||
4565 | const sal_Int32 nCellStyle = iter->second; | ||||||
4566 | |||||||
4567 | uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>(); | ||||||
4568 | if (!xStyle.is()) | ||||||
4569 | throw lang::IllegalArgumentException(); | ||||||
4570 | |||||||
4571 | SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get()); | ||||||
4572 | if (!pStyleToReplaceWith) | ||||||
4573 | throw lang::IllegalArgumentException(); | ||||||
4574 | |||||||
4575 | // replace only with physical ... | ||||||
4576 | if (!pStyleToReplaceWith->IsPhysical()) | ||||||
4577 | throw lang::IllegalArgumentException(); | ||||||
4578 | |||||||
4579 | const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap(); | ||||||
4580 | const sal_Int32 nBoxFormat = rTableTemplateMap[nCellStyle]; | ||||||
4581 | |||||||
4582 | // move SwBoxAutoFormat to dest. SwTableAutoFormat | ||||||
4583 | m_pTableAutoFormat->SetBoxFormat(*pStyleToReplaceWith->GetBoxFormat(), nBoxFormat); | ||||||
4584 | // remove unassigned SwBoxAutoFormat, which is not anymore in use anyways | ||||||
4585 | m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(xStyle->getName()); | ||||||
4586 | // make SwXTextCellStyle use new, moved SwBoxAutoFormat | ||||||
4587 | pStyleToReplaceWith->SetBoxFormat(&m_pTableAutoFormat->GetBoxFormat(nBoxFormat)); | ||||||
4588 | m_pTableAutoFormat->GetBoxFormat(nBoxFormat).SetXObject(xStyle); | ||||||
4589 | // make this SwXTextTableStyle use new SwXTextCellStyle | ||||||
4590 | m_aCellStyles[nCellStyle] = xStyle; | ||||||
4591 | } | ||||||
4592 | |||||||
4593 | void SAL_CALL SwXTextTableStyle::removeByName(const OUString& /*Name*/) | ||||||
4594 | { | ||||||
4595 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4595" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4595" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4595" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4595" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4596 | } | ||||||
4597 | |||||||
4598 | //XElementAccess | ||||||
4599 | uno::Type SAL_CALL SAL_CALL SwXTextTableStyle::getElementType() | ||||||
4600 | { | ||||||
4601 | return cppu::UnoType<style::XStyle>::get(); | ||||||
4602 | } | ||||||
4603 | |||||||
4604 | sal_Bool SAL_CALL SAL_CALL SwXTextTableStyle::hasElements() | ||||||
4605 | { | ||||||
4606 | return true; | ||||||
4607 | } | ||||||
4608 | |||||||
4609 | //XServiceInfo | ||||||
4610 | OUString SAL_CALL SwXTextTableStyle::getImplementationName() | ||||||
4611 | { | ||||||
4612 | return {"SwXTextTableStyle"}; | ||||||
4613 | } | ||||||
4614 | |||||||
4615 | sal_Bool SAL_CALL SwXTextTableStyle::supportsService(const OUString& rServiceName) | ||||||
4616 | { | ||||||
4617 | return cppu::supportsService(this, rServiceName); | ||||||
4618 | } | ||||||
4619 | |||||||
4620 | css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getSupportedServiceNames() | ||||||
4621 | { | ||||||
4622 | return {"com.sun.star.style.Style"}; | ||||||
4623 | } | ||||||
4624 | |||||||
4625 | // SwXTextCellStyle | ||||||
4626 | SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, const OUString& sParentStyle) : | ||||||
4627 | m_pDocShell(pDocShell), | ||||||
4628 | m_pBoxAutoFormat(pBoxAutoFormat), | ||||||
4629 | m_sParentStyle(sParentStyle), | ||||||
4630 | m_bPhysical(true) | ||||||
4631 | { } | ||||||
4632 | |||||||
4633 | SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, const OUString& sName) : | ||||||
4634 | m_pDocShell(pDocShell), | ||||||
4635 | m_pBoxAutoFormat_Impl(std::make_shared<SwBoxAutoFormat>()), | ||||||
4636 | m_sName(sName), | ||||||
4637 | m_bPhysical(false) | ||||||
4638 | { | ||||||
4639 | m_pBoxAutoFormat = m_pBoxAutoFormat_Impl.get(); | ||||||
4640 | } | ||||||
4641 | |||||||
4642 | SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat() | ||||||
4643 | { | ||||||
4644 | return m_pBoxAutoFormat; | ||||||
4645 | } | ||||||
4646 | |||||||
4647 | void SwXTextCellStyle::SetBoxFormat(SwBoxAutoFormat* pBoxFormat) | ||||||
4648 | { | ||||||
4649 | if (m_bPhysical) | ||||||
4650 | m_pBoxAutoFormat = pBoxFormat; | ||||||
4651 | else | ||||||
4652 | SAL_INFO("sw.uno", "trying to call SwXTextCellStyle::SetBoxFormat on non physical style")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "trying to call SwXTextCellStyle::SetBoxFormat on non physical style" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4652" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "trying to call SwXTextCellStyle::SetBoxFormat on non physical style" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "trying to call SwXTextCellStyle::SetBoxFormat on non physical style" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4652" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "trying to call SwXTextCellStyle::SetBoxFormat on non physical style" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4652" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "trying to call SwXTextCellStyle::SetBoxFormat on non physical style" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "trying to call SwXTextCellStyle::SetBoxFormat on non physical style" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4652" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4653 | } | ||||||
4654 | |||||||
4655 | void SwXTextCellStyle::SetPhysical() | ||||||
4656 | { | ||||||
4657 | if (!m_bPhysical) | ||||||
4658 | { | ||||||
4659 | SwBoxAutoFormat* pBoxAutoFormat = GetBoxAutoFormat(m_pDocShell, m_sName, &m_sParentStyle); | ||||||
4660 | if (pBoxAutoFormat) | ||||||
4661 | { | ||||||
4662 | m_bPhysical = true; | ||||||
4663 | m_pBoxAutoFormat_Impl = nullptr; | ||||||
4664 | m_pBoxAutoFormat = pBoxAutoFormat; | ||||||
4665 | m_pBoxAutoFormat->SetXObject(uno::Reference<style::XStyle>(this)); | ||||||
4666 | } | ||||||
4667 | else | ||||||
4668 | SAL_WARN("sw.uno", "setting style physical, but SwBoxAutoFormat in document not found")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "setting style physical, but SwBoxAutoFormat in document not found" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4668" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "setting style physical, but SwBoxAutoFormat in document not found" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "setting style physical, but SwBoxAutoFormat in document not found" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4668" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "setting style physical, but SwBoxAutoFormat in document not found" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4668" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "setting style physical, but SwBoxAutoFormat in document not found" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "setting style physical, but SwBoxAutoFormat in document not found" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4668" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4669 | } | ||||||
4670 | else | ||||||
4671 | SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextCellStyle")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "calling SetPhysical on a physical SwXTextCellStyle" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4671" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "calling SetPhysical on a physical SwXTextCellStyle" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "calling SetPhysical on a physical SwXTextCellStyle" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4671" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "calling SetPhysical on a physical SwXTextCellStyle" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4671" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "calling SetPhysical on a physical SwXTextCellStyle" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "calling SetPhysical on a physical SwXTextCellStyle" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4671" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4672 | } | ||||||
4673 | |||||||
4674 | bool SwXTextCellStyle::IsPhysical() const | ||||||
4675 | { | ||||||
4676 | return m_bPhysical; | ||||||
4677 | } | ||||||
4678 | |||||||
4679 | SwBoxAutoFormat* SwXTextCellStyle::GetBoxAutoFormat(SwDocShell* pDocShell, const OUString& sName, OUString* pParentName) | ||||||
4680 | { | ||||||
4681 | if (sName.isEmpty()) | ||||||
4682 | return nullptr; | ||||||
4683 | |||||||
4684 | SwBoxAutoFormat* pBoxAutoFormat = pDocShell->GetDoc()->GetCellStyles().GetBoxFormat(sName); | ||||||
4685 | if (!pBoxAutoFormat) | ||||||
4686 | { | ||||||
4687 | sal_Int32 nSeparatorIndex, nTemplateIndex; | ||||||
4688 | OUString sParentName, sCellSubName; | ||||||
4689 | |||||||
4690 | nSeparatorIndex = sName.lastIndexOf('.'); | ||||||
4691 | if (0 >= nSeparatorIndex) | ||||||
4692 | return nullptr; | ||||||
4693 | |||||||
4694 | sParentName = sName.copy(0, nSeparatorIndex); | ||||||
4695 | sCellSubName = sName.copy(nSeparatorIndex+1); | ||||||
4696 | nTemplateIndex = sCellSubName.toInt32()-1; // -1 because cell styles names start from 1, but internally are indexed from 0 | ||||||
4697 | if (0 > nTemplateIndex) | ||||||
4698 | return nullptr; | ||||||
4699 | |||||||
4700 | const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap(); | ||||||
4701 | if (rTableTemplateMap.size() <= o3tl::make_unsigned(nTemplateIndex)) | ||||||
4702 | return nullptr; | ||||||
4703 | |||||||
4704 | SwStyleNameMapper::FillUIName(sParentName, sParentName, SwGetPoolIdFromName::TabStyle); | ||||||
4705 | SwTableAutoFormat* pTableAutoFormat = pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentName); | ||||||
4706 | if (!pTableAutoFormat) | ||||||
4707 | return nullptr; | ||||||
4708 | |||||||
4709 | if (pParentName) | ||||||
4710 | *pParentName = sParentName; | ||||||
4711 | sal_uInt32 nBoxIndex = rTableTemplateMap[nTemplateIndex]; | ||||||
4712 | pBoxAutoFormat = &pTableAutoFormat->GetBoxFormat(nBoxIndex); | ||||||
4713 | } | ||||||
4714 | |||||||
4715 | return pBoxAutoFormat; | ||||||
4716 | } | ||||||
4717 | |||||||
4718 | css::uno::Reference<css::style::XStyle> SwXTextCellStyle::CreateXTextCellStyle(SwDocShell* pDocShell, const OUString& sName) | ||||||
4719 | { | ||||||
4720 | uno::Reference<style::XStyle> xTextCellStyle; | ||||||
4721 | |||||||
4722 | if (!sName.isEmpty()) // create a cell style for a physical box | ||||||
4723 | { | ||||||
4724 | OUString sParentName; | ||||||
4725 | SwBoxAutoFormat* pBoxFormat = GetBoxAutoFormat(pDocShell, sName, &sParentName); | ||||||
4726 | |||||||
4727 | // something went wrong but we don't want a crash | ||||||
4728 | if (!pBoxFormat) | ||||||
4729 | { | ||||||
4730 | // return a default-dummy style to prevent crash | ||||||
4731 | static SwBoxAutoFormat aDefaultBoxFormat; | ||||||
4732 | pBoxFormat = &aDefaultBoxFormat; | ||||||
4733 | } | ||||||
4734 | |||||||
4735 | xTextCellStyle.set(pBoxFormat->GetXObject(), uno::UNO_QUERY); | ||||||
4736 | if (!xTextCellStyle.is()) | ||||||
4737 | { | ||||||
4738 | xTextCellStyle.set(new SwXTextCellStyle(pDocShell, pBoxFormat, sParentName)); | ||||||
4739 | pBoxFormat->SetXObject(xTextCellStyle); | ||||||
4740 | } | ||||||
4741 | } | ||||||
4742 | else // create a non physical style | ||||||
4743 | xTextCellStyle.set(new SwXTextCellStyle(pDocShell, sName)); | ||||||
4744 | |||||||
4745 | return xTextCellStyle; | ||||||
4746 | } | ||||||
4747 | |||||||
4748 | // XStyle | ||||||
4749 | sal_Bool SAL_CALL SwXTextCellStyle::isUserDefined() | ||||||
4750 | { | ||||||
4751 | SolarMutexGuard aGuard; | ||||||
4752 | // if this cell belong to first table style then its default style | ||||||
4753 | if (&m_pDocShell->GetDoc()->GetTableStyles()[0] == m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(m_sParentStyle)) | ||||||
4754 | return false; | ||||||
4755 | |||||||
4756 | return true; | ||||||
4757 | } | ||||||
4758 | |||||||
4759 | sal_Bool SAL_CALL SwXTextCellStyle::isInUse() | ||||||
4760 | { | ||||||
4761 | SolarMutexGuard aGuard; | ||||||
4762 | uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY); | ||||||
4763 | if (!xFamiliesSupplier.is()) | ||||||
4764 | return false; | ||||||
4765 | |||||||
4766 | uno::Reference<container::XNameAccess> xFamilies = xFamiliesSupplier->getStyleFamilies(); | ||||||
4767 | if (!xFamilies.is()) | ||||||
4768 | return false; | ||||||
4769 | |||||||
4770 | uno::Reference<container::XNameAccess> xTableStyles; | ||||||
4771 | xFamilies->getByName("TableStyles") >>= xTableStyles; | ||||||
4772 | if (!xTableStyles.is()) | ||||||
4773 | return false; | ||||||
4774 | |||||||
4775 | uno::Reference<style::XStyle> xStyle; | ||||||
4776 | xTableStyles->getByName(m_sParentStyle) >>= xStyle; | ||||||
4777 | if (!xStyle.is()) | ||||||
4778 | return false; | ||||||
4779 | |||||||
4780 | return xStyle->isInUse(); | ||||||
4781 | } | ||||||
4782 | |||||||
4783 | OUString SAL_CALL SwXTextCellStyle::getParentStyle() | ||||||
4784 | { | ||||||
4785 | // Do not return name of the parent (which is a table style) because the parent should be a cell style. | ||||||
4786 | return OUString(); | ||||||
4787 | } | ||||||
4788 | |||||||
4789 | void SAL_CALL SwXTextCellStyle::setParentStyle(const OUString& /*sParentStyle*/) | ||||||
4790 | { | ||||||
4791 | SolarMutexGuard aGuard; | ||||||
4792 | // Changing parent to one which is unaware of it will lead to a something unexpected. getName() rely on a parent. | ||||||
4793 | SAL_INFO("sw.uno", "Changing SwXTextCellStyle parent")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Changing SwXTextCellStyle parent" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4793" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Changing SwXTextCellStyle parent"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Changing SwXTextCellStyle parent"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4793" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Changing SwXTextCellStyle parent") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4793" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Changing SwXTextCellStyle parent"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Changing SwXTextCellStyle parent"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "4793" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4794 | } | ||||||
4795 | |||||||
4796 | //XNamed | ||||||
4797 | OUString SAL_CALL SwXTextCellStyle::getName() | ||||||
4798 | { | ||||||
4799 | SolarMutexGuard aGuard; | ||||||
4800 | OUString sName; | ||||||
4801 | |||||||
4802 | // if style is physical then we request a name from doc | ||||||
4803 | if (m_bPhysical) | ||||||
4804 | { | ||||||
4805 | SwTableAutoFormat* pTableFormat = m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(m_sParentStyle); | ||||||
4806 | if (!pTableFormat) | ||||||
4807 | { | ||||||
4808 | // if auto format is not found as a child of table formats, look in SwDoc cellstyles | ||||||
4809 | sName = m_pDocShell->GetDoc()->GetCellStyles().GetBoxFormatName(*m_pBoxAutoFormat); | ||||||
4810 | } | ||||||
4811 | else | ||||||
4812 | { | ||||||
4813 | OUString sParentStyle; | ||||||
4814 | SwStyleNameMapper::FillProgName(m_sParentStyle, sParentStyle, SwGetPoolIdFromName::TabStyle); | ||||||
4815 | sName = sParentStyle + pTableFormat->GetTableTemplateCellSubName(*m_pBoxAutoFormat); | ||||||
4816 | } | ||||||
4817 | } | ||||||
4818 | else | ||||||
4819 | sName = m_sName; | ||||||
4820 | |||||||
4821 | return sName; | ||||||
4822 | } | ||||||
4823 | |||||||
4824 | void SAL_CALL SwXTextCellStyle::setName(const OUString& sName) | ||||||
4825 | { | ||||||
4826 | SolarMutexGuard aGuard; | ||||||
4827 | // if style is physical then we can not rename it. | ||||||
4828 | if (!m_bPhysical) | ||||||
4829 | m_sName = sName; | ||||||
4830 | // change name if style is unassigned (name is not generated automatically) | ||||||
4831 | m_pDocShell->GetDoc()->GetCellStyles().ChangeBoxFormatName(getName(), sName); | ||||||
4832 | } | ||||||
4833 | |||||||
4834 | //XPropertySet | ||||||
4835 | css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextCellStyle::getPropertySetInfo() | ||||||
4836 | { | ||||||
4837 | static uno::Reference<beans::XPropertySetInfo> xRef(aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE101)->getPropertySetInfo()); | ||||||
4838 | return xRef; | ||||||
4839 | } | ||||||
4840 | |||||||
4841 | void SAL_CALL SwXTextCellStyle::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& aValue) | ||||||
4842 | { | ||||||
4843 | SolarMutexGuard aGuard; | ||||||
4844 | const SfxItemPropertySimpleEntry *const pEntry = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE101)->getPropertyMap().getByName(rPropertyName); | ||||||
4845 | if(pEntry) | ||||||
4846 | { | ||||||
4847 | switch(pEntry->nWID) | ||||||
4848 | { | ||||||
4849 | case RES_BACKGROUND: | ||||||
4850 | { | ||||||
4851 | SvxBrushItem rBrush = m_pBoxAutoFormat->GetBackground(); | ||||||
4852 | rBrush.PutValue(aValue, 0); | ||||||
4853 | m_pBoxAutoFormat->SetBackground(rBrush); | ||||||
4854 | return; | ||||||
4855 | } | ||||||
4856 | case RES_BOX: | ||||||
4857 | { | ||||||
4858 | SvxBoxItem rBox = m_pBoxAutoFormat->GetBox(); | ||||||
4859 | rBox.PutValue(aValue, pEntry->nMemberId); | ||||||
4860 | m_pBoxAutoFormat->SetBox(rBox); | ||||||
4861 | return; | ||||||
4862 | } | ||||||
4863 | case RES_VERT_ORIENT: | ||||||
4864 | { | ||||||
4865 | SwFormatVertOrient rVertOrient = m_pBoxAutoFormat->GetVerticalAlignment(); | ||||||
4866 | rVertOrient.PutValue(aValue, pEntry->nMemberId); | ||||||
4867 | m_pBoxAutoFormat->SetVerticalAlignment(rVertOrient); | ||||||
4868 | return; | ||||||
4869 | } | ||||||
4870 | case RES_FRAMEDIR: | ||||||
4871 | { | ||||||
4872 | SvxFrameDirectionItem rDirItem = m_pBoxAutoFormat->GetTextOrientation(); | ||||||
4873 | rDirItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4874 | m_pBoxAutoFormat->SetTextOrientation(rDirItem); | ||||||
4875 | return; | ||||||
4876 | } | ||||||
4877 | case RES_BOXATR_FORMAT: | ||||||
4878 | { | ||||||
4879 | sal_uInt32 nKey; | ||||||
4880 | if (aValue >>= nKey) | ||||||
4881 | { | ||||||
4882 | // FIXME: It's not working for old "automatic" currency formats, which are still in use by autotbl.fmt. | ||||||
4883 | // Scenario: | ||||||
4884 | // 1) Mark all styles present by default in autotbl.fmt as default. | ||||||
4885 | // 2) convert all currencies present in autotbl.fmt before calling this code | ||||||
4886 | const SvNumberformat* pNumFormat = m_pDocShell->GetDoc()->GetNumberFormatter()->GetEntry(nKey); | ||||||
4887 | if (pNumFormat) | ||||||
4888 | m_pBoxAutoFormat->SetValueFormat(pNumFormat->GetFormatstring(), pNumFormat->GetLanguage(), GetAppLanguage()); | ||||||
4889 | } | ||||||
4890 | return; | ||||||
4891 | } | ||||||
4892 | // Paragraph attributes | ||||||
4893 | case RES_PARATR_ADJUST: | ||||||
4894 | { | ||||||
4895 | SvxAdjustItem rAdjustItem = m_pBoxAutoFormat->GetAdjust(); | ||||||
4896 | rAdjustItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4897 | m_pBoxAutoFormat->SetAdjust(rAdjustItem); | ||||||
4898 | return; | ||||||
4899 | } | ||||||
4900 | case RES_CHRATR_COLOR: | ||||||
4901 | { | ||||||
4902 | SvxColorItem rColorItem = m_pBoxAutoFormat->GetColor(); | ||||||
4903 | rColorItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4904 | m_pBoxAutoFormat->SetColor(rColorItem); | ||||||
4905 | return; | ||||||
4906 | } | ||||||
4907 | case RES_CHRATR_SHADOWED: | ||||||
4908 | { | ||||||
4909 | SvxShadowedItem rShadowedItem = m_pBoxAutoFormat->GetShadowed(); | ||||||
4910 | bool bValue = false; aValue >>= bValue; | ||||||
4911 | rShadowedItem.SetValue(bValue); | ||||||
4912 | m_pBoxAutoFormat->SetShadowed(rShadowedItem); | ||||||
4913 | return; | ||||||
4914 | } | ||||||
4915 | case RES_CHRATR_CONTOUR: | ||||||
4916 | { | ||||||
4917 | SvxContourItem rContourItem = m_pBoxAutoFormat->GetContour(); | ||||||
4918 | bool bValue = false; aValue >>= bValue; | ||||||
4919 | rContourItem.SetValue(bValue); | ||||||
4920 | m_pBoxAutoFormat->SetContour(rContourItem); | ||||||
4921 | return; | ||||||
4922 | } | ||||||
4923 | case RES_CHRATR_CROSSEDOUT: | ||||||
4924 | { | ||||||
4925 | SvxCrossedOutItem rCrossedOutItem = m_pBoxAutoFormat->GetCrossedOut(); | ||||||
4926 | rCrossedOutItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4927 | m_pBoxAutoFormat->SetCrossedOut(rCrossedOutItem); | ||||||
4928 | return; | ||||||
4929 | } | ||||||
4930 | case RES_CHRATR_UNDERLINE: | ||||||
4931 | { | ||||||
4932 | SvxUnderlineItem rUnderlineItem = m_pBoxAutoFormat->GetUnderline(); | ||||||
4933 | rUnderlineItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4934 | m_pBoxAutoFormat->SetUnderline(rUnderlineItem); | ||||||
4935 | return; | ||||||
4936 | } | ||||||
4937 | case RES_CHRATR_FONTSIZE: | ||||||
4938 | { | ||||||
4939 | SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetHeight(); | ||||||
4940 | rFontHeightItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4941 | m_pBoxAutoFormat->SetHeight(rFontHeightItem); | ||||||
4942 | return; | ||||||
4943 | } | ||||||
4944 | case RES_CHRATR_WEIGHT: | ||||||
4945 | { | ||||||
4946 | SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetWeight(); | ||||||
4947 | rWeightItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4948 | m_pBoxAutoFormat->SetWeight(rWeightItem); | ||||||
4949 | return; | ||||||
4950 | } | ||||||
4951 | case RES_CHRATR_POSTURE: | ||||||
4952 | { | ||||||
4953 | SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetPosture(); | ||||||
4954 | rPostureItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4955 | m_pBoxAutoFormat->SetPosture(rPostureItem); | ||||||
4956 | return; | ||||||
4957 | } | ||||||
4958 | case RES_CHRATR_FONT: | ||||||
4959 | { | ||||||
4960 | SvxFontItem rFontItem = m_pBoxAutoFormat->GetFont(); | ||||||
4961 | rFontItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4962 | m_pBoxAutoFormat->SetFont(rFontItem); | ||||||
4963 | return; | ||||||
4964 | } | ||||||
4965 | case RES_CHRATR_CJK_FONTSIZE: | ||||||
4966 | { | ||||||
4967 | SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCJKHeight(); | ||||||
4968 | rFontHeightItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4969 | m_pBoxAutoFormat->SetCJKHeight(rFontHeightItem); | ||||||
4970 | return; | ||||||
4971 | } | ||||||
4972 | case RES_CHRATR_CJK_WEIGHT: | ||||||
4973 | { | ||||||
4974 | SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCJKWeight(); | ||||||
4975 | rWeightItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4976 | m_pBoxAutoFormat->SetCJKWeight(rWeightItem); | ||||||
4977 | return; | ||||||
4978 | } | ||||||
4979 | case RES_CHRATR_CJK_POSTURE: | ||||||
4980 | { | ||||||
4981 | SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCJKPosture(); | ||||||
4982 | rPostureItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4983 | m_pBoxAutoFormat->SetCJKPosture(rPostureItem); | ||||||
4984 | return; | ||||||
4985 | } | ||||||
4986 | case RES_CHRATR_CJK_FONT: | ||||||
4987 | { | ||||||
4988 | SvxFontItem rFontItem = m_pBoxAutoFormat->GetCJKFont(); | ||||||
4989 | rFontItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4990 | m_pBoxAutoFormat->SetCJKFont(rFontItem); | ||||||
4991 | return; | ||||||
4992 | } | ||||||
4993 | case RES_CHRATR_CTL_FONTSIZE: | ||||||
4994 | { | ||||||
4995 | SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCTLHeight(); | ||||||
4996 | rFontHeightItem.PutValue(aValue, pEntry->nMemberId); | ||||||
4997 | m_pBoxAutoFormat->SetCTLHeight(rFontHeightItem); | ||||||
4998 | return; | ||||||
4999 | } | ||||||
5000 | case RES_CHRATR_CTL_WEIGHT: | ||||||
5001 | { | ||||||
5002 | SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCTLWeight(); | ||||||
5003 | rWeightItem.PutValue(aValue, pEntry->nMemberId); | ||||||
5004 | m_pBoxAutoFormat->SetCTLWeight(rWeightItem); | ||||||
5005 | return; | ||||||
5006 | } | ||||||
5007 | case RES_CHRATR_CTL_POSTURE: | ||||||
5008 | { | ||||||
5009 | SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCTLPosture(); | ||||||
5010 | rPostureItem.PutValue(aValue, pEntry->nMemberId); | ||||||
5011 | m_pBoxAutoFormat->SetCTLPosture(rPostureItem); | ||||||
5012 | return; | ||||||
5013 | } | ||||||
5014 | case RES_CHRATR_CTL_FONT: | ||||||
5015 | { | ||||||
5016 | SvxFontItem rFontItem = m_pBoxAutoFormat->GetCTLFont(); | ||||||
5017 | rFontItem.PutValue(aValue, pEntry->nMemberId); | ||||||
5018 | m_pBoxAutoFormat->SetCTLFont(rFontItem); | ||||||
5019 | return; | ||||||
5020 | } | ||||||
5021 | default: | ||||||
5022 | SAL_WARN("sw.uno", "SwXTextCellStyle unknown nWID")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "SwXTextCellStyle unknown nWID" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5022" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle unknown nWID"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle unknown nWID"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5022" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SwXTextCellStyle unknown nWID") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5022" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle unknown nWID"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle unknown nWID"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5022" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5023 | throw css::uno::RuntimeException(); | ||||||
5024 | } | ||||||
5025 | } | ||||||
5026 | |||||||
5027 | throw css::beans::UnknownPropertyException(rPropertyName); | ||||||
5028 | } | ||||||
5029 | |||||||
5030 | css::uno::Any SAL_CALL SwXTextCellStyle::getPropertyValue(const OUString& rPropertyName) | ||||||
5031 | { | ||||||
5032 | SolarMutexGuard aGuard; | ||||||
5033 | uno::Any aRet; | ||||||
5034 | const SfxItemPropertySimpleEntry *const pEntry = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE101)->getPropertyMap().getByName(rPropertyName); | ||||||
5035 | if(pEntry) | ||||||
5036 | { | ||||||
5037 | switch(pEntry->nWID) | ||||||
5038 | { | ||||||
5039 | case RES_BACKGROUND: | ||||||
5040 | { | ||||||
5041 | const SvxBrushItem& rBrush = m_pBoxAutoFormat->GetBackground(); | ||||||
5042 | rBrush.QueryValue(aRet); | ||||||
5043 | return aRet; | ||||||
5044 | } | ||||||
5045 | case RES_BOX: | ||||||
5046 | { | ||||||
5047 | const SvxBoxItem& rBox = m_pBoxAutoFormat->GetBox(); | ||||||
5048 | rBox.QueryValue(aRet, pEntry->nMemberId); | ||||||
5049 | return aRet; | ||||||
5050 | } | ||||||
5051 | case RES_VERT_ORIENT: | ||||||
5052 | { | ||||||
5053 | const SwFormatVertOrient& rVertOrient = m_pBoxAutoFormat->GetVerticalAlignment(); | ||||||
5054 | rVertOrient.QueryValue(aRet, pEntry->nMemberId); | ||||||
5055 | return aRet; | ||||||
5056 | } | ||||||
5057 | case RES_FRAMEDIR: | ||||||
5058 | { | ||||||
5059 | const SvxFrameDirectionItem& rDirItem = m_pBoxAutoFormat->GetTextOrientation(); | ||||||
5060 | rDirItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5061 | return aRet; | ||||||
5062 | } | ||||||
5063 | case RES_BOXATR_FORMAT: | ||||||
5064 | { | ||||||
5065 | OUString sFormat; | ||||||
5066 | LanguageType eLng, eSys; | ||||||
5067 | m_pBoxAutoFormat->GetValueFormat(sFormat, eLng, eSys); | ||||||
5068 | if(!sFormat.isEmpty()) | ||||||
5069 | { | ||||||
5070 | SvNumFormatType nType; bool bNew; sal_Int32 nCheckPos; | ||||||
5071 | sal_uInt32 nKey = m_pDocShell->GetDoc()->GetNumberFormatter()->GetIndexPuttingAndConverting(sFormat, eLng, eSys, nType, bNew, nCheckPos); | ||||||
5072 | aRet <<= nKey; | ||||||
5073 | } | ||||||
5074 | return aRet; | ||||||
5075 | } | ||||||
5076 | // Paragraph attributes | ||||||
5077 | case RES_PARATR_ADJUST: | ||||||
5078 | { | ||||||
5079 | const SvxAdjustItem& rAdjustItem = m_pBoxAutoFormat->GetAdjust(); | ||||||
5080 | rAdjustItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5081 | return aRet; | ||||||
5082 | } | ||||||
5083 | case RES_CHRATR_COLOR: | ||||||
5084 | { | ||||||
5085 | const SvxColorItem& rColorItem = m_pBoxAutoFormat->GetColor(); | ||||||
5086 | rColorItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5087 | return aRet; | ||||||
5088 | } | ||||||
5089 | case RES_CHRATR_SHADOWED: | ||||||
5090 | { | ||||||
5091 | const SvxShadowedItem& rShadowedItem = m_pBoxAutoFormat->GetShadowed(); | ||||||
5092 | aRet <<= rShadowedItem.GetValue(); | ||||||
5093 | return aRet; | ||||||
5094 | } | ||||||
5095 | case RES_CHRATR_CONTOUR: | ||||||
5096 | { | ||||||
5097 | const SvxContourItem& rContourItem = m_pBoxAutoFormat->GetContour(); | ||||||
5098 | aRet <<= rContourItem.GetValue(); | ||||||
5099 | return aRet; | ||||||
5100 | } | ||||||
5101 | case RES_CHRATR_CROSSEDOUT: | ||||||
5102 | { | ||||||
5103 | const SvxCrossedOutItem& rCrossedOutItem = m_pBoxAutoFormat->GetCrossedOut(); | ||||||
5104 | rCrossedOutItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5105 | return aRet; | ||||||
5106 | } | ||||||
5107 | case RES_CHRATR_UNDERLINE: | ||||||
5108 | { | ||||||
5109 | const SvxUnderlineItem& rUnderlineItem = m_pBoxAutoFormat->GetUnderline(); | ||||||
5110 | rUnderlineItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5111 | return aRet; | ||||||
5112 | } | ||||||
5113 | case RES_CHRATR_FONTSIZE: | ||||||
5114 | { | ||||||
5115 | const SvxFontHeightItem& rFontHeightItem = m_pBoxAutoFormat->GetHeight(); | ||||||
5116 | rFontHeightItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5117 | return aRet; | ||||||
5118 | } | ||||||
5119 | case RES_CHRATR_WEIGHT: | ||||||
5120 | { | ||||||
5121 | const SvxWeightItem& rWeightItem = m_pBoxAutoFormat->GetWeight(); | ||||||
5122 | rWeightItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5123 | return aRet; | ||||||
5124 | } | ||||||
5125 | case RES_CHRATR_POSTURE: | ||||||
5126 | { | ||||||
5127 | const SvxPostureItem& rPostureItem = m_pBoxAutoFormat->GetPosture(); | ||||||
5128 | rPostureItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5129 | return aRet; | ||||||
5130 | } | ||||||
5131 | case RES_CHRATR_FONT: | ||||||
5132 | { | ||||||
5133 | const SvxFontItem rFontItem = m_pBoxAutoFormat->GetFont(); | ||||||
5134 | rFontItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5135 | return aRet; | ||||||
5136 | } | ||||||
5137 | case RES_CHRATR_CJK_FONTSIZE: | ||||||
5138 | { | ||||||
5139 | const SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCJKHeight(); | ||||||
5140 | rFontHeightItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5141 | return aRet; | ||||||
5142 | } | ||||||
5143 | case RES_CHRATR_CJK_WEIGHT: | ||||||
5144 | { | ||||||
5145 | const SvxWeightItem& rWeightItem = m_pBoxAutoFormat->GetCJKWeight(); | ||||||
5146 | rWeightItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5147 | return aRet; | ||||||
5148 | } | ||||||
5149 | case RES_CHRATR_CJK_POSTURE: | ||||||
5150 | { | ||||||
5151 | const SvxPostureItem& rPostureItem = m_pBoxAutoFormat->GetCJKPosture(); | ||||||
5152 | rPostureItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5153 | return aRet; | ||||||
5154 | } | ||||||
5155 | case RES_CHRATR_CJK_FONT: | ||||||
5156 | { | ||||||
5157 | const SvxFontItem rFontItem = m_pBoxAutoFormat->GetCJKFont(); | ||||||
5158 | rFontItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5159 | return aRet; | ||||||
5160 | } | ||||||
5161 | case RES_CHRATR_CTL_FONTSIZE: | ||||||
5162 | { | ||||||
5163 | const SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCTLHeight(); | ||||||
5164 | rFontHeightItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5165 | return aRet; | ||||||
5166 | } | ||||||
5167 | case RES_CHRATR_CTL_WEIGHT: | ||||||
5168 | { | ||||||
5169 | const SvxWeightItem& rWeightItem = m_pBoxAutoFormat->GetCTLWeight(); | ||||||
5170 | rWeightItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5171 | return aRet; | ||||||
5172 | } | ||||||
5173 | case RES_CHRATR_CTL_POSTURE: | ||||||
5174 | { | ||||||
5175 | const SvxPostureItem& rPostureItem = m_pBoxAutoFormat->GetCTLPosture(); | ||||||
5176 | rPostureItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5177 | return aRet; | ||||||
5178 | } | ||||||
5179 | case RES_CHRATR_CTL_FONT: | ||||||
5180 | { | ||||||
5181 | const SvxFontItem rFontItem = m_pBoxAutoFormat->GetCTLFont(); | ||||||
5182 | rFontItem.QueryValue(aRet, pEntry->nMemberId); | ||||||
5183 | return aRet; | ||||||
5184 | } | ||||||
5185 | default: | ||||||
5186 | SAL_WARN("sw.uno", "SwXTextCellStyle unknown nWID")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "SwXTextCellStyle unknown nWID" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5186" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle unknown nWID"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle unknown nWID"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5186" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SwXTextCellStyle unknown nWID") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5186" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle unknown nWID"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle unknown nWID"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5186" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5187 | throw css::uno::RuntimeException(); | ||||||
5188 | } | ||||||
5189 | } | ||||||
5190 | |||||||
5191 | throw css::beans::UnknownPropertyException(rPropertyName); | ||||||
5192 | } | ||||||
5193 | |||||||
5194 | void SAL_CALL SwXTextCellStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*xListener*/ ) | ||||||
5195 | { | ||||||
5196 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5196" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5196" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5196" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5196" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5197 | } | ||||||
5198 | |||||||
5199 | void SAL_CALL SwXTextCellStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*aListener*/ ) | ||||||
5200 | { | ||||||
5201 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5201" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5201" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5201" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5201" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5202 | } | ||||||
5203 | |||||||
5204 | void SAL_CALL SwXTextCellStyle::addVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ ) | ||||||
5205 | { | ||||||
5206 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5206" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5206" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5206" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5206" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5207 | } | ||||||
5208 | |||||||
5209 | void SAL_CALL SwXTextCellStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ ) | ||||||
5210 | { | ||||||
5211 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5211" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5211" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5211" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5211" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5212 | } | ||||||
5213 | |||||||
5214 | //XPropertyState | ||||||
5215 | css::beans::PropertyState SAL_CALL SwXTextCellStyle::getPropertyState(const OUString& rPropertyName) | ||||||
5216 | { | ||||||
5217 | SolarMutexGuard aGuard; | ||||||
5218 | uno::Sequence<OUString> aNames { rPropertyName }; | ||||||
5219 | uno::Sequence<beans::PropertyState> aStates = getPropertyStates(aNames); | ||||||
5220 | return aStates.getConstArray()[0]; | ||||||
5221 | } | ||||||
5222 | |||||||
5223 | css::uno::Sequence<css::beans::PropertyState> SAL_CALL SwXTextCellStyle::getPropertyStates(const css::uno::Sequence<OUString>& aPropertyNames) | ||||||
5224 | { | ||||||
5225 | SolarMutexGuard aGuard; | ||||||
5226 | uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength()); | ||||||
5227 | beans::PropertyState* pStates = aRet.getArray(); | ||||||
5228 | const SwBoxAutoFormat& rDefaultBoxFormat = SwTableAutoFormat::GetDefaultBoxFormat(); | ||||||
5229 | const SfxItemPropertyMap& rMap = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE101)->getPropertyMap(); | ||||||
5230 | const OUString* pNames = aPropertyNames.getConstArray(); | ||||||
5231 | for(sal_Int32 i=0; i < aPropertyNames.getLength(); ++i) | ||||||
5232 | { | ||||||
5233 | const OUString sPropName = pNames[i]; | ||||||
5234 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(sPropName); | ||||||
5235 | if(pEntry) | ||||||
5236 | { | ||||||
5237 | uno::Any aAny1, aAny2; | ||||||
5238 | switch(pEntry->nWID) | ||||||
5239 | { | ||||||
5240 | case RES_BACKGROUND: | ||||||
5241 | m_pBoxAutoFormat->GetBackground().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5242 | rDefaultBoxFormat.GetBackground().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5243 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5244 | break; | ||||||
5245 | case RES_BOX: | ||||||
5246 | m_pBoxAutoFormat->GetBox().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5247 | rDefaultBoxFormat.GetBox().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5248 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5249 | break; | ||||||
5250 | case RES_VERT_ORIENT: | ||||||
5251 | m_pBoxAutoFormat->GetVerticalAlignment().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5252 | rDefaultBoxFormat.GetVerticalAlignment().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5253 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5254 | break; | ||||||
5255 | case RES_FRAMEDIR: | ||||||
5256 | m_pBoxAutoFormat->GetTextOrientation().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5257 | rDefaultBoxFormat.GetTextOrientation().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5258 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5259 | break; | ||||||
5260 | case RES_BOXATR_FORMAT: | ||||||
5261 | { | ||||||
5262 | OUString sFormat; | ||||||
5263 | LanguageType eLng, eSys; | ||||||
5264 | m_pBoxAutoFormat->GetValueFormat(sFormat, eLng, eSys); | ||||||
5265 | pStates[i] = sFormat.isEmpty() ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5266 | break; | ||||||
5267 | } | ||||||
5268 | case RES_PARATR_ADJUST: | ||||||
5269 | m_pBoxAutoFormat->GetAdjust().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5270 | rDefaultBoxFormat.GetAdjust().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5271 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5272 | break; | ||||||
5273 | case RES_CHRATR_COLOR: | ||||||
5274 | m_pBoxAutoFormat->GetColor().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5275 | rDefaultBoxFormat.GetColor().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5276 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5277 | break; | ||||||
5278 | case RES_CHRATR_SHADOWED: | ||||||
5279 | m_pBoxAutoFormat->GetShadowed().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5280 | rDefaultBoxFormat.GetShadowed().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5281 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5282 | break; | ||||||
5283 | case RES_CHRATR_CONTOUR: | ||||||
5284 | m_pBoxAutoFormat->GetContour().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5285 | rDefaultBoxFormat.GetContour().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5286 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5287 | break; | ||||||
5288 | case RES_CHRATR_CROSSEDOUT: | ||||||
5289 | m_pBoxAutoFormat->GetCrossedOut().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5290 | rDefaultBoxFormat.GetCrossedOut().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5291 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5292 | break; | ||||||
5293 | case RES_CHRATR_UNDERLINE: | ||||||
5294 | m_pBoxAutoFormat->GetUnderline().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5295 | rDefaultBoxFormat.GetUnderline().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5296 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5297 | break; | ||||||
5298 | case RES_CHRATR_FONTSIZE: | ||||||
5299 | m_pBoxAutoFormat->GetHeight().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5300 | rDefaultBoxFormat.GetHeight().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5301 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5302 | break; | ||||||
5303 | case RES_CHRATR_WEIGHT: | ||||||
5304 | m_pBoxAutoFormat->GetWeight().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5305 | rDefaultBoxFormat.GetWeight().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5306 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5307 | break; | ||||||
5308 | case RES_CHRATR_POSTURE: | ||||||
5309 | m_pBoxAutoFormat->GetPosture().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5310 | rDefaultBoxFormat.GetPosture().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5311 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5312 | break; | ||||||
5313 | case RES_CHRATR_FONT: | ||||||
5314 | m_pBoxAutoFormat->GetFont().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5315 | rDefaultBoxFormat.GetFont().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5316 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5317 | break; | ||||||
5318 | case RES_CHRATR_CJK_FONTSIZE: | ||||||
5319 | m_pBoxAutoFormat->GetCJKHeight().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5320 | rDefaultBoxFormat.GetCJKHeight().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5321 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5322 | break; | ||||||
5323 | case RES_CHRATR_CJK_WEIGHT: | ||||||
5324 | m_pBoxAutoFormat->GetCJKWeight().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5325 | rDefaultBoxFormat.GetCJKWeight().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5326 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5327 | break; | ||||||
5328 | case RES_CHRATR_CJK_POSTURE: | ||||||
5329 | m_pBoxAutoFormat->GetCJKPosture().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5330 | rDefaultBoxFormat.GetCJKPosture().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5331 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5332 | break; | ||||||
5333 | case RES_CHRATR_CJK_FONT: | ||||||
5334 | m_pBoxAutoFormat->GetCJKFont().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5335 | rDefaultBoxFormat.GetCJKFont().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5336 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5337 | break; | ||||||
5338 | case RES_CHRATR_CTL_FONTSIZE: | ||||||
5339 | m_pBoxAutoFormat->GetCTLHeight().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5340 | rDefaultBoxFormat.GetCTLHeight().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5341 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5342 | break; | ||||||
5343 | case RES_CHRATR_CTL_WEIGHT: | ||||||
5344 | m_pBoxAutoFormat->GetCTLWeight().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5345 | rDefaultBoxFormat.GetCTLWeight().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5346 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5347 | break; | ||||||
5348 | case RES_CHRATR_CTL_POSTURE: | ||||||
5349 | m_pBoxAutoFormat->GetCTLPosture().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5350 | rDefaultBoxFormat.GetCTLPosture().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5351 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5352 | break; | ||||||
5353 | case RES_CHRATR_CTL_FONT: | ||||||
5354 | m_pBoxAutoFormat->GetCTLFont().QueryValue(aAny1, pEntry->nMemberId); | ||||||
5355 | rDefaultBoxFormat.GetCTLFont().QueryValue(aAny2, pEntry->nMemberId); | ||||||
5356 | pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE; | ||||||
5357 | break; | ||||||
5358 | default: | ||||||
5359 | // fallthrough to DIRECT_VALUE, to export properties for which getPropertyStates is not implemented | ||||||
5360 | pStates[i] = beans::PropertyState_DIRECT_VALUE; | ||||||
5361 | SAL_WARN("sw.uno", "SwXTextCellStyle getPropertyStates unknown nWID")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "SwXTextCellStyle getPropertyStates unknown nWID" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5361" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle getPropertyStates unknown nWID" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle getPropertyStates unknown nWID"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ( "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5361" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SwXTextCellStyle getPropertyStates unknown nWID" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5361" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle getPropertyStates unknown nWID" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle getPropertyStates unknown nWID"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ( "/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5361" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5362 | } | ||||||
5363 | } | ||||||
5364 | else | ||||||
5365 | { | ||||||
5366 | SAL_WARN("sw.uno", "SwXTextCellStyle unknown property:" + sPropName)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "SwXTextCellStyle unknown property:" + sPropName) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5366" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle unknown property:" + sPropName), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "SwXTextCellStyle unknown property:" + sPropName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5366" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SwXTextCellStyle unknown property:" + sPropName) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5366" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle unknown property:" + sPropName), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "SwXTextCellStyle unknown property:" + sPropName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5366" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5367 | throw css::beans::UnknownPropertyException(sPropName); | ||||||
5368 | } | ||||||
5369 | } | ||||||
5370 | return aRet; | ||||||
5371 | } | ||||||
5372 | |||||||
5373 | void SAL_CALL SwXTextCellStyle::setPropertyToDefault(const OUString& rPropertyName) | ||||||
5374 | { | ||||||
5375 | SolarMutexGuard aGuard; | ||||||
5376 | const SwBoxAutoFormat& rDefaultBoxFormat = SwTableAutoFormat::GetDefaultBoxFormat(); | ||||||
5377 | const SfxItemPropertyMap& rMap = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE101)->getPropertyMap(); | ||||||
5378 | const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropertyName); | ||||||
5379 | if(!pEntry) | ||||||
5380 | return; | ||||||
5381 | |||||||
5382 | uno::Any aAny; | ||||||
5383 | switch(pEntry->nWID) | ||||||
5384 | { | ||||||
5385 | case RES_BACKGROUND: | ||||||
5386 | { | ||||||
5387 | SvxBrushItem rBrush = m_pBoxAutoFormat->GetBackground(); | ||||||
5388 | rDefaultBoxFormat.GetBackground().QueryValue(aAny, pEntry->nMemberId); | ||||||
5389 | rBrush.PutValue(aAny, pEntry->nMemberId); | ||||||
5390 | m_pBoxAutoFormat->SetBackground(rBrush); | ||||||
5391 | break; | ||||||
5392 | } | ||||||
5393 | case RES_BOX: | ||||||
5394 | { | ||||||
5395 | SvxBoxItem rBox = m_pBoxAutoFormat->GetBox(); | ||||||
5396 | rDefaultBoxFormat.GetBox().QueryValue(aAny, pEntry->nMemberId); | ||||||
5397 | rBox.PutValue(aAny, pEntry->nMemberId); | ||||||
5398 | m_pBoxAutoFormat->SetBox(rBox); | ||||||
5399 | break; | ||||||
5400 | } | ||||||
5401 | case RES_VERT_ORIENT: | ||||||
5402 | { | ||||||
5403 | SwFormatVertOrient rVertOrient = m_pBoxAutoFormat->GetVerticalAlignment(); | ||||||
5404 | rDefaultBoxFormat.GetVerticalAlignment().QueryValue(aAny, pEntry->nMemberId); | ||||||
5405 | rVertOrient.PutValue(aAny, pEntry->nMemberId); | ||||||
5406 | m_pBoxAutoFormat->SetVerticalAlignment(rVertOrient); | ||||||
5407 | break; | ||||||
5408 | } | ||||||
5409 | case RES_FRAMEDIR: | ||||||
5410 | { | ||||||
5411 | SvxFrameDirectionItem rFrameDirectionItem = m_pBoxAutoFormat->GetTextOrientation(); | ||||||
5412 | rDefaultBoxFormat.GetTextOrientation().QueryValue(aAny, pEntry->nMemberId); | ||||||
5413 | rFrameDirectionItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5414 | m_pBoxAutoFormat->SetTextOrientation(rFrameDirectionItem); | ||||||
5415 | break; | ||||||
5416 | } | ||||||
5417 | case RES_BOXATR_FORMAT: | ||||||
5418 | { | ||||||
5419 | OUString sFormat; | ||||||
5420 | LanguageType eLng, eSys; | ||||||
5421 | rDefaultBoxFormat.GetValueFormat(sFormat, eLng, eSys); | ||||||
5422 | m_pBoxAutoFormat->SetValueFormat(sFormat, eLng, eSys); | ||||||
5423 | break; | ||||||
5424 | } | ||||||
5425 | case RES_PARATR_ADJUST: | ||||||
5426 | { | ||||||
5427 | SvxAdjustItem rAdjustItem = m_pBoxAutoFormat->GetAdjust(); | ||||||
5428 | rDefaultBoxFormat.GetAdjust().QueryValue(aAny, pEntry->nMemberId); | ||||||
5429 | rAdjustItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5430 | m_pBoxAutoFormat->SetAdjust(rAdjustItem); | ||||||
5431 | break; | ||||||
5432 | } | ||||||
5433 | case RES_CHRATR_COLOR: | ||||||
5434 | { | ||||||
5435 | SvxColorItem rColorItem = m_pBoxAutoFormat->GetColor(); | ||||||
5436 | rDefaultBoxFormat.GetColor().QueryValue(aAny, pEntry->nMemberId); | ||||||
5437 | rColorItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5438 | m_pBoxAutoFormat->SetColor(rColorItem); | ||||||
5439 | break; | ||||||
5440 | } | ||||||
5441 | case RES_CHRATR_SHADOWED: | ||||||
5442 | { | ||||||
5443 | SvxShadowedItem rShadowedItem = m_pBoxAutoFormat->GetShadowed(); | ||||||
5444 | rDefaultBoxFormat.GetShadowed().QueryValue(aAny, pEntry->nMemberId); | ||||||
5445 | rShadowedItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5446 | m_pBoxAutoFormat->SetShadowed(rShadowedItem); | ||||||
5447 | break; | ||||||
5448 | } | ||||||
5449 | case RES_CHRATR_CONTOUR: | ||||||
5450 | { | ||||||
5451 | SvxContourItem rContourItem = m_pBoxAutoFormat->GetContour(); | ||||||
5452 | rDefaultBoxFormat.GetContour().QueryValue(aAny, pEntry->nMemberId); | ||||||
5453 | rContourItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5454 | m_pBoxAutoFormat->SetContour(rContourItem); | ||||||
5455 | break; | ||||||
5456 | } | ||||||
5457 | case RES_CHRATR_CROSSEDOUT: | ||||||
5458 | { | ||||||
5459 | SvxCrossedOutItem rCrossedOutItem = m_pBoxAutoFormat->GetCrossedOut(); | ||||||
5460 | rDefaultBoxFormat.GetCrossedOut().QueryValue(aAny, pEntry->nMemberId); | ||||||
5461 | rCrossedOutItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5462 | m_pBoxAutoFormat->SetCrossedOut(rCrossedOutItem); | ||||||
5463 | break; | ||||||
5464 | } | ||||||
5465 | case RES_CHRATR_UNDERLINE: | ||||||
5466 | { | ||||||
5467 | SvxUnderlineItem rUnderlineItem = m_pBoxAutoFormat->GetUnderline(); | ||||||
5468 | rDefaultBoxFormat.GetUnderline().QueryValue(aAny, pEntry->nMemberId); | ||||||
5469 | rUnderlineItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5470 | m_pBoxAutoFormat->SetUnderline(rUnderlineItem); | ||||||
5471 | break; | ||||||
5472 | } | ||||||
5473 | case RES_CHRATR_FONTSIZE: | ||||||
5474 | { | ||||||
5475 | SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetHeight(); | ||||||
5476 | rDefaultBoxFormat.GetHeight().QueryValue(aAny, pEntry->nMemberId); | ||||||
5477 | rFontHeightItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5478 | m_pBoxAutoFormat->SetHeight(rFontHeightItem); | ||||||
5479 | break; | ||||||
5480 | } | ||||||
5481 | case RES_CHRATR_WEIGHT: | ||||||
5482 | { | ||||||
5483 | SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetWeight(); | ||||||
5484 | rDefaultBoxFormat.GetWeight().QueryValue(aAny, pEntry->nMemberId); | ||||||
5485 | rWeightItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5486 | m_pBoxAutoFormat->SetWeight(rWeightItem); | ||||||
5487 | break; | ||||||
5488 | } | ||||||
5489 | case RES_CHRATR_POSTURE: | ||||||
5490 | { | ||||||
5491 | SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetPosture(); | ||||||
5492 | rDefaultBoxFormat.GetPosture().QueryValue(aAny, pEntry->nMemberId); | ||||||
5493 | rPostureItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5494 | m_pBoxAutoFormat->SetPosture(rPostureItem); | ||||||
5495 | break; | ||||||
5496 | } | ||||||
5497 | case RES_CHRATR_FONT: | ||||||
5498 | { | ||||||
5499 | SvxFontItem rFontItem = m_pBoxAutoFormat->GetFont(); | ||||||
5500 | rDefaultBoxFormat.GetFont().QueryValue(aAny, pEntry->nMemberId); | ||||||
5501 | rFontItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5502 | m_pBoxAutoFormat->SetFont(rFontItem); | ||||||
5503 | break; | ||||||
5504 | } | ||||||
5505 | case RES_CHRATR_CJK_FONTSIZE: | ||||||
5506 | { | ||||||
5507 | SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCJKHeight(); | ||||||
5508 | rDefaultBoxFormat.GetCJKHeight().QueryValue(aAny, pEntry->nMemberId); | ||||||
5509 | rFontHeightItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5510 | m_pBoxAutoFormat->SetCJKHeight(rFontHeightItem); | ||||||
5511 | break; | ||||||
5512 | } | ||||||
5513 | case RES_CHRATR_CJK_WEIGHT: | ||||||
5514 | { | ||||||
5515 | SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCJKWeight(); | ||||||
5516 | rDefaultBoxFormat.GetCJKWeight().QueryValue(aAny, pEntry->nMemberId); | ||||||
5517 | rWeightItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5518 | m_pBoxAutoFormat->SetCJKWeight(rWeightItem); | ||||||
5519 | break; | ||||||
5520 | } | ||||||
5521 | case RES_CHRATR_CJK_POSTURE: | ||||||
5522 | { | ||||||
5523 | SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCJKPosture(); | ||||||
5524 | rDefaultBoxFormat.GetCJKPosture().QueryValue(aAny, pEntry->nMemberId); | ||||||
5525 | rPostureItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5526 | m_pBoxAutoFormat->SetCJKPosture(rPostureItem); | ||||||
5527 | break; | ||||||
5528 | } | ||||||
5529 | case RES_CHRATR_CJK_FONT: | ||||||
5530 | { | ||||||
5531 | SvxFontItem rFontItem = m_pBoxAutoFormat->GetCJKFont(); | ||||||
5532 | rDefaultBoxFormat.GetCJKFont().QueryValue(aAny, pEntry->nMemberId); | ||||||
5533 | rFontItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5534 | m_pBoxAutoFormat->SetCJKFont(rFontItem); | ||||||
5535 | break; | ||||||
5536 | } | ||||||
5537 | case RES_CHRATR_CTL_FONTSIZE: | ||||||
5538 | { | ||||||
5539 | SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCTLHeight(); | ||||||
5540 | rDefaultBoxFormat.GetCTLHeight().QueryValue(aAny, pEntry->nMemberId); | ||||||
5541 | rFontHeightItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5542 | m_pBoxAutoFormat->SetCTLHeight(rFontHeightItem); | ||||||
5543 | break; | ||||||
5544 | } | ||||||
5545 | case RES_CHRATR_CTL_WEIGHT: | ||||||
5546 | { | ||||||
5547 | SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCTLWeight(); | ||||||
5548 | rDefaultBoxFormat.GetCTLWeight().QueryValue(aAny, pEntry->nMemberId); | ||||||
5549 | rWeightItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5550 | m_pBoxAutoFormat->SetCTLWeight(rWeightItem); | ||||||
5551 | break; | ||||||
5552 | } | ||||||
5553 | case RES_CHRATR_CTL_POSTURE: | ||||||
5554 | { | ||||||
5555 | SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCTLPosture(); | ||||||
5556 | rDefaultBoxFormat.GetCTLPosture().QueryValue(aAny, pEntry->nMemberId); | ||||||
5557 | rPostureItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5558 | m_pBoxAutoFormat->SetCTLPosture(rPostureItem); | ||||||
5559 | break; | ||||||
5560 | } | ||||||
5561 | case RES_CHRATR_CTL_FONT: | ||||||
5562 | { | ||||||
5563 | SvxFontItem rFontItem = m_pBoxAutoFormat->GetCTLFont(); | ||||||
5564 | rDefaultBoxFormat.GetCTLFont().QueryValue(aAny, pEntry->nMemberId); | ||||||
5565 | rFontItem.PutValue(aAny, pEntry->nMemberId); | ||||||
5566 | m_pBoxAutoFormat->SetCTLFont(rFontItem); | ||||||
5567 | break; | ||||||
5568 | } | ||||||
5569 | default: | ||||||
5570 | SAL_WARN("sw.uno", "SwXTextCellStyle setPropertyToDefault unknown nWID")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "SwXTextCellStyle setPropertyToDefault unknown nWID" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5570" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle setPropertyToDefault unknown nWID" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle setPropertyToDefault unknown nWID" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5570" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SwXTextCellStyle setPropertyToDefault unknown nWID" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5570" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SwXTextCellStyle setPropertyToDefault unknown nWID" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SwXTextCellStyle setPropertyToDefault unknown nWID" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5570" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5571 | } | ||||||
5572 | } | ||||||
5573 | |||||||
5574 | css::uno::Any SAL_CALL SwXTextCellStyle::getPropertyDefault(const OUString& /*aPropertyName*/) | ||||||
5575 | { | ||||||
5576 | SAL_WARN("sw.uno", "not implemented")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno" ), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5576" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5576" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "not implemented") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5576" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "not implemented"), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "not implemented"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx" ":" "5576" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5577 | uno::Any aRet; | ||||||
5578 | return aRet; | ||||||
5579 | } | ||||||
5580 | |||||||
5581 | //XServiceInfo | ||||||
5582 | OUString SAL_CALL SwXTextCellStyle::getImplementationName() | ||||||
5583 | { | ||||||
5584 | return {"SwXTextCellStyle"}; | ||||||
5585 | } | ||||||
5586 | |||||||
5587 | sal_Bool SAL_CALL SwXTextCellStyle::supportsService(const OUString& rServiceName) | ||||||
5588 | { | ||||||
5589 | return cppu::supportsService(this, rServiceName); | ||||||
5590 | } | ||||||
5591 | |||||||
5592 | css::uno::Sequence<OUString> SAL_CALL SwXTextCellStyle::getSupportedServiceNames() | ||||||
5593 | { | ||||||
5594 | return {"com.sun.star.style.Style"}; | ||||||
5595 | } | ||||||
5596 | |||||||
5597 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | // Algorithm implementation -*- C++ -*- |
2 | |
3 | // Copyright (C) 2001-2020 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /* |
26 | * |
27 | * Copyright (c) 1994 |
28 | * Hewlett-Packard Company |
29 | * |
30 | * Permission to use, copy, modify, distribute and sell this software |
31 | * and its documentation for any purpose is hereby granted without fee, |
32 | * provided that the above copyright notice appear in all copies and |
33 | * that both that copyright notice and this permission notice appear |
34 | * in supporting documentation. Hewlett-Packard Company makes no |
35 | * representations about the suitability of this software for any |
36 | * purpose. It is provided "as is" without express or implied warranty. |
37 | * |
38 | * |
39 | * Copyright (c) 1996 |
40 | * Silicon Graphics Computer Systems, Inc. |
41 | * |
42 | * Permission to use, copy, modify, distribute and sell this software |
43 | * and its documentation for any purpose is hereby granted without fee, |
44 | * provided that the above copyright notice appear in all copies and |
45 | * that both that copyright notice and this permission notice appear |
46 | * in supporting documentation. Silicon Graphics makes no |
47 | * representations about the suitability of this software for any |
48 | * purpose. It is provided "as is" without express or implied warranty. |
49 | */ |
50 | |
51 | /** @file bits/stl_algo.h |
52 | * This is an internal header file, included by other library headers. |
53 | * Do not attempt to use it directly. @headername{algorithm} |
54 | */ |
55 | |
56 | #ifndef _STL_ALGO_H1 |
57 | #define _STL_ALGO_H1 1 |
58 | |
59 | #include <cstdlib> // for rand |
60 | #include <bits/algorithmfwd.h> |
61 | #include <bits/stl_heap.h> |
62 | #include <bits/stl_tempbuf.h> // for _Temporary_buffer |
63 | #include <bits/predefined_ops.h> |
64 | |
65 | #if __cplusplus201703L >= 201103L |
66 | #include <bits/uniform_int_dist.h> |
67 | #endif |
68 | |
69 | // See concept_check.h for the __glibcxx_*_requires macros. |
70 | |
71 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
72 | { |
73 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
74 | |
75 | /// Swaps the median value of *__a, *__b and *__c under __comp to *__result |
76 | template<typename _Iterator, typename _Compare> |
77 | _GLIBCXX20_CONSTEXPR |
78 | void |
79 | __move_median_to_first(_Iterator __result,_Iterator __a, _Iterator __b, |
80 | _Iterator __c, _Compare __comp) |
81 | { |
82 | if (__comp(__a, __b)) |
83 | { |
84 | if (__comp(__b, __c)) |
85 | std::iter_swap(__result, __b); |
86 | else if (__comp(__a, __c)) |
87 | std::iter_swap(__result, __c); |
88 | else |
89 | std::iter_swap(__result, __a); |
90 | } |
91 | else if (__comp(__a, __c)) |
92 | std::iter_swap(__result, __a); |
93 | else if (__comp(__b, __c)) |
94 | std::iter_swap(__result, __c); |
95 | else |
96 | std::iter_swap(__result, __b); |
97 | } |
98 | |
99 | /// Provided for stable_partition to use. |
100 | template<typename _InputIterator, typename _Predicate> |
101 | _GLIBCXX20_CONSTEXPR |
102 | inline _InputIterator |
103 | __find_if_not(_InputIterator __first, _InputIterator __last, |
104 | _Predicate __pred) |
105 | { |
106 | return std::__find_if(__first, __last, |
107 | __gnu_cxx::__ops::__negate(__pred), |
108 | std::__iterator_category(__first)); |
109 | } |
110 | |
111 | /// Like find_if_not(), but uses and updates a count of the |
112 | /// remaining range length instead of comparing against an end |
113 | /// iterator. |
114 | template<typename _InputIterator, typename _Predicate, typename _Distance> |
115 | _GLIBCXX20_CONSTEXPR |
116 | _InputIterator |
117 | __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred) |
118 | { |
119 | for (; __len; --__len, (void) ++__first) |
120 | if (!__pred(__first)) |
121 | break; |
122 | return __first; |
123 | } |
124 | |
125 | // set_difference |
126 | // set_intersection |
127 | // set_symmetric_difference |
128 | // set_union |
129 | // for_each |
130 | // find |
131 | // find_if |
132 | // find_first_of |
133 | // adjacent_find |
134 | // count |
135 | // count_if |
136 | // search |
137 | |
138 | template<typename _ForwardIterator1, typename _ForwardIterator2, |
139 | typename _BinaryPredicate> |
140 | _GLIBCXX20_CONSTEXPR |
141 | _ForwardIterator1 |
142 | __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
143 | _ForwardIterator2 __first2, _ForwardIterator2 __last2, |
144 | _BinaryPredicate __predicate) |
145 | { |
146 | // Test for empty ranges |
147 | if (__first1 == __last1 || __first2 == __last2) |
148 | return __first1; |
149 | |
150 | // Test for a pattern of length 1. |
151 | _ForwardIterator2 __p1(__first2); |
152 | if (++__p1 == __last2) |
153 | return std::__find_if(__first1, __last1, |
154 | __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); |
155 | |
156 | // General case. |
157 | _ForwardIterator1 __current = __first1; |
158 | |
159 | for (;;) |
160 | { |
161 | __first1 = |
162 | std::__find_if(__first1, __last1, |
163 | __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); |
164 | |
165 | if (__first1 == __last1) |
166 | return __last1; |
167 | |
168 | _ForwardIterator2 __p = __p1; |
169 | __current = __first1; |
170 | if (++__current == __last1) |
171 | return __last1; |
172 | |
173 | while (__predicate(__current, __p)) |
174 | { |
175 | if (++__p == __last2) |
176 | return __first1; |
177 | if (++__current == __last1) |
178 | return __last1; |
179 | } |
180 | ++__first1; |
181 | } |
182 | return __first1; |
183 | } |
184 | |
185 | // search_n |
186 | |
187 | /** |
188 | * This is an helper function for search_n overloaded for forward iterators. |
189 | */ |
190 | template<typename _ForwardIterator, typename _Integer, |
191 | typename _UnaryPredicate> |
192 | _GLIBCXX20_CONSTEXPR |
193 | _ForwardIterator |
194 | __search_n_aux(_ForwardIterator __first, _ForwardIterator __last, |
195 | _Integer __count, _UnaryPredicate __unary_pred, |
196 | std::forward_iterator_tag) |
197 | { |
198 | __first = std::__find_if(__first, __last, __unary_pred); |
199 | while (__first != __last) |
200 | { |
201 | typename iterator_traits<_ForwardIterator>::difference_type |
202 | __n = __count; |
203 | _ForwardIterator __i = __first; |
204 | ++__i; |
205 | while (__i != __last && __n != 1 && __unary_pred(__i)) |
206 | { |
207 | ++__i; |
208 | --__n; |
209 | } |
210 | if (__n == 1) |
211 | return __first; |
212 | if (__i == __last) |
213 | return __last; |
214 | __first = std::__find_if(++__i, __last, __unary_pred); |
215 | } |
216 | return __last; |
217 | } |
218 | |
219 | /** |
220 | * This is an helper function for search_n overloaded for random access |
221 | * iterators. |
222 | */ |
223 | template<typename _RandomAccessIter, typename _Integer, |
224 | typename _UnaryPredicate> |
225 | _GLIBCXX20_CONSTEXPR |
226 | _RandomAccessIter |
227 | __search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last, |
228 | _Integer __count, _UnaryPredicate __unary_pred, |
229 | std::random_access_iterator_tag) |
230 | { |
231 | typedef typename std::iterator_traits<_RandomAccessIter>::difference_type |
232 | _DistanceType; |
233 | |
234 | _DistanceType __tailSize = __last - __first; |
235 | _DistanceType __remainder = __count; |
236 | |
237 | while (__remainder <= __tailSize) // the main loop... |
238 | { |
239 | __first += __remainder; |
240 | __tailSize -= __remainder; |
241 | // __first here is always pointing to one past the last element of |
242 | // next possible match. |
243 | _RandomAccessIter __backTrack = __first; |
244 | while (__unary_pred(--__backTrack)) |
245 | { |
246 | if (--__remainder == 0) |
247 | return (__first - __count); // Success |
248 | } |
249 | __remainder = __count + 1 - (__first - __backTrack); |
250 | } |
251 | return __last; // Failure |
252 | } |
253 | |
254 | template<typename _ForwardIterator, typename _Integer, |
255 | typename _UnaryPredicate> |
256 | _GLIBCXX20_CONSTEXPR |
257 | _ForwardIterator |
258 | __search_n(_ForwardIterator __first, _ForwardIterator __last, |
259 | _Integer __count, |
260 | _UnaryPredicate __unary_pred) |
261 | { |
262 | if (__count <= 0) |
263 | return __first; |
264 | |
265 | if (__count == 1) |
266 | return std::__find_if(__first, __last, __unary_pred); |
267 | |
268 | return std::__search_n_aux(__first, __last, __count, __unary_pred, |
269 | std::__iterator_category(__first)); |
270 | } |
271 | |
272 | // find_end for forward iterators. |
273 | template<typename _ForwardIterator1, typename _ForwardIterator2, |
274 | typename _BinaryPredicate> |
275 | _GLIBCXX20_CONSTEXPR |
276 | _ForwardIterator1 |
277 | __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
278 | _ForwardIterator2 __first2, _ForwardIterator2 __last2, |
279 | forward_iterator_tag, forward_iterator_tag, |
280 | _BinaryPredicate __comp) |
281 | { |
282 | if (__first2 == __last2) |
283 | return __last1; |
284 | |
285 | _ForwardIterator1 __result = __last1; |
286 | while (1) |
287 | { |
288 | _ForwardIterator1 __new_result |
289 | = std::__search(__first1, __last1, __first2, __last2, __comp); |
290 | if (__new_result == __last1) |
291 | return __result; |
292 | else |
293 | { |
294 | __result = __new_result; |
295 | __first1 = __new_result; |
296 | ++__first1; |
297 | } |
298 | } |
299 | } |
300 | |
301 | // find_end for bidirectional iterators (much faster). |
302 | template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, |
303 | typename _BinaryPredicate> |
304 | _GLIBCXX20_CONSTEXPR |
305 | _BidirectionalIterator1 |
306 | __find_end(_BidirectionalIterator1 __first1, |
307 | _BidirectionalIterator1 __last1, |
308 | _BidirectionalIterator2 __first2, |
309 | _BidirectionalIterator2 __last2, |
310 | bidirectional_iterator_tag, bidirectional_iterator_tag, |
311 | _BinaryPredicate __comp) |
312 | { |
313 | // concept requirements |
314 | __glibcxx_function_requires(_BidirectionalIteratorConcept< |
315 | _BidirectionalIterator1>) |
316 | __glibcxx_function_requires(_BidirectionalIteratorConcept< |
317 | _BidirectionalIterator2>) |
318 | |
319 | typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; |
320 | typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; |
321 | |
322 | _RevIterator1 __rlast1(__first1); |
323 | _RevIterator2 __rlast2(__first2); |
324 | _RevIterator1 __rresult = std::__search(_RevIterator1(__last1), __rlast1, |
325 | _RevIterator2(__last2), __rlast2, |
326 | __comp); |
327 | |
328 | if (__rresult == __rlast1) |
329 | return __last1; |
330 | else |
331 | { |
332 | _BidirectionalIterator1 __result = __rresult.base(); |
333 | std::advance(__result, -std::distance(__first2, __last2)); |
334 | return __result; |
335 | } |
336 | } |
337 | |
338 | /** |
339 | * @brief Find last matching subsequence in a sequence. |
340 | * @ingroup non_mutating_algorithms |
341 | * @param __first1 Start of range to search. |
342 | * @param __last1 End of range to search. |
343 | * @param __first2 Start of sequence to match. |
344 | * @param __last2 End of sequence to match. |
345 | * @return The last iterator @c i in the range |
346 | * @p [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == |
347 | * @p *(__first2+N) for each @c N in the range @p |
348 | * [0,__last2-__first2), or @p __last1 if no such iterator exists. |
349 | * |
350 | * Searches the range @p [__first1,__last1) for a sub-sequence that |
351 | * compares equal value-by-value with the sequence given by @p |
352 | * [__first2,__last2) and returns an iterator to the __first |
353 | * element of the sub-sequence, or @p __last1 if the sub-sequence |
354 | * is not found. The sub-sequence will be the last such |
355 | * subsequence contained in [__first1,__last1). |
356 | * |
357 | * Because the sub-sequence must lie completely within the range @p |
358 | * [__first1,__last1) it must start at a position less than @p |
359 | * __last1-(__last2-__first2) where @p __last2-__first2 is the |
360 | * length of the sub-sequence. This means that the returned |
361 | * iterator @c i will be in the range @p |
362 | * [__first1,__last1-(__last2-__first2)) |
363 | */ |
364 | template<typename _ForwardIterator1, typename _ForwardIterator2> |
365 | _GLIBCXX20_CONSTEXPR |
366 | inline _ForwardIterator1 |
367 | find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
368 | _ForwardIterator2 __first2, _ForwardIterator2 __last2) |
369 | { |
370 | // concept requirements |
371 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) |
372 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) |
373 | __glibcxx_function_requires(_EqualOpConcept< |
374 | typename iterator_traits<_ForwardIterator1>::value_type, |
375 | typename iterator_traits<_ForwardIterator2>::value_type>) |
376 | __glibcxx_requires_valid_range(__first1, __last1); |
377 | __glibcxx_requires_valid_range(__first2, __last2); |
378 | |
379 | return std::__find_end(__first1, __last1, __first2, __last2, |
380 | std::__iterator_category(__first1), |
381 | std::__iterator_category(__first2), |
382 | __gnu_cxx::__ops::__iter_equal_to_iter()); |
383 | } |
384 | |
385 | /** |
386 | * @brief Find last matching subsequence in a sequence using a predicate. |
387 | * @ingroup non_mutating_algorithms |
388 | * @param __first1 Start of range to search. |
389 | * @param __last1 End of range to search. |
390 | * @param __first2 Start of sequence to match. |
391 | * @param __last2 End of sequence to match. |
392 | * @param __comp The predicate to use. |
393 | * @return The last iterator @c i in the range @p |
394 | * [__first1,__last1-(__last2-__first2)) such that @c |
395 | * predicate(*(i+N), @p (__first2+N)) is true for each @c N in the |
396 | * range @p [0,__last2-__first2), or @p __last1 if no such iterator |
397 | * exists. |
398 | * |
399 | * Searches the range @p [__first1,__last1) for a sub-sequence that |
400 | * compares equal value-by-value with the sequence given by @p |
401 | * [__first2,__last2) using comp as a predicate and returns an |
402 | * iterator to the first element of the sub-sequence, or @p __last1 |
403 | * if the sub-sequence is not found. The sub-sequence will be the |
404 | * last such subsequence contained in [__first,__last1). |
405 | * |
406 | * Because the sub-sequence must lie completely within the range @p |
407 | * [__first1,__last1) it must start at a position less than @p |
408 | * __last1-(__last2-__first2) where @p __last2-__first2 is the |
409 | * length of the sub-sequence. This means that the returned |
410 | * iterator @c i will be in the range @p |
411 | * [__first1,__last1-(__last2-__first2)) |
412 | */ |
413 | template<typename _ForwardIterator1, typename _ForwardIterator2, |
414 | typename _BinaryPredicate> |
415 | _GLIBCXX20_CONSTEXPR |
416 | inline _ForwardIterator1 |
417 | find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
418 | _ForwardIterator2 __first2, _ForwardIterator2 __last2, |
419 | _BinaryPredicate __comp) |
420 | { |
421 | // concept requirements |
422 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) |
423 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) |
424 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
425 | typename iterator_traits<_ForwardIterator1>::value_type, |
426 | typename iterator_traits<_ForwardIterator2>::value_type>) |
427 | __glibcxx_requires_valid_range(__first1, __last1); |
428 | __glibcxx_requires_valid_range(__first2, __last2); |
429 | |
430 | return std::__find_end(__first1, __last1, __first2, __last2, |
431 | std::__iterator_category(__first1), |
432 | std::__iterator_category(__first2), |
433 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
434 | } |
435 | |
436 | #if __cplusplus201703L >= 201103L |
437 | /** |
438 | * @brief Checks that a predicate is true for all the elements |
439 | * of a sequence. |
440 | * @ingroup non_mutating_algorithms |
441 | * @param __first An input iterator. |
442 | * @param __last An input iterator. |
443 | * @param __pred A predicate. |
444 | * @return True if the check is true, false otherwise. |
445 | * |
446 | * Returns true if @p __pred is true for each element in the range |
447 | * @p [__first,__last), and false otherwise. |
448 | */ |
449 | template<typename _InputIterator, typename _Predicate> |
450 | _GLIBCXX20_CONSTEXPR |
451 | inline bool |
452 | all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) |
453 | { return __last == std::find_if_not(__first, __last, __pred); } |
454 | |
455 | /** |
456 | * @brief Checks that a predicate is false for all the elements |
457 | * of a sequence. |
458 | * @ingroup non_mutating_algorithms |
459 | * @param __first An input iterator. |
460 | * @param __last An input iterator. |
461 | * @param __pred A predicate. |
462 | * @return True if the check is true, false otherwise. |
463 | * |
464 | * Returns true if @p __pred is false for each element in the range |
465 | * @p [__first,__last), and false otherwise. |
466 | */ |
467 | template<typename _InputIterator, typename _Predicate> |
468 | _GLIBCXX20_CONSTEXPR |
469 | inline bool |
470 | none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) |
471 | { return __last == _GLIBCXX_STD_Astd::find_if(__first, __last, __pred); } |
472 | |
473 | /** |
474 | * @brief Checks that a predicate is false for at least an element |
475 | * of a sequence. |
476 | * @ingroup non_mutating_algorithms |
477 | * @param __first An input iterator. |
478 | * @param __last An input iterator. |
479 | * @param __pred A predicate. |
480 | * @return True if the check is true, false otherwise. |
481 | * |
482 | * Returns true if an element exists in the range @p |
483 | * [__first,__last) such that @p __pred is true, and false |
484 | * otherwise. |
485 | */ |
486 | template<typename _InputIterator, typename _Predicate> |
487 | _GLIBCXX20_CONSTEXPR |
488 | inline bool |
489 | any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) |
490 | { return !std::none_of(__first, __last, __pred); } |
491 | |
492 | /** |
493 | * @brief Find the first element in a sequence for which a |
494 | * predicate is false. |
495 | * @ingroup non_mutating_algorithms |
496 | * @param __first An input iterator. |
497 | * @param __last An input iterator. |
498 | * @param __pred A predicate. |
499 | * @return The first iterator @c i in the range @p [__first,__last) |
500 | * such that @p __pred(*i) is false, or @p __last if no such iterator exists. |
501 | */ |
502 | template<typename _InputIterator, typename _Predicate> |
503 | _GLIBCXX20_CONSTEXPR |
504 | inline _InputIterator |
505 | find_if_not(_InputIterator __first, _InputIterator __last, |
506 | _Predicate __pred) |
507 | { |
508 | // concept requirements |
509 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
510 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
511 | typename iterator_traits<_InputIterator>::value_type>) |
512 | __glibcxx_requires_valid_range(__first, __last); |
513 | return std::__find_if_not(__first, __last, |
514 | __gnu_cxx::__ops::__pred_iter(__pred)); |
515 | } |
516 | |
517 | /** |
518 | * @brief Checks whether the sequence is partitioned. |
519 | * @ingroup mutating_algorithms |
520 | * @param __first An input iterator. |
521 | * @param __last An input iterator. |
522 | * @param __pred A predicate. |
523 | * @return True if the range @p [__first,__last) is partioned by @p __pred, |
524 | * i.e. if all elements that satisfy @p __pred appear before those that |
525 | * do not. |
526 | */ |
527 | template<typename _InputIterator, typename _Predicate> |
528 | _GLIBCXX20_CONSTEXPR |
529 | inline bool |
530 | is_partitioned(_InputIterator __first, _InputIterator __last, |
531 | _Predicate __pred) |
532 | { |
533 | __first = std::find_if_not(__first, __last, __pred); |
534 | if (__first == __last) |
535 | return true; |
536 | ++__first; |
537 | return std::none_of(__first, __last, __pred); |
538 | } |
539 | |
540 | /** |
541 | * @brief Find the partition point of a partitioned range. |
542 | * @ingroup mutating_algorithms |
543 | * @param __first An iterator. |
544 | * @param __last Another iterator. |
545 | * @param __pred A predicate. |
546 | * @return An iterator @p mid such that @p all_of(__first, mid, __pred) |
547 | * and @p none_of(mid, __last, __pred) are both true. |
548 | */ |
549 | template<typename _ForwardIterator, typename _Predicate> |
550 | _GLIBCXX20_CONSTEXPR |
551 | _ForwardIterator |
552 | partition_point(_ForwardIterator __first, _ForwardIterator __last, |
553 | _Predicate __pred) |
554 | { |
555 | // concept requirements |
556 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
557 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
558 | typename iterator_traits<_ForwardIterator>::value_type>) |
559 | |
560 | // A specific debug-mode test will be necessary... |
561 | __glibcxx_requires_valid_range(__first, __last); |
562 | |
563 | typedef typename iterator_traits<_ForwardIterator>::difference_type |
564 | _DistanceType; |
565 | |
566 | _DistanceType __len = std::distance(__first, __last); |
567 | |
568 | while (__len > 0) |
569 | { |
570 | _DistanceType __half = __len >> 1; |
571 | _ForwardIterator __middle = __first; |
572 | std::advance(__middle, __half); |
573 | if (__pred(*__middle)) |
574 | { |
575 | __first = __middle; |
576 | ++__first; |
577 | __len = __len - __half - 1; |
578 | } |
579 | else |
580 | __len = __half; |
581 | } |
582 | return __first; |
583 | } |
584 | #endif |
585 | |
586 | template<typename _InputIterator, typename _OutputIterator, |
587 | typename _Predicate> |
588 | _GLIBCXX20_CONSTEXPR |
589 | _OutputIterator |
590 | __remove_copy_if(_InputIterator __first, _InputIterator __last, |
591 | _OutputIterator __result, _Predicate __pred) |
592 | { |
593 | for (; __first != __last; ++__first) |
594 | if (!__pred(__first)) |
595 | { |
596 | *__result = *__first; |
597 | ++__result; |
598 | } |
599 | return __result; |
600 | } |
601 | |
602 | /** |
603 | * @brief Copy a sequence, removing elements of a given value. |
604 | * @ingroup mutating_algorithms |
605 | * @param __first An input iterator. |
606 | * @param __last An input iterator. |
607 | * @param __result An output iterator. |
608 | * @param __value The value to be removed. |
609 | * @return An iterator designating the end of the resulting sequence. |
610 | * |
611 | * Copies each element in the range @p [__first,__last) not equal |
612 | * to @p __value to the range beginning at @p __result. |
613 | * remove_copy() is stable, so the relative order of elements that |
614 | * are copied is unchanged. |
615 | */ |
616 | template<typename _InputIterator, typename _OutputIterator, typename _Tp> |
617 | _GLIBCXX20_CONSTEXPR |
618 | inline _OutputIterator |
619 | remove_copy(_InputIterator __first, _InputIterator __last, |
620 | _OutputIterator __result, const _Tp& __value) |
621 | { |
622 | // concept requirements |
623 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
624 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
625 | typename iterator_traits<_InputIterator>::value_type>) |
626 | __glibcxx_function_requires(_EqualOpConcept< |
627 | typename iterator_traits<_InputIterator>::value_type, _Tp>) |
628 | __glibcxx_requires_valid_range(__first, __last); |
629 | |
630 | return std::__remove_copy_if(__first, __last, __result, |
631 | __gnu_cxx::__ops::__iter_equals_val(__value)); |
632 | } |
633 | |
634 | /** |
635 | * @brief Copy a sequence, removing elements for which a predicate is true. |
636 | * @ingroup mutating_algorithms |
637 | * @param __first An input iterator. |
638 | * @param __last An input iterator. |
639 | * @param __result An output iterator. |
640 | * @param __pred A predicate. |
641 | * @return An iterator designating the end of the resulting sequence. |
642 | * |
643 | * Copies each element in the range @p [__first,__last) for which |
644 | * @p __pred returns false to the range beginning at @p __result. |
645 | * |
646 | * remove_copy_if() is stable, so the relative order of elements that are |
647 | * copied is unchanged. |
648 | */ |
649 | template<typename _InputIterator, typename _OutputIterator, |
650 | typename _Predicate> |
651 | _GLIBCXX20_CONSTEXPR |
652 | inline _OutputIterator |
653 | remove_copy_if(_InputIterator __first, _InputIterator __last, |
654 | _OutputIterator __result, _Predicate __pred) |
655 | { |
656 | // concept requirements |
657 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
658 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
659 | typename iterator_traits<_InputIterator>::value_type>) |
660 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
661 | typename iterator_traits<_InputIterator>::value_type>) |
662 | __glibcxx_requires_valid_range(__first, __last); |
663 | |
664 | return std::__remove_copy_if(__first, __last, __result, |
665 | __gnu_cxx::__ops::__pred_iter(__pred)); |
666 | } |
667 | |
668 | #if __cplusplus201703L >= 201103L |
669 | /** |
670 | * @brief Copy the elements of a sequence for which a predicate is true. |
671 | * @ingroup mutating_algorithms |
672 | * @param __first An input iterator. |
673 | * @param __last An input iterator. |
674 | * @param __result An output iterator. |
675 | * @param __pred A predicate. |
676 | * @return An iterator designating the end of the resulting sequence. |
677 | * |
678 | * Copies each element in the range @p [__first,__last) for which |
679 | * @p __pred returns true to the range beginning at @p __result. |
680 | * |
681 | * copy_if() is stable, so the relative order of elements that are |
682 | * copied is unchanged. |
683 | */ |
684 | template<typename _InputIterator, typename _OutputIterator, |
685 | typename _Predicate> |
686 | _GLIBCXX20_CONSTEXPR |
687 | _OutputIterator |
688 | copy_if(_InputIterator __first, _InputIterator __last, |
689 | _OutputIterator __result, _Predicate __pred) |
690 | { |
691 | // concept requirements |
692 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
693 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
694 | typename iterator_traits<_InputIterator>::value_type>) |
695 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
696 | typename iterator_traits<_InputIterator>::value_type>) |
697 | __glibcxx_requires_valid_range(__first, __last); |
698 | |
699 | for (; __first != __last; ++__first) |
700 | if (__pred(*__first)) |
701 | { |
702 | *__result = *__first; |
703 | ++__result; |
704 | } |
705 | return __result; |
706 | } |
707 | |
708 | template<typename _InputIterator, typename _Size, typename _OutputIterator> |
709 | _GLIBCXX20_CONSTEXPR |
710 | _OutputIterator |
711 | __copy_n_a(_InputIterator __first, _Size __n, _OutputIterator __result) |
712 | { |
713 | if (__n > 0) |
714 | { |
715 | while (true) |
716 | { |
717 | *__result = *__first; |
718 | ++__result; |
719 | if (--__n > 0) |
720 | ++__first; |
721 | else |
722 | break; |
723 | } |
724 | } |
725 | return __result; |
726 | } |
727 | |
728 | template<typename _CharT, typename _Size> |
729 | __enable_if_t<__is_char<_CharT>::__value, _CharT*> |
730 | __copy_n_a(istreambuf_iterator<_CharT, char_traits<_CharT>>, |
731 | _Size, _CharT*); |
732 | |
733 | template<typename _InputIterator, typename _Size, typename _OutputIterator> |
734 | _GLIBCXX20_CONSTEXPR |
735 | _OutputIterator |
736 | __copy_n(_InputIterator __first, _Size __n, |
737 | _OutputIterator __result, input_iterator_tag) |
738 | { |
739 | return std::__niter_wrap(__result, |
740 | __copy_n_a(__first, __n, |
741 | std::__niter_base(__result))); |
742 | } |
743 | |
744 | template<typename _RandomAccessIterator, typename _Size, |
745 | typename _OutputIterator> |
746 | _GLIBCXX20_CONSTEXPR |
747 | inline _OutputIterator |
748 | __copy_n(_RandomAccessIterator __first, _Size __n, |
749 | _OutputIterator __result, random_access_iterator_tag) |
750 | { return std::copy(__first, __first + __n, __result); } |
751 | |
752 | /** |
753 | * @brief Copies the range [first,first+n) into [result,result+n). |
754 | * @ingroup mutating_algorithms |
755 | * @param __first An input iterator. |
756 | * @param __n The number of elements to copy. |
757 | * @param __result An output iterator. |
758 | * @return result+n. |
759 | * |
760 | * This inline function will boil down to a call to @c memmove whenever |
761 | * possible. Failing that, if random access iterators are passed, then the |
762 | * loop count will be known (and therefore a candidate for compiler |
763 | * optimizations such as unrolling). |
764 | */ |
765 | template<typename _InputIterator, typename _Size, typename _OutputIterator> |
766 | _GLIBCXX20_CONSTEXPR |
767 | inline _OutputIterator |
768 | copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) |
769 | { |
770 | // concept requirements |
771 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
772 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
773 | typename iterator_traits<_InputIterator>::value_type>) |
774 | __glibcxx_requires_can_increment(__first, __n); |
775 | __glibcxx_requires_can_increment(__result, __n); |
776 | |
777 | return std::__copy_n(__first, __n, __result, |
778 | std::__iterator_category(__first)); |
779 | } |
780 | |
781 | /** |
782 | * @brief Copy the elements of a sequence to separate output sequences |
783 | * depending on the truth value of a predicate. |
784 | * @ingroup mutating_algorithms |
785 | * @param __first An input iterator. |
786 | * @param __last An input iterator. |
787 | * @param __out_true An output iterator. |
788 | * @param __out_false An output iterator. |
789 | * @param __pred A predicate. |
790 | * @return A pair designating the ends of the resulting sequences. |
791 | * |
792 | * Copies each element in the range @p [__first,__last) for which |
793 | * @p __pred returns true to the range beginning at @p out_true |
794 | * and each element for which @p __pred returns false to @p __out_false. |
795 | */ |
796 | template<typename _InputIterator, typename _OutputIterator1, |
797 | typename _OutputIterator2, typename _Predicate> |
798 | _GLIBCXX20_CONSTEXPR |
799 | pair<_OutputIterator1, _OutputIterator2> |
800 | partition_copy(_InputIterator __first, _InputIterator __last, |
801 | _OutputIterator1 __out_true, _OutputIterator2 __out_false, |
802 | _Predicate __pred) |
803 | { |
804 | // concept requirements |
805 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
806 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator1, |
807 | typename iterator_traits<_InputIterator>::value_type>) |
808 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator2, |
809 | typename iterator_traits<_InputIterator>::value_type>) |
810 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
811 | typename iterator_traits<_InputIterator>::value_type>) |
812 | __glibcxx_requires_valid_range(__first, __last); |
813 | |
814 | for (; __first != __last; ++__first) |
815 | if (__pred(*__first)) |
816 | { |
817 | *__out_true = *__first; |
818 | ++__out_true; |
819 | } |
820 | else |
821 | { |
822 | *__out_false = *__first; |
823 | ++__out_false; |
824 | } |
825 | |
826 | return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); |
827 | } |
828 | #endif // C++11 |
829 | |
830 | template<typename _ForwardIterator, typename _Predicate> |
831 | _GLIBCXX20_CONSTEXPR |
832 | _ForwardIterator |
833 | __remove_if(_ForwardIterator __first, _ForwardIterator __last, |
834 | _Predicate __pred) |
835 | { |
836 | __first = std::__find_if(__first, __last, __pred); |
837 | if (__first == __last) |
838 | return __first; |
839 | _ForwardIterator __result = __first; |
840 | ++__first; |
841 | for (; __first != __last; ++__first) |
842 | if (!__pred(__first)) |
843 | { |
844 | *__result = _GLIBCXX_MOVE(*__first)std::move(*__first); |
845 | ++__result; |
846 | } |
847 | return __result; |
848 | } |
849 | |
850 | /** |
851 | * @brief Remove elements from a sequence. |
852 | * @ingroup mutating_algorithms |
853 | * @param __first An input iterator. |
854 | * @param __last An input iterator. |
855 | * @param __value The value to be removed. |
856 | * @return An iterator designating the end of the resulting sequence. |
857 | * |
858 | * All elements equal to @p __value are removed from the range |
859 | * @p [__first,__last). |
860 | * |
861 | * remove() is stable, so the relative order of elements that are |
862 | * not removed is unchanged. |
863 | * |
864 | * Elements between the end of the resulting sequence and @p __last |
865 | * are still present, but their value is unspecified. |
866 | */ |
867 | template<typename _ForwardIterator, typename _Tp> |
868 | _GLIBCXX20_CONSTEXPR |
869 | inline _ForwardIterator |
870 | remove(_ForwardIterator __first, _ForwardIterator __last, |
871 | const _Tp& __value) |
872 | { |
873 | // concept requirements |
874 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
875 | _ForwardIterator>) |
876 | __glibcxx_function_requires(_EqualOpConcept< |
877 | typename iterator_traits<_ForwardIterator>::value_type, _Tp>) |
878 | __glibcxx_requires_valid_range(__first, __last); |
879 | |
880 | return std::__remove_if(__first, __last, |
881 | __gnu_cxx::__ops::__iter_equals_val(__value)); |
882 | } |
883 | |
884 | /** |
885 | * @brief Remove elements from a sequence using a predicate. |
886 | * @ingroup mutating_algorithms |
887 | * @param __first A forward iterator. |
888 | * @param __last A forward iterator. |
889 | * @param __pred A predicate. |
890 | * @return An iterator designating the end of the resulting sequence. |
891 | * |
892 | * All elements for which @p __pred returns true are removed from the range |
893 | * @p [__first,__last). |
894 | * |
895 | * remove_if() is stable, so the relative order of elements that are |
896 | * not removed is unchanged. |
897 | * |
898 | * Elements between the end of the resulting sequence and @p __last |
899 | * are still present, but their value is unspecified. |
900 | */ |
901 | template<typename _ForwardIterator, typename _Predicate> |
902 | _GLIBCXX20_CONSTEXPR |
903 | inline _ForwardIterator |
904 | remove_if(_ForwardIterator __first, _ForwardIterator __last, |
905 | _Predicate __pred) |
906 | { |
907 | // concept requirements |
908 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
909 | _ForwardIterator>) |
910 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
911 | typename iterator_traits<_ForwardIterator>::value_type>) |
912 | __glibcxx_requires_valid_range(__first, __last); |
913 | |
914 | return std::__remove_if(__first, __last, |
915 | __gnu_cxx::__ops::__pred_iter(__pred)); |
916 | } |
917 | |
918 | template<typename _ForwardIterator, typename _BinaryPredicate> |
919 | _GLIBCXX20_CONSTEXPR |
920 | _ForwardIterator |
921 | __adjacent_find(_ForwardIterator __first, _ForwardIterator __last, |
922 | _BinaryPredicate __binary_pred) |
923 | { |
924 | if (__first == __last) |
925 | return __last; |
926 | _ForwardIterator __next = __first; |
927 | while (++__next != __last) |
928 | { |
929 | if (__binary_pred(__first, __next)) |
930 | return __first; |
931 | __first = __next; |
932 | } |
933 | return __last; |
934 | } |
935 | |
936 | template<typename _ForwardIterator, typename _BinaryPredicate> |
937 | _GLIBCXX20_CONSTEXPR |
938 | _ForwardIterator |
939 | __unique(_ForwardIterator __first, _ForwardIterator __last, |
940 | _BinaryPredicate __binary_pred) |
941 | { |
942 | // Skip the beginning, if already unique. |
943 | __first = std::__adjacent_find(__first, __last, __binary_pred); |
944 | if (__first == __last) |
945 | return __last; |
946 | |
947 | // Do the real copy work. |
948 | _ForwardIterator __dest = __first; |
949 | ++__first; |
950 | while (++__first != __last) |
951 | if (!__binary_pred(__dest, __first)) |
952 | *++__dest = _GLIBCXX_MOVE(*__first)std::move(*__first); |
953 | return ++__dest; |
954 | } |
955 | |
956 | /** |
957 | * @brief Remove consecutive duplicate values from a sequence. |
958 | * @ingroup mutating_algorithms |
959 | * @param __first A forward iterator. |
960 | * @param __last A forward iterator. |
961 | * @return An iterator designating the end of the resulting sequence. |
962 | * |
963 | * Removes all but the first element from each group of consecutive |
964 | * values that compare equal. |
965 | * unique() is stable, so the relative order of elements that are |
966 | * not removed is unchanged. |
967 | * Elements between the end of the resulting sequence and @p __last |
968 | * are still present, but their value is unspecified. |
969 | */ |
970 | template<typename _ForwardIterator> |
971 | _GLIBCXX20_CONSTEXPR |
972 | inline _ForwardIterator |
973 | unique(_ForwardIterator __first, _ForwardIterator __last) |
974 | { |
975 | // concept requirements |
976 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
977 | _ForwardIterator>) |
978 | __glibcxx_function_requires(_EqualityComparableConcept< |
979 | typename iterator_traits<_ForwardIterator>::value_type>) |
980 | __glibcxx_requires_valid_range(__first, __last); |
981 | |
982 | return std::__unique(__first, __last, |
983 | __gnu_cxx::__ops::__iter_equal_to_iter()); |
984 | } |
985 | |
986 | /** |
987 | * @brief Remove consecutive values from a sequence using a predicate. |
988 | * @ingroup mutating_algorithms |
989 | * @param __first A forward iterator. |
990 | * @param __last A forward iterator. |
991 | * @param __binary_pred A binary predicate. |
992 | * @return An iterator designating the end of the resulting sequence. |
993 | * |
994 | * Removes all but the first element from each group of consecutive |
995 | * values for which @p __binary_pred returns true. |
996 | * unique() is stable, so the relative order of elements that are |
997 | * not removed is unchanged. |
998 | * Elements between the end of the resulting sequence and @p __last |
999 | * are still present, but their value is unspecified. |
1000 | */ |
1001 | template<typename _ForwardIterator, typename _BinaryPredicate> |
1002 | _GLIBCXX20_CONSTEXPR |
1003 | inline _ForwardIterator |
1004 | unique(_ForwardIterator __first, _ForwardIterator __last, |
1005 | _BinaryPredicate __binary_pred) |
1006 | { |
1007 | // concept requirements |
1008 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
1009 | _ForwardIterator>) |
1010 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
1011 | typename iterator_traits<_ForwardIterator>::value_type, |
1012 | typename iterator_traits<_ForwardIterator>::value_type>) |
1013 | __glibcxx_requires_valid_range(__first, __last); |
1014 | |
1015 | return std::__unique(__first, __last, |
1016 | __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); |
1017 | } |
1018 | |
1019 | /** |
1020 | * This is an uglified |
1021 | * unique_copy(_InputIterator, _InputIterator, _OutputIterator, |
1022 | * _BinaryPredicate) |
1023 | * overloaded for forward iterators and output iterator as result. |
1024 | */ |
1025 | template<typename _ForwardIterator, typename _OutputIterator, |
1026 | typename _BinaryPredicate> |
1027 | _GLIBCXX20_CONSTEXPR |
1028 | _OutputIterator |
1029 | __unique_copy(_ForwardIterator __first, _ForwardIterator __last, |
1030 | _OutputIterator __result, _BinaryPredicate __binary_pred, |
1031 | forward_iterator_tag, output_iterator_tag) |
1032 | { |
1033 | // concept requirements -- iterators already checked |
1034 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
1035 | typename iterator_traits<_ForwardIterator>::value_type, |
1036 | typename iterator_traits<_ForwardIterator>::value_type>) |
1037 | |
1038 | _ForwardIterator __next = __first; |
1039 | *__result = *__first; |
1040 | while (++__next != __last) |
1041 | if (!__binary_pred(__first, __next)) |
1042 | { |
1043 | __first = __next; |
1044 | *++__result = *__first; |
1045 | } |
1046 | return ++__result; |
1047 | } |
1048 | |
1049 | /** |
1050 | * This is an uglified |
1051 | * unique_copy(_InputIterator, _InputIterator, _OutputIterator, |
1052 | * _BinaryPredicate) |
1053 | * overloaded for input iterators and output iterator as result. |
1054 | */ |
1055 | template<typename _InputIterator, typename _OutputIterator, |
1056 | typename _BinaryPredicate> |
1057 | _GLIBCXX20_CONSTEXPR |
1058 | _OutputIterator |
1059 | __unique_copy(_InputIterator __first, _InputIterator __last, |
1060 | _OutputIterator __result, _BinaryPredicate __binary_pred, |
1061 | input_iterator_tag, output_iterator_tag) |
1062 | { |
1063 | // concept requirements -- iterators already checked |
1064 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
1065 | typename iterator_traits<_InputIterator>::value_type, |
1066 | typename iterator_traits<_InputIterator>::value_type>) |
1067 | |
1068 | typename iterator_traits<_InputIterator>::value_type __value = *__first; |
1069 | __decltype(__gnu_cxx::__ops::__iter_comp_val(__binary_pred)) |
1070 | __rebound_pred |
1071 | = __gnu_cxx::__ops::__iter_comp_val(__binary_pred); |
1072 | *__result = __value; |
1073 | while (++__first != __last) |
1074 | if (!__rebound_pred(__first, __value)) |
1075 | { |
1076 | __value = *__first; |
1077 | *++__result = __value; |
1078 | } |
1079 | return ++__result; |
1080 | } |
1081 | |
1082 | /** |
1083 | * This is an uglified |
1084 | * unique_copy(_InputIterator, _InputIterator, _OutputIterator, |
1085 | * _BinaryPredicate) |
1086 | * overloaded for input iterators and forward iterator as result. |
1087 | */ |
1088 | template<typename _InputIterator, typename _ForwardIterator, |
1089 | typename _BinaryPredicate> |
1090 | _GLIBCXX20_CONSTEXPR |
1091 | _ForwardIterator |
1092 | __unique_copy(_InputIterator __first, _InputIterator __last, |
1093 | _ForwardIterator __result, _BinaryPredicate __binary_pred, |
1094 | input_iterator_tag, forward_iterator_tag) |
1095 | { |
1096 | // concept requirements -- iterators already checked |
1097 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
1098 | typename iterator_traits<_ForwardIterator>::value_type, |
1099 | typename iterator_traits<_InputIterator>::value_type>) |
1100 | *__result = *__first; |
1101 | while (++__first != __last) |
1102 | if (!__binary_pred(__result, __first)) |
1103 | *++__result = *__first; |
1104 | return ++__result; |
1105 | } |
1106 | |
1107 | /** |
1108 | * This is an uglified reverse(_BidirectionalIterator, |
1109 | * _BidirectionalIterator) |
1110 | * overloaded for bidirectional iterators. |
1111 | */ |
1112 | template<typename _BidirectionalIterator> |
1113 | _GLIBCXX20_CONSTEXPR |
1114 | void |
1115 | __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, |
1116 | bidirectional_iterator_tag) |
1117 | { |
1118 | while (true) |
1119 | if (__first == __last || __first == --__last) |
1120 | return; |
1121 | else |
1122 | { |
1123 | std::iter_swap(__first, __last); |
1124 | ++__first; |
1125 | } |
1126 | } |
1127 | |
1128 | /** |
1129 | * This is an uglified reverse(_BidirectionalIterator, |
1130 | * _BidirectionalIterator) |
1131 | * overloaded for random access iterators. |
1132 | */ |
1133 | template<typename _RandomAccessIterator> |
1134 | _GLIBCXX20_CONSTEXPR |
1135 | void |
1136 | __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, |
1137 | random_access_iterator_tag) |
1138 | { |
1139 | if (__first == __last) |
1140 | return; |
1141 | --__last; |
1142 | while (__first < __last) |
1143 | { |
1144 | std::iter_swap(__first, __last); |
1145 | ++__first; |
1146 | --__last; |
1147 | } |
1148 | } |
1149 | |
1150 | /** |
1151 | * @brief Reverse a sequence. |
1152 | * @ingroup mutating_algorithms |
1153 | * @param __first A bidirectional iterator. |
1154 | * @param __last A bidirectional iterator. |
1155 | * @return reverse() returns no value. |
1156 | * |
1157 | * Reverses the order of the elements in the range @p [__first,__last), |
1158 | * so that the first element becomes the last etc. |
1159 | * For every @c i such that @p 0<=i<=(__last-__first)/2), @p reverse() |
1160 | * swaps @p *(__first+i) and @p *(__last-(i+1)) |
1161 | */ |
1162 | template<typename _BidirectionalIterator> |
1163 | _GLIBCXX20_CONSTEXPR |
1164 | inline void |
1165 | reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) |
1166 | { |
1167 | // concept requirements |
1168 | __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< |
1169 | _BidirectionalIterator>) |
1170 | __glibcxx_requires_valid_range(__first, __last); |
1171 | std::__reverse(__first, __last, std::__iterator_category(__first)); |
1172 | } |
1173 | |
1174 | /** |
1175 | * @brief Copy a sequence, reversing its elements. |
1176 | * @ingroup mutating_algorithms |
1177 | * @param __first A bidirectional iterator. |
1178 | * @param __last A bidirectional iterator. |
1179 | * @param __result An output iterator. |
1180 | * @return An iterator designating the end of the resulting sequence. |
1181 | * |
1182 | * Copies the elements in the range @p [__first,__last) to the |
1183 | * range @p [__result,__result+(__last-__first)) such that the |
1184 | * order of the elements is reversed. For every @c i such that @p |
1185 | * 0<=i<=(__last-__first), @p reverse_copy() performs the |
1186 | * assignment @p *(__result+(__last-__first)-1-i) = *(__first+i). |
1187 | * The ranges @p [__first,__last) and @p |
1188 | * [__result,__result+(__last-__first)) must not overlap. |
1189 | */ |
1190 | template<typename _BidirectionalIterator, typename _OutputIterator> |
1191 | _GLIBCXX20_CONSTEXPR |
1192 | _OutputIterator |
1193 | reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, |
1194 | _OutputIterator __result) |
1195 | { |
1196 | // concept requirements |
1197 | __glibcxx_function_requires(_BidirectionalIteratorConcept< |
1198 | _BidirectionalIterator>) |
1199 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
1200 | typename iterator_traits<_BidirectionalIterator>::value_type>) |
1201 | __glibcxx_requires_valid_range(__first, __last); |
1202 | |
1203 | while (__first != __last) |
1204 | { |
1205 | --__last; |
1206 | *__result = *__last; |
1207 | ++__result; |
1208 | } |
1209 | return __result; |
1210 | } |
1211 | |
1212 | /** |
1213 | * This is a helper function for the rotate algorithm specialized on RAIs. |
1214 | * It returns the greatest common divisor of two integer values. |
1215 | */ |
1216 | template<typename _EuclideanRingElement> |
1217 | _GLIBCXX20_CONSTEXPR |
1218 | _EuclideanRingElement |
1219 | __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) |
1220 | { |
1221 | while (__n != 0) |
1222 | { |
1223 | _EuclideanRingElement __t = __m % __n; |
1224 | __m = __n; |
1225 | __n = __t; |
1226 | } |
1227 | return __m; |
1228 | } |
1229 | |
1230 | inline namespace _V2 |
1231 | { |
1232 | |
1233 | /// This is a helper function for the rotate algorithm. |
1234 | template<typename _ForwardIterator> |
1235 | _GLIBCXX20_CONSTEXPR |
1236 | _ForwardIterator |
1237 | __rotate(_ForwardIterator __first, |
1238 | _ForwardIterator __middle, |
1239 | _ForwardIterator __last, |
1240 | forward_iterator_tag) |
1241 | { |
1242 | if (__first == __middle) |
1243 | return __last; |
1244 | else if (__last == __middle) |
1245 | return __first; |
1246 | |
1247 | _ForwardIterator __first2 = __middle; |
1248 | do |
1249 | { |
1250 | std::iter_swap(__first, __first2); |
1251 | ++__first; |
1252 | ++__first2; |
1253 | if (__first == __middle) |
1254 | __middle = __first2; |
1255 | } |
1256 | while (__first2 != __last); |
1257 | |
1258 | _ForwardIterator __ret = __first; |
1259 | |
1260 | __first2 = __middle; |
1261 | |
1262 | while (__first2 != __last) |
1263 | { |
1264 | std::iter_swap(__first, __first2); |
1265 | ++__first; |
1266 | ++__first2; |
1267 | if (__first == __middle) |
1268 | __middle = __first2; |
1269 | else if (__first2 == __last) |
1270 | __first2 = __middle; |
1271 | } |
1272 | return __ret; |
1273 | } |
1274 | |
1275 | /// This is a helper function for the rotate algorithm. |
1276 | template<typename _BidirectionalIterator> |
1277 | _GLIBCXX20_CONSTEXPR |
1278 | _BidirectionalIterator |
1279 | __rotate(_BidirectionalIterator __first, |
1280 | _BidirectionalIterator __middle, |
1281 | _BidirectionalIterator __last, |
1282 | bidirectional_iterator_tag) |
1283 | { |
1284 | // concept requirements |
1285 | __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< |
1286 | _BidirectionalIterator>) |
1287 | |
1288 | if (__first == __middle) |
1289 | return __last; |
1290 | else if (__last == __middle) |
1291 | return __first; |
1292 | |
1293 | std::__reverse(__first, __middle, bidirectional_iterator_tag()); |
1294 | std::__reverse(__middle, __last, bidirectional_iterator_tag()); |
1295 | |
1296 | while (__first != __middle && __middle != __last) |
1297 | { |
1298 | std::iter_swap(__first, --__last); |
1299 | ++__first; |
1300 | } |
1301 | |
1302 | if (__first == __middle) |
1303 | { |
1304 | std::__reverse(__middle, __last, bidirectional_iterator_tag()); |
1305 | return __last; |
1306 | } |
1307 | else |
1308 | { |
1309 | std::__reverse(__first, __middle, bidirectional_iterator_tag()); |
1310 | return __first; |
1311 | } |
1312 | } |
1313 | |
1314 | /// This is a helper function for the rotate algorithm. |
1315 | template<typename _RandomAccessIterator> |
1316 | _GLIBCXX20_CONSTEXPR |
1317 | _RandomAccessIterator |
1318 | __rotate(_RandomAccessIterator __first, |
1319 | _RandomAccessIterator __middle, |
1320 | _RandomAccessIterator __last, |
1321 | random_access_iterator_tag) |
1322 | { |
1323 | // concept requirements |
1324 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
1325 | _RandomAccessIterator>) |
1326 | |
1327 | if (__first == __middle) |
1328 | return __last; |
1329 | else if (__last == __middle) |
1330 | return __first; |
1331 | |
1332 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type |
1333 | _Distance; |
1334 | typedef typename iterator_traits<_RandomAccessIterator>::value_type |
1335 | _ValueType; |
1336 | |
1337 | _Distance __n = __last - __first; |
1338 | _Distance __k = __middle - __first; |
1339 | |
1340 | if (__k == __n - __k) |
1341 | { |
1342 | std::swap_ranges(__first, __middle, __middle); |
1343 | return __middle; |
1344 | } |
1345 | |
1346 | _RandomAccessIterator __p = __first; |
1347 | _RandomAccessIterator __ret = __first + (__last - __middle); |
1348 | |
1349 | for (;;) |
1350 | { |
1351 | if (__k < __n - __k) |
1352 | { |
1353 | if (__is_pod(_ValueType) && __k == 1) |
1354 | { |
1355 | _ValueType __t = _GLIBCXX_MOVE(*__p)std::move(*__p); |
1356 | _GLIBCXX_MOVE3(__p + 1, __p + __n, __p)std::move(__p + 1, __p + __n, __p); |
1357 | *(__p + __n - 1) = _GLIBCXX_MOVE(__t)std::move(__t); |
1358 | return __ret; |
1359 | } |
1360 | _RandomAccessIterator __q = __p + __k; |
1361 | for (_Distance __i = 0; __i < __n - __k; ++ __i) |
1362 | { |
1363 | std::iter_swap(__p, __q); |
1364 | ++__p; |
1365 | ++__q; |
1366 | } |
1367 | __n %= __k; |
1368 | if (__n == 0) |
1369 | return __ret; |
1370 | std::swap(__n, __k); |
1371 | __k = __n - __k; |
1372 | } |
1373 | else |
1374 | { |
1375 | __k = __n - __k; |
1376 | if (__is_pod(_ValueType) && __k == 1) |
1377 | { |
1378 | _ValueType __t = _GLIBCXX_MOVE(*(__p + __n - 1))std::move(*(__p + __n - 1)); |
1379 | _GLIBCXX_MOVE_BACKWARD3(__p, __p + __n - 1, __p + __n)std::move_backward(__p, __p + __n - 1, __p + __n); |
1380 | *__p = _GLIBCXX_MOVE(__t)std::move(__t); |
1381 | return __ret; |
1382 | } |
1383 | _RandomAccessIterator __q = __p + __n; |
1384 | __p = __q - __k; |
1385 | for (_Distance __i = 0; __i < __n - __k; ++ __i) |
1386 | { |
1387 | --__p; |
1388 | --__q; |
1389 | std::iter_swap(__p, __q); |
1390 | } |
1391 | __n %= __k; |
1392 | if (__n == 0) |
1393 | return __ret; |
1394 | std::swap(__n, __k); |
1395 | } |
1396 | } |
1397 | } |
1398 | |
1399 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1400 | // DR 488. rotate throws away useful information |
1401 | /** |
1402 | * @brief Rotate the elements of a sequence. |
1403 | * @ingroup mutating_algorithms |
1404 | * @param __first A forward iterator. |
1405 | * @param __middle A forward iterator. |
1406 | * @param __last A forward iterator. |
1407 | * @return first + (last - middle). |
1408 | * |
1409 | * Rotates the elements of the range @p [__first,__last) by |
1410 | * @p (__middle - __first) positions so that the element at @p __middle |
1411 | * is moved to @p __first, the element at @p __middle+1 is moved to |
1412 | * @p __first+1 and so on for each element in the range |
1413 | * @p [__first,__last). |
1414 | * |
1415 | * This effectively swaps the ranges @p [__first,__middle) and |
1416 | * @p [__middle,__last). |
1417 | * |
1418 | * Performs |
1419 | * @p *(__first+(n+(__last-__middle))%(__last-__first))=*(__first+n) |
1420 | * for each @p n in the range @p [0,__last-__first). |
1421 | */ |
1422 | template<typename _ForwardIterator> |
1423 | _GLIBCXX20_CONSTEXPR |
1424 | inline _ForwardIterator |
1425 | rotate(_ForwardIterator __first, _ForwardIterator __middle, |
1426 | _ForwardIterator __last) |
1427 | { |
1428 | // concept requirements |
1429 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
1430 | _ForwardIterator>) |
1431 | __glibcxx_requires_valid_range(__first, __middle); |
1432 | __glibcxx_requires_valid_range(__middle, __last); |
1433 | |
1434 | return std::__rotate(__first, __middle, __last, |
1435 | std::__iterator_category(__first)); |
1436 | } |
1437 | |
1438 | } // namespace _V2 |
1439 | |
1440 | /** |
1441 | * @brief Copy a sequence, rotating its elements. |
1442 | * @ingroup mutating_algorithms |
1443 | * @param __first A forward iterator. |
1444 | * @param __middle A forward iterator. |
1445 | * @param __last A forward iterator. |
1446 | * @param __result An output iterator. |
1447 | * @return An iterator designating the end of the resulting sequence. |
1448 | * |
1449 | * Copies the elements of the range @p [__first,__last) to the |
1450 | * range beginning at @result, rotating the copied elements by |
1451 | * @p (__middle-__first) positions so that the element at @p __middle |
1452 | * is moved to @p __result, the element at @p __middle+1 is moved |
1453 | * to @p __result+1 and so on for each element in the range @p |
1454 | * [__first,__last). |
1455 | * |
1456 | * Performs |
1457 | * @p *(__result+(n+(__last-__middle))%(__last-__first))=*(__first+n) |
1458 | * for each @p n in the range @p [0,__last-__first). |
1459 | */ |
1460 | template<typename _ForwardIterator, typename _OutputIterator> |
1461 | _GLIBCXX20_CONSTEXPR |
1462 | inline _OutputIterator |
1463 | rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, |
1464 | _ForwardIterator __last, _OutputIterator __result) |
1465 | { |
1466 | // concept requirements |
1467 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
1468 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
1469 | typename iterator_traits<_ForwardIterator>::value_type>) |
1470 | __glibcxx_requires_valid_range(__first, __middle); |
1471 | __glibcxx_requires_valid_range(__middle, __last); |
1472 | |
1473 | return std::copy(__first, __middle, |
1474 | std::copy(__middle, __last, __result)); |
1475 | } |
1476 | |
1477 | /// This is a helper function... |
1478 | template<typename _ForwardIterator, typename _Predicate> |
1479 | _GLIBCXX20_CONSTEXPR |
1480 | _ForwardIterator |
1481 | __partition(_ForwardIterator __first, _ForwardIterator __last, |
1482 | _Predicate __pred, forward_iterator_tag) |
1483 | { |
1484 | if (__first == __last) |
1485 | return __first; |
1486 | |
1487 | while (__pred(*__first)) |
1488 | if (++__first == __last) |
1489 | return __first; |
1490 | |
1491 | _ForwardIterator __next = __first; |
1492 | |
1493 | while (++__next != __last) |
1494 | if (__pred(*__next)) |
1495 | { |
1496 | std::iter_swap(__first, __next); |
1497 | ++__first; |
1498 | } |
1499 | |
1500 | return __first; |
1501 | } |
1502 | |
1503 | /// This is a helper function... |
1504 | template<typename _BidirectionalIterator, typename _Predicate> |
1505 | _GLIBCXX20_CONSTEXPR |
1506 | _BidirectionalIterator |
1507 | __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, |
1508 | _Predicate __pred, bidirectional_iterator_tag) |
1509 | { |
1510 | while (true) |
1511 | { |
1512 | while (true) |
1513 | if (__first == __last) |
1514 | return __first; |
1515 | else if (__pred(*__first)) |
1516 | ++__first; |
1517 | else |
1518 | break; |
1519 | --__last; |
1520 | while (true) |
1521 | if (__first == __last) |
1522 | return __first; |
1523 | else if (!bool(__pred(*__last))) |
1524 | --__last; |
1525 | else |
1526 | break; |
1527 | std::iter_swap(__first, __last); |
1528 | ++__first; |
1529 | } |
1530 | } |
1531 | |
1532 | // partition |
1533 | |
1534 | /// This is a helper function... |
1535 | /// Requires __first != __last and !__pred(__first) |
1536 | /// and __len == distance(__first, __last). |
1537 | /// |
1538 | /// !__pred(__first) allows us to guarantee that we don't |
1539 | /// move-assign an element onto itself. |
1540 | template<typename _ForwardIterator, typename _Pointer, typename _Predicate, |
1541 | typename _Distance> |
1542 | _ForwardIterator |
1543 | __stable_partition_adaptive(_ForwardIterator __first, |
1544 | _ForwardIterator __last, |
1545 | _Predicate __pred, _Distance __len, |
1546 | _Pointer __buffer, |
1547 | _Distance __buffer_size) |
1548 | { |
1549 | if (__len == 1) |
1550 | return __first; |
1551 | |
1552 | if (__len <= __buffer_size) |
1553 | { |
1554 | _ForwardIterator __result1 = __first; |
1555 | _Pointer __result2 = __buffer; |
1556 | |
1557 | // The precondition guarantees that !__pred(__first), so |
1558 | // move that element to the buffer before starting the loop. |
1559 | // This ensures that we only call __pred once per element. |
1560 | *__result2 = _GLIBCXX_MOVE(*__first)std::move(*__first); |
1561 | ++__result2; |
1562 | ++__first; |
1563 | for (; __first != __last; ++__first) |
1564 | if (__pred(__first)) |
1565 | { |
1566 | *__result1 = _GLIBCXX_MOVE(*__first)std::move(*__first); |
1567 | ++__result1; |
1568 | } |
1569 | else |
1570 | { |
1571 | *__result2 = _GLIBCXX_MOVE(*__first)std::move(*__first); |
1572 | ++__result2; |
1573 | } |
1574 | |
1575 | _GLIBCXX_MOVE3(__buffer, __result2, __result1)std::move(__buffer, __result2, __result1); |
1576 | return __result1; |
1577 | } |
1578 | |
1579 | _ForwardIterator __middle = __first; |
1580 | std::advance(__middle, __len / 2); |
1581 | _ForwardIterator __left_split = |
1582 | std::__stable_partition_adaptive(__first, __middle, __pred, |
1583 | __len / 2, __buffer, |
1584 | __buffer_size); |
1585 | |
1586 | // Advance past true-predicate values to satisfy this |
1587 | // function's preconditions. |
1588 | _Distance __right_len = __len - __len / 2; |
1589 | _ForwardIterator __right_split = |
1590 | std::__find_if_not_n(__middle, __right_len, __pred); |
1591 | |
1592 | if (__right_len) |
1593 | __right_split = |
1594 | std::__stable_partition_adaptive(__right_split, __last, __pred, |
1595 | __right_len, |
1596 | __buffer, __buffer_size); |
1597 | |
1598 | return std::rotate(__left_split, __middle, __right_split); |
1599 | } |
1600 | |
1601 | template<typename _ForwardIterator, typename _Predicate> |
1602 | _ForwardIterator |
1603 | __stable_partition(_ForwardIterator __first, _ForwardIterator __last, |
1604 | _Predicate __pred) |
1605 | { |
1606 | __first = std::__find_if_not(__first, __last, __pred); |
1607 | |
1608 | if (__first == __last) |
1609 | return __first; |
1610 | |
1611 | typedef typename iterator_traits<_ForwardIterator>::value_type |
1612 | _ValueType; |
1613 | typedef typename iterator_traits<_ForwardIterator>::difference_type |
1614 | _DistanceType; |
1615 | |
1616 | _Temporary_buffer<_ForwardIterator, _ValueType> |
1617 | __buf(__first, std::distance(__first, __last)); |
1618 | return |
1619 | std::__stable_partition_adaptive(__first, __last, __pred, |
1620 | _DistanceType(__buf.requested_size()), |
1621 | __buf.begin(), |
1622 | _DistanceType(__buf.size())); |
1623 | } |
1624 | |
1625 | /** |
1626 | * @brief Move elements for which a predicate is true to the beginning |
1627 | * of a sequence, preserving relative ordering. |
1628 | * @ingroup mutating_algorithms |
1629 | * @param __first A forward iterator. |
1630 | * @param __last A forward iterator. |
1631 | * @param __pred A predicate functor. |
1632 | * @return An iterator @p middle such that @p __pred(i) is true for each |
1633 | * iterator @p i in the range @p [first,middle) and false for each @p i |
1634 | * in the range @p [middle,last). |
1635 | * |
1636 | * Performs the same function as @p partition() with the additional |
1637 | * guarantee that the relative ordering of elements in each group is |
1638 | * preserved, so any two elements @p x and @p y in the range |
1639 | * @p [__first,__last) such that @p __pred(x)==__pred(y) will have the same |
1640 | * relative ordering after calling @p stable_partition(). |
1641 | */ |
1642 | template<typename _ForwardIterator, typename _Predicate> |
1643 | inline _ForwardIterator |
1644 | stable_partition(_ForwardIterator __first, _ForwardIterator __last, |
1645 | _Predicate __pred) |
1646 | { |
1647 | // concept requirements |
1648 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
1649 | _ForwardIterator>) |
1650 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
1651 | typename iterator_traits<_ForwardIterator>::value_type>) |
1652 | __glibcxx_requires_valid_range(__first, __last); |
1653 | |
1654 | return std::__stable_partition(__first, __last, |
1655 | __gnu_cxx::__ops::__pred_iter(__pred)); |
1656 | } |
1657 | |
1658 | /// This is a helper function for the sort routines. |
1659 | template<typename _RandomAccessIterator, typename _Compare> |
1660 | _GLIBCXX20_CONSTEXPR |
1661 | void |
1662 | __heap_select(_RandomAccessIterator __first, |
1663 | _RandomAccessIterator __middle, |
1664 | _RandomAccessIterator __last, _Compare __comp) |
1665 | { |
1666 | std::__make_heap(__first, __middle, __comp); |
1667 | for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) |
1668 | if (__comp(__i, __first)) |
1669 | std::__pop_heap(__first, __middle, __i, __comp); |
1670 | } |
1671 | |
1672 | // partial_sort |
1673 | |
1674 | template<typename _InputIterator, typename _RandomAccessIterator, |
1675 | typename _Compare> |
1676 | _GLIBCXX20_CONSTEXPR |
1677 | _RandomAccessIterator |
1678 | __partial_sort_copy(_InputIterator __first, _InputIterator __last, |
1679 | _RandomAccessIterator __result_first, |
1680 | _RandomAccessIterator __result_last, |
1681 | _Compare __comp) |
1682 | { |
1683 | typedef typename iterator_traits<_InputIterator>::value_type |
1684 | _InputValueType; |
1685 | typedef iterator_traits<_RandomAccessIterator> _RItTraits; |
1686 | typedef typename _RItTraits::difference_type _DistanceType; |
1687 | |
1688 | if (__result_first == __result_last) |
1689 | return __result_last; |
1690 | _RandomAccessIterator __result_real_last = __result_first; |
1691 | while (__first != __last && __result_real_last != __result_last) |
1692 | { |
1693 | *__result_real_last = *__first; |
1694 | ++__result_real_last; |
1695 | ++__first; |
1696 | } |
1697 | |
1698 | std::__make_heap(__result_first, __result_real_last, __comp); |
1699 | while (__first != __last) |
1700 | { |
1701 | if (__comp(__first, __result_first)) |
1702 | std::__adjust_heap(__result_first, _DistanceType(0), |
1703 | _DistanceType(__result_real_last |
1704 | - __result_first), |
1705 | _InputValueType(*__first), __comp); |
1706 | ++__first; |
1707 | } |
1708 | std::__sort_heap(__result_first, __result_real_last, __comp); |
1709 | return __result_real_last; |
1710 | } |
1711 | |
1712 | /** |
1713 | * @brief Copy the smallest elements of a sequence. |
1714 | * @ingroup sorting_algorithms |
1715 | * @param __first An iterator. |
1716 | * @param __last Another iterator. |
1717 | * @param __result_first A random-access iterator. |
1718 | * @param __result_last Another random-access iterator. |
1719 | * @return An iterator indicating the end of the resulting sequence. |
1720 | * |
1721 | * Copies and sorts the smallest N values from the range @p [__first,__last) |
1722 | * to the range beginning at @p __result_first, where the number of |
1723 | * elements to be copied, @p N, is the smaller of @p (__last-__first) and |
1724 | * @p (__result_last-__result_first). |
1725 | * After the sort if @e i and @e j are iterators in the range |
1726 | * @p [__result_first,__result_first+N) such that i precedes j then |
1727 | * *j<*i is false. |
1728 | * The value returned is @p __result_first+N. |
1729 | */ |
1730 | template<typename _InputIterator, typename _RandomAccessIterator> |
1731 | _GLIBCXX20_CONSTEXPR |
1732 | inline _RandomAccessIterator |
1733 | partial_sort_copy(_InputIterator __first, _InputIterator __last, |
1734 | _RandomAccessIterator __result_first, |
1735 | _RandomAccessIterator __result_last) |
1736 | { |
1737 | #ifdef _GLIBCXX_CONCEPT_CHECKS |
1738 | typedef typename iterator_traits<_InputIterator>::value_type |
1739 | _InputValueType; |
1740 | typedef typename iterator_traits<_RandomAccessIterator>::value_type |
1741 | _OutputValueType; |
1742 | #endif |
1743 | |
1744 | // concept requirements |
1745 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
1746 | __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, |
1747 | _OutputValueType>) |
1748 | __glibcxx_function_requires(_LessThanOpConcept<_InputValueType, |
1749 | _OutputValueType>) |
1750 | __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) |
1751 | __glibcxx_requires_valid_range(__first, __last); |
1752 | __glibcxx_requires_irreflexive(__first, __last); |
1753 | __glibcxx_requires_valid_range(__result_first, __result_last); |
1754 | |
1755 | return std::__partial_sort_copy(__first, __last, |
1756 | __result_first, __result_last, |
1757 | __gnu_cxx::__ops::__iter_less_iter()); |
1758 | } |
1759 | |
1760 | /** |
1761 | * @brief Copy the smallest elements of a sequence using a predicate for |
1762 | * comparison. |
1763 | * @ingroup sorting_algorithms |
1764 | * @param __first An input iterator. |
1765 | * @param __last Another input iterator. |
1766 | * @param __result_first A random-access iterator. |
1767 | * @param __result_last Another random-access iterator. |
1768 | * @param __comp A comparison functor. |
1769 | * @return An iterator indicating the end of the resulting sequence. |
1770 | * |
1771 | * Copies and sorts the smallest N values from the range @p [__first,__last) |
1772 | * to the range beginning at @p result_first, where the number of |
1773 | * elements to be copied, @p N, is the smaller of @p (__last-__first) and |
1774 | * @p (__result_last-__result_first). |
1775 | * After the sort if @e i and @e j are iterators in the range |
1776 | * @p [__result_first,__result_first+N) such that i precedes j then |
1777 | * @p __comp(*j,*i) is false. |
1778 | * The value returned is @p __result_first+N. |
1779 | */ |
1780 | template<typename _InputIterator, typename _RandomAccessIterator, |
1781 | typename _Compare> |
1782 | _GLIBCXX20_CONSTEXPR |
1783 | inline _RandomAccessIterator |
1784 | partial_sort_copy(_InputIterator __first, _InputIterator __last, |
1785 | _RandomAccessIterator __result_first, |
1786 | _RandomAccessIterator __result_last, |
1787 | _Compare __comp) |
1788 | { |
1789 | #ifdef _GLIBCXX_CONCEPT_CHECKS |
1790 | typedef typename iterator_traits<_InputIterator>::value_type |
1791 | _InputValueType; |
1792 | typedef typename iterator_traits<_RandomAccessIterator>::value_type |
1793 | _OutputValueType; |
1794 | #endif |
1795 | |
1796 | // concept requirements |
1797 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
1798 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
1799 | _RandomAccessIterator>) |
1800 | __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, |
1801 | _OutputValueType>) |
1802 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
1803 | _InputValueType, _OutputValueType>) |
1804 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
1805 | _OutputValueType, _OutputValueType>) |
1806 | __glibcxx_requires_valid_range(__first, __last); |
1807 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
1808 | __glibcxx_requires_valid_range(__result_first, __result_last); |
1809 | |
1810 | return std::__partial_sort_copy(__first, __last, |
1811 | __result_first, __result_last, |
1812 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
1813 | } |
1814 | |
1815 | /// This is a helper function for the sort routine. |
1816 | template<typename _RandomAccessIterator, typename _Compare> |
1817 | _GLIBCXX20_CONSTEXPR |
1818 | void |
1819 | __unguarded_linear_insert(_RandomAccessIterator __last, |
1820 | _Compare __comp) |
1821 | { |
1822 | typename iterator_traits<_RandomAccessIterator>::value_type |
1823 | __val = _GLIBCXX_MOVE(*__last)std::move(*__last); |
1824 | _RandomAccessIterator __next = __last; |
1825 | --__next; |
1826 | while (__comp(__val, __next)) |
1827 | { |
1828 | *__last = _GLIBCXX_MOVE(*__next)std::move(*__next); |
1829 | __last = __next; |
1830 | --__next; |
1831 | } |
1832 | *__last = _GLIBCXX_MOVE(__val)std::move(__val); |
1833 | } |
1834 | |
1835 | /// This is a helper function for the sort routine. |
1836 | template<typename _RandomAccessIterator, typename _Compare> |
1837 | _GLIBCXX20_CONSTEXPR |
1838 | void |
1839 | __insertion_sort(_RandomAccessIterator __first, |
1840 | _RandomAccessIterator __last, _Compare __comp) |
1841 | { |
1842 | if (__first == __last) return; |
1843 | |
1844 | for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) |
1845 | { |
1846 | if (__comp(__i, __first)) |
1847 | { |
1848 | typename iterator_traits<_RandomAccessIterator>::value_type |
1849 | __val = _GLIBCXX_MOVE(*__i)std::move(*__i); |
1850 | _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1)std::move_backward(__first, __i, __i + 1); |
1851 | *__first = _GLIBCXX_MOVE(__val)std::move(__val); |
1852 | } |
1853 | else |
1854 | std::__unguarded_linear_insert(__i, |
1855 | __gnu_cxx::__ops::__val_comp_iter(__comp)); |
1856 | } |
1857 | } |
1858 | |
1859 | /// This is a helper function for the sort routine. |
1860 | template<typename _RandomAccessIterator, typename _Compare> |
1861 | _GLIBCXX20_CONSTEXPR |
1862 | inline void |
1863 | __unguarded_insertion_sort(_RandomAccessIterator __first, |
1864 | _RandomAccessIterator __last, _Compare __comp) |
1865 | { |
1866 | for (_RandomAccessIterator __i = __first; __i != __last; ++__i) |
1867 | std::__unguarded_linear_insert(__i, |
1868 | __gnu_cxx::__ops::__val_comp_iter(__comp)); |
1869 | } |
1870 | |
1871 | /** |
1872 | * @doctodo |
1873 | * This controls some aspect of the sort routines. |
1874 | */ |
1875 | enum { _S_threshold = 16 }; |
1876 | |
1877 | /// This is a helper function for the sort routine. |
1878 | template<typename _RandomAccessIterator, typename _Compare> |
1879 | _GLIBCXX20_CONSTEXPR |
1880 | void |
1881 | __final_insertion_sort(_RandomAccessIterator __first, |
1882 | _RandomAccessIterator __last, _Compare __comp) |
1883 | { |
1884 | if (__last - __first > int(_S_threshold)) |
1885 | { |
1886 | std::__insertion_sort(__first, __first + int(_S_threshold), __comp); |
1887 | std::__unguarded_insertion_sort(__first + int(_S_threshold), __last, |
1888 | __comp); |
1889 | } |
1890 | else |
1891 | std::__insertion_sort(__first, __last, __comp); |
1892 | } |
1893 | |
1894 | /// This is a helper function... |
1895 | template<typename _RandomAccessIterator, typename _Compare> |
1896 | _GLIBCXX20_CONSTEXPR |
1897 | _RandomAccessIterator |
1898 | __unguarded_partition(_RandomAccessIterator __first, |
1899 | _RandomAccessIterator __last, |
1900 | _RandomAccessIterator __pivot, _Compare __comp) |
1901 | { |
1902 | while (true) |
1903 | { |
1904 | while (__comp(__first, __pivot)) |
1905 | ++__first; |
1906 | --__last; |
1907 | while (__comp(__pivot, __last)) |
1908 | --__last; |
1909 | if (!(__first < __last)) |
1910 | return __first; |
1911 | std::iter_swap(__first, __last); |
1912 | ++__first; |
1913 | } |
1914 | } |
1915 | |
1916 | /// This is a helper function... |
1917 | template<typename _RandomAccessIterator, typename _Compare> |
1918 | _GLIBCXX20_CONSTEXPR |
1919 | inline _RandomAccessIterator |
1920 | __unguarded_partition_pivot(_RandomAccessIterator __first, |
1921 | _RandomAccessIterator __last, _Compare __comp) |
1922 | { |
1923 | _RandomAccessIterator __mid = __first + (__last - __first) / 2; |
1924 | std::__move_median_to_first(__first, __first + 1, __mid, __last - 1, |
1925 | __comp); |
1926 | return std::__unguarded_partition(__first + 1, __last, __first, __comp); |
1927 | } |
1928 | |
1929 | template<typename _RandomAccessIterator, typename _Compare> |
1930 | _GLIBCXX20_CONSTEXPR |
1931 | inline void |
1932 | __partial_sort(_RandomAccessIterator __first, |
1933 | _RandomAccessIterator __middle, |
1934 | _RandomAccessIterator __last, |
1935 | _Compare __comp) |
1936 | { |
1937 | std::__heap_select(__first, __middle, __last, __comp); |
1938 | std::__sort_heap(__first, __middle, __comp); |
1939 | } |
1940 | |
1941 | /// This is a helper function for the sort routine. |
1942 | template<typename _RandomAccessIterator, typename _Size, typename _Compare> |
1943 | _GLIBCXX20_CONSTEXPR |
1944 | void |
1945 | __introsort_loop(_RandomAccessIterator __first, |
1946 | _RandomAccessIterator __last, |
1947 | _Size __depth_limit, _Compare __comp) |
1948 | { |
1949 | while (__last - __first > int(_S_threshold)) |
1950 | { |
1951 | if (__depth_limit == 0) |
1952 | { |
1953 | std::__partial_sort(__first, __last, __last, __comp); |
1954 | return; |
1955 | } |
1956 | --__depth_limit; |
1957 | _RandomAccessIterator __cut = |
1958 | std::__unguarded_partition_pivot(__first, __last, __comp); |
1959 | std::__introsort_loop(__cut, __last, __depth_limit, __comp); |
1960 | __last = __cut; |
1961 | } |
1962 | } |
1963 | |
1964 | // sort |
1965 | |
1966 | template<typename _RandomAccessIterator, typename _Compare> |
1967 | _GLIBCXX20_CONSTEXPR |
1968 | inline void |
1969 | __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, |
1970 | _Compare __comp) |
1971 | { |
1972 | if (__first != __last) |
1973 | { |
1974 | std::__introsort_loop(__first, __last, |
1975 | std::__lg(__last - __first) * 2, |
1976 | __comp); |
1977 | std::__final_insertion_sort(__first, __last, __comp); |
1978 | } |
1979 | } |
1980 | |
1981 | template<typename _RandomAccessIterator, typename _Size, typename _Compare> |
1982 | _GLIBCXX20_CONSTEXPR |
1983 | void |
1984 | __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, |
1985 | _RandomAccessIterator __last, _Size __depth_limit, |
1986 | _Compare __comp) |
1987 | { |
1988 | while (__last - __first > 3) |
1989 | { |
1990 | if (__depth_limit == 0) |
1991 | { |
1992 | std::__heap_select(__first, __nth + 1, __last, __comp); |
1993 | // Place the nth largest element in its final position. |
1994 | std::iter_swap(__first, __nth); |
1995 | return; |
1996 | } |
1997 | --__depth_limit; |
1998 | _RandomAccessIterator __cut = |
1999 | std::__unguarded_partition_pivot(__first, __last, __comp); |
2000 | if (__cut <= __nth) |
2001 | __first = __cut; |
2002 | else |
2003 | __last = __cut; |
2004 | } |
2005 | std::__insertion_sort(__first, __last, __comp); |
2006 | } |
2007 | |
2008 | // nth_element |
2009 | |
2010 | // lower_bound moved to stl_algobase.h |
2011 | |
2012 | /** |
2013 | * @brief Finds the first position in which @p __val could be inserted |
2014 | * without changing the ordering. |
2015 | * @ingroup binary_search_algorithms |
2016 | * @param __first An iterator. |
2017 | * @param __last Another iterator. |
2018 | * @param __val The search term. |
2019 | * @param __comp A functor to use for comparisons. |
2020 | * @return An iterator pointing to the first element <em>not less |
2021 | * than</em> @p __val, or end() if every element is less |
2022 | * than @p __val. |
2023 | * @ingroup binary_search_algorithms |
2024 | * |
2025 | * The comparison function should have the same effects on ordering as |
2026 | * the function used for the initial sort. |
2027 | */ |
2028 | template<typename _ForwardIterator, typename _Tp, typename _Compare> |
2029 | _GLIBCXX20_CONSTEXPR |
2030 | inline _ForwardIterator |
2031 | lower_bound(_ForwardIterator __first, _ForwardIterator __last, |
2032 | const _Tp& __val, _Compare __comp) |
2033 | { |
2034 | // concept requirements |
2035 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
2036 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2037 | typename iterator_traits<_ForwardIterator>::value_type, _Tp>) |
2038 | __glibcxx_requires_partitioned_lower_pred(__first, __last, |
2039 | __val, __comp); |
2040 | |
2041 | return std::__lower_bound(__first, __last, __val, |
2042 | __gnu_cxx::__ops::__iter_comp_val(__comp)); |
2043 | } |
2044 | |
2045 | template<typename _ForwardIterator, typename _Tp, typename _Compare> |
2046 | _GLIBCXX20_CONSTEXPR |
2047 | _ForwardIterator |
2048 | __upper_bound(_ForwardIterator __first, _ForwardIterator __last, |
2049 | const _Tp& __val, _Compare __comp) |
2050 | { |
2051 | typedef typename iterator_traits<_ForwardIterator>::difference_type |
2052 | _DistanceType; |
2053 | |
2054 | _DistanceType __len = std::distance(__first, __last); |
2055 | |
2056 | while (__len > 0) |
2057 | { |
2058 | _DistanceType __half = __len >> 1; |
2059 | _ForwardIterator __middle = __first; |
2060 | std::advance(__middle, __half); |
2061 | if (__comp(__val, __middle)) |
2062 | __len = __half; |
2063 | else |
2064 | { |
2065 | __first = __middle; |
2066 | ++__first; |
2067 | __len = __len - __half - 1; |
2068 | } |
2069 | } |
2070 | return __first; |
2071 | } |
2072 | |
2073 | /** |
2074 | * @brief Finds the last position in which @p __val could be inserted |
2075 | * without changing the ordering. |
2076 | * @ingroup binary_search_algorithms |
2077 | * @param __first An iterator. |
2078 | * @param __last Another iterator. |
2079 | * @param __val The search term. |
2080 | * @return An iterator pointing to the first element greater than @p __val, |
2081 | * or end() if no elements are greater than @p __val. |
2082 | * @ingroup binary_search_algorithms |
2083 | */ |
2084 | template<typename _ForwardIterator, typename _Tp> |
2085 | _GLIBCXX20_CONSTEXPR |
2086 | inline _ForwardIterator |
2087 | upper_bound(_ForwardIterator __first, _ForwardIterator __last, |
2088 | const _Tp& __val) |
2089 | { |
2090 | // concept requirements |
2091 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
2092 | __glibcxx_function_requires(_LessThanOpConcept< |
2093 | _Tp, typename iterator_traits<_ForwardIterator>::value_type>) |
2094 | __glibcxx_requires_partitioned_upper(__first, __last, __val); |
2095 | |
2096 | return std::__upper_bound(__first, __last, __val, |
2097 | __gnu_cxx::__ops::__val_less_iter()); |
2098 | } |
2099 | |
2100 | /** |
2101 | * @brief Finds the last position in which @p __val could be inserted |
2102 | * without changing the ordering. |
2103 | * @ingroup binary_search_algorithms |
2104 | * @param __first An iterator. |
2105 | * @param __last Another iterator. |
2106 | * @param __val The search term. |
2107 | * @param __comp A functor to use for comparisons. |
2108 | * @return An iterator pointing to the first element greater than @p __val, |
2109 | * or end() if no elements are greater than @p __val. |
2110 | * @ingroup binary_search_algorithms |
2111 | * |
2112 | * The comparison function should have the same effects on ordering as |
2113 | * the function used for the initial sort. |
2114 | */ |
2115 | template<typename _ForwardIterator, typename _Tp, typename _Compare> |
2116 | _GLIBCXX20_CONSTEXPR |
2117 | inline _ForwardIterator |
2118 | upper_bound(_ForwardIterator __first, _ForwardIterator __last, |
2119 | const _Tp& __val, _Compare __comp) |
2120 | { |
2121 | // concept requirements |
2122 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
2123 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2124 | _Tp, typename iterator_traits<_ForwardIterator>::value_type>) |
2125 | __glibcxx_requires_partitioned_upper_pred(__first, __last, |
2126 | __val, __comp); |
2127 | |
2128 | return std::__upper_bound(__first, __last, __val, |
2129 | __gnu_cxx::__ops::__val_comp_iter(__comp)); |
2130 | } |
2131 | |
2132 | template<typename _ForwardIterator, typename _Tp, |
2133 | typename _CompareItTp, typename _CompareTpIt> |
2134 | _GLIBCXX20_CONSTEXPR |
2135 | pair<_ForwardIterator, _ForwardIterator> |
2136 | __equal_range(_ForwardIterator __first, _ForwardIterator __last, |
2137 | const _Tp& __val, |
2138 | _CompareItTp __comp_it_val, _CompareTpIt __comp_val_it) |
2139 | { |
2140 | typedef typename iterator_traits<_ForwardIterator>::difference_type |
2141 | _DistanceType; |
2142 | |
2143 | _DistanceType __len = std::distance(__first, __last); |
2144 | |
2145 | while (__len > 0) |
2146 | { |
2147 | _DistanceType __half = __len >> 1; |
2148 | _ForwardIterator __middle = __first; |
2149 | std::advance(__middle, __half); |
2150 | if (__comp_it_val(__middle, __val)) |
2151 | { |
2152 | __first = __middle; |
2153 | ++__first; |
2154 | __len = __len - __half - 1; |
2155 | } |
2156 | else if (__comp_val_it(__val, __middle)) |
2157 | __len = __half; |
2158 | else |
2159 | { |
2160 | _ForwardIterator __left |
2161 | = std::__lower_bound(__first, __middle, __val, __comp_it_val); |
2162 | std::advance(__first, __len); |
2163 | _ForwardIterator __right |
2164 | = std::__upper_bound(++__middle, __first, __val, __comp_val_it); |
2165 | return pair<_ForwardIterator, _ForwardIterator>(__left, __right); |
2166 | } |
2167 | } |
2168 | return pair<_ForwardIterator, _ForwardIterator>(__first, __first); |
2169 | } |
2170 | |
2171 | /** |
2172 | * @brief Finds the largest subrange in which @p __val could be inserted |
2173 | * at any place in it without changing the ordering. |
2174 | * @ingroup binary_search_algorithms |
2175 | * @param __first An iterator. |
2176 | * @param __last Another iterator. |
2177 | * @param __val The search term. |
2178 | * @return An pair of iterators defining the subrange. |
2179 | * @ingroup binary_search_algorithms |
2180 | * |
2181 | * This is equivalent to |
2182 | * @code |
2183 | * std::make_pair(lower_bound(__first, __last, __val), |
2184 | * upper_bound(__first, __last, __val)) |
2185 | * @endcode |
2186 | * but does not actually call those functions. |
2187 | */ |
2188 | template<typename _ForwardIterator, typename _Tp> |
2189 | _GLIBCXX20_CONSTEXPR |
2190 | inline pair<_ForwardIterator, _ForwardIterator> |
2191 | equal_range(_ForwardIterator __first, _ForwardIterator __last, |
2192 | const _Tp& __val) |
2193 | { |
2194 | // concept requirements |
2195 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
2196 | __glibcxx_function_requires(_LessThanOpConcept< |
2197 | typename iterator_traits<_ForwardIterator>::value_type, _Tp>) |
2198 | __glibcxx_function_requires(_LessThanOpConcept< |
2199 | _Tp, typename iterator_traits<_ForwardIterator>::value_type>) |
2200 | __glibcxx_requires_partitioned_lower(__first, __last, __val); |
2201 | __glibcxx_requires_partitioned_upper(__first, __last, __val); |
2202 | |
2203 | return std::__equal_range(__first, __last, __val, |
2204 | __gnu_cxx::__ops::__iter_less_val(), |
2205 | __gnu_cxx::__ops::__val_less_iter()); |
2206 | } |
2207 | |
2208 | /** |
2209 | * @brief Finds the largest subrange in which @p __val could be inserted |
2210 | * at any place in it without changing the ordering. |
2211 | * @param __first An iterator. |
2212 | * @param __last Another iterator. |
2213 | * @param __val The search term. |
2214 | * @param __comp A functor to use for comparisons. |
2215 | * @return An pair of iterators defining the subrange. |
2216 | * @ingroup binary_search_algorithms |
2217 | * |
2218 | * This is equivalent to |
2219 | * @code |
2220 | * std::make_pair(lower_bound(__first, __last, __val, __comp), |
2221 | * upper_bound(__first, __last, __val, __comp)) |
2222 | * @endcode |
2223 | * but does not actually call those functions. |
2224 | */ |
2225 | template<typename _ForwardIterator, typename _Tp, typename _Compare> |
2226 | _GLIBCXX20_CONSTEXPR |
2227 | inline pair<_ForwardIterator, _ForwardIterator> |
2228 | equal_range(_ForwardIterator __first, _ForwardIterator __last, |
2229 | const _Tp& __val, _Compare __comp) |
2230 | { |
2231 | // concept requirements |
2232 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
2233 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2234 | typename iterator_traits<_ForwardIterator>::value_type, _Tp>) |
2235 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2236 | _Tp, typename iterator_traits<_ForwardIterator>::value_type>) |
2237 | __glibcxx_requires_partitioned_lower_pred(__first, __last, |
2238 | __val, __comp); |
2239 | __glibcxx_requires_partitioned_upper_pred(__first, __last, |
2240 | __val, __comp); |
2241 | |
2242 | return std::__equal_range(__first, __last, __val, |
2243 | __gnu_cxx::__ops::__iter_comp_val(__comp), |
2244 | __gnu_cxx::__ops::__val_comp_iter(__comp)); |
2245 | } |
2246 | |
2247 | /** |
2248 | * @brief Determines whether an element exists in a range. |
2249 | * @ingroup binary_search_algorithms |
2250 | * @param __first An iterator. |
2251 | * @param __last Another iterator. |
2252 | * @param __val The search term. |
2253 | * @return True if @p __val (or its equivalent) is in [@p |
2254 | * __first,@p __last ]. |
2255 | * |
2256 | * Note that this does not actually return an iterator to @p __val. For |
2257 | * that, use std::find or a container's specialized find member functions. |
2258 | */ |
2259 | template<typename _ForwardIterator, typename _Tp> |
2260 | _GLIBCXX20_CONSTEXPR |
2261 | bool |
2262 | binary_search(_ForwardIterator __first, _ForwardIterator __last, |
2263 | const _Tp& __val) |
2264 | { |
2265 | // concept requirements |
2266 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
2267 | __glibcxx_function_requires(_LessThanOpConcept< |
2268 | _Tp, typename iterator_traits<_ForwardIterator>::value_type>) |
2269 | __glibcxx_requires_partitioned_lower(__first, __last, __val); |
2270 | __glibcxx_requires_partitioned_upper(__first, __last, __val); |
2271 | |
2272 | _ForwardIterator __i |
2273 | = std::__lower_bound(__first, __last, __val, |
2274 | __gnu_cxx::__ops::__iter_less_val()); |
2275 | return __i != __last && !(__val < *__i); |
2276 | } |
2277 | |
2278 | /** |
2279 | * @brief Determines whether an element exists in a range. |
2280 | * @ingroup binary_search_algorithms |
2281 | * @param __first An iterator. |
2282 | * @param __last Another iterator. |
2283 | * @param __val The search term. |
2284 | * @param __comp A functor to use for comparisons. |
2285 | * @return True if @p __val (or its equivalent) is in @p [__first,__last]. |
2286 | * |
2287 | * Note that this does not actually return an iterator to @p __val. For |
2288 | * that, use std::find or a container's specialized find member functions. |
2289 | * |
2290 | * The comparison function should have the same effects on ordering as |
2291 | * the function used for the initial sort. |
2292 | */ |
2293 | template<typename _ForwardIterator, typename _Tp, typename _Compare> |
2294 | _GLIBCXX20_CONSTEXPR |
2295 | bool |
2296 | binary_search(_ForwardIterator __first, _ForwardIterator __last, |
2297 | const _Tp& __val, _Compare __comp) |
2298 | { |
2299 | // concept requirements |
2300 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
2301 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2302 | _Tp, typename iterator_traits<_ForwardIterator>::value_type>) |
2303 | __glibcxx_requires_partitioned_lower_pred(__first, __last, |
2304 | __val, __comp); |
2305 | __glibcxx_requires_partitioned_upper_pred(__first, __last, |
2306 | __val, __comp); |
2307 | |
2308 | _ForwardIterator __i |
2309 | = std::__lower_bound(__first, __last, __val, |
2310 | __gnu_cxx::__ops::__iter_comp_val(__comp)); |
2311 | return __i != __last && !bool(__comp(__val, *__i)); |
2312 | } |
2313 | |
2314 | // merge |
2315 | |
2316 | /// This is a helper function for the __merge_adaptive routines. |
2317 | template<typename _InputIterator1, typename _InputIterator2, |
2318 | typename _OutputIterator, typename _Compare> |
2319 | void |
2320 | __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, |
2321 | _InputIterator2 __first2, _InputIterator2 __last2, |
2322 | _OutputIterator __result, _Compare __comp) |
2323 | { |
2324 | while (__first1 != __last1 && __first2 != __last2) |
2325 | { |
2326 | if (__comp(__first2, __first1)) |
2327 | { |
2328 | *__result = _GLIBCXX_MOVE(*__first2)std::move(*__first2); |
2329 | ++__first2; |
2330 | } |
2331 | else |
2332 | { |
2333 | *__result = _GLIBCXX_MOVE(*__first1)std::move(*__first1); |
2334 | ++__first1; |
2335 | } |
2336 | ++__result; |
2337 | } |
2338 | if (__first1 != __last1) |
2339 | _GLIBCXX_MOVE3(__first1, __last1, __result)std::move(__first1, __last1, __result); |
2340 | } |
2341 | |
2342 | /// This is a helper function for the __merge_adaptive routines. |
2343 | template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, |
2344 | typename _BidirectionalIterator3, typename _Compare> |
2345 | void |
2346 | __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, |
2347 | _BidirectionalIterator1 __last1, |
2348 | _BidirectionalIterator2 __first2, |
2349 | _BidirectionalIterator2 __last2, |
2350 | _BidirectionalIterator3 __result, |
2351 | _Compare __comp) |
2352 | { |
2353 | if (__first1 == __last1) |
2354 | { |
2355 | _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result)std::move_backward(__first2, __last2, __result); |
2356 | return; |
2357 | } |
2358 | else if (__first2 == __last2) |
2359 | return; |
2360 | |
2361 | --__last1; |
2362 | --__last2; |
2363 | while (true) |
2364 | { |
2365 | if (__comp(__last2, __last1)) |
2366 | { |
2367 | *--__result = _GLIBCXX_MOVE(*__last1)std::move(*__last1); |
2368 | if (__first1 == __last1) |
2369 | { |
2370 | _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result)std::move_backward(__first2, ++__last2, __result); |
2371 | return; |
2372 | } |
2373 | --__last1; |
2374 | } |
2375 | else |
2376 | { |
2377 | *--__result = _GLIBCXX_MOVE(*__last2)std::move(*__last2); |
2378 | if (__first2 == __last2) |
2379 | return; |
2380 | --__last2; |
2381 | } |
2382 | } |
2383 | } |
2384 | |
2385 | /// This is a helper function for the merge routines. |
2386 | template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, |
2387 | typename _Distance> |
2388 | _BidirectionalIterator1 |
2389 | __rotate_adaptive(_BidirectionalIterator1 __first, |
2390 | _BidirectionalIterator1 __middle, |
2391 | _BidirectionalIterator1 __last, |
2392 | _Distance __len1, _Distance __len2, |
2393 | _BidirectionalIterator2 __buffer, |
2394 | _Distance __buffer_size) |
2395 | { |
2396 | _BidirectionalIterator2 __buffer_end; |
2397 | if (__len1 > __len2 && __len2 <= __buffer_size) |
2398 | { |
2399 | if (__len2) |
2400 | { |
2401 | __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer)std::move(__middle, __last, __buffer); |
2402 | _GLIBCXX_MOVE_BACKWARD3(__first, __middle, __last)std::move_backward(__first, __middle, __last); |
2403 | return _GLIBCXX_MOVE3(__buffer, __buffer_end, __first)std::move(__buffer, __buffer_end, __first); |
2404 | } |
2405 | else |
2406 | return __first; |
2407 | } |
2408 | else if (__len1 <= __buffer_size) |
2409 | { |
2410 | if (__len1) |
2411 | { |
2412 | __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer)std::move(__first, __middle, __buffer); |
2413 | _GLIBCXX_MOVE3(__middle, __last, __first)std::move(__middle, __last, __first); |
2414 | return _GLIBCXX_MOVE_BACKWARD3(__buffer, __buffer_end, __last)std::move_backward(__buffer, __buffer_end, __last); |
2415 | } |
2416 | else |
2417 | return __last; |
2418 | } |
2419 | else |
2420 | return std::rotate(__first, __middle, __last); |
2421 | } |
2422 | |
2423 | /// This is a helper function for the merge routines. |
2424 | template<typename _BidirectionalIterator, typename _Distance, |
2425 | typename _Pointer, typename _Compare> |
2426 | void |
2427 | __merge_adaptive(_BidirectionalIterator __first, |
2428 | _BidirectionalIterator __middle, |
2429 | _BidirectionalIterator __last, |
2430 | _Distance __len1, _Distance __len2, |
2431 | _Pointer __buffer, _Distance __buffer_size, |
2432 | _Compare __comp) |
2433 | { |
2434 | if (__len1 <= __len2 && __len1 <= __buffer_size) |
2435 | { |
2436 | _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer)std::move(__first, __middle, __buffer); |
2437 | std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last, |
2438 | __first, __comp); |
2439 | } |
2440 | else if (__len2 <= __buffer_size) |
2441 | { |
2442 | _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer)std::move(__middle, __last, __buffer); |
2443 | std::__move_merge_adaptive_backward(__first, __middle, __buffer, |
2444 | __buffer_end, __last, __comp); |
2445 | } |
2446 | else |
2447 | { |
2448 | _BidirectionalIterator __first_cut = __first; |
2449 | _BidirectionalIterator __second_cut = __middle; |
2450 | _Distance __len11 = 0; |
2451 | _Distance __len22 = 0; |
2452 | if (__len1 > __len2) |
2453 | { |
2454 | __len11 = __len1 / 2; |
2455 | std::advance(__first_cut, __len11); |
2456 | __second_cut |
2457 | = std::__lower_bound(__middle, __last, *__first_cut, |
2458 | __gnu_cxx::__ops::__iter_comp_val(__comp)); |
2459 | __len22 = std::distance(__middle, __second_cut); |
2460 | } |
2461 | else |
2462 | { |
2463 | __len22 = __len2 / 2; |
2464 | std::advance(__second_cut, __len22); |
2465 | __first_cut |
2466 | = std::__upper_bound(__first, __middle, *__second_cut, |
2467 | __gnu_cxx::__ops::__val_comp_iter(__comp)); |
2468 | __len11 = std::distance(__first, __first_cut); |
2469 | } |
2470 | |
2471 | _BidirectionalIterator __new_middle |
2472 | = std::__rotate_adaptive(__first_cut, __middle, __second_cut, |
2473 | __len1 - __len11, __len22, __buffer, |
2474 | __buffer_size); |
2475 | std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, |
2476 | __len22, __buffer, __buffer_size, __comp); |
2477 | std::__merge_adaptive(__new_middle, __second_cut, __last, |
2478 | __len1 - __len11, |
2479 | __len2 - __len22, __buffer, |
2480 | __buffer_size, __comp); |
2481 | } |
2482 | } |
2483 | |
2484 | /// This is a helper function for the merge routines. |
2485 | template<typename _BidirectionalIterator, typename _Distance, |
2486 | typename _Compare> |
2487 | void |
2488 | __merge_without_buffer(_BidirectionalIterator __first, |
2489 | _BidirectionalIterator __middle, |
2490 | _BidirectionalIterator __last, |
2491 | _Distance __len1, _Distance __len2, |
2492 | _Compare __comp) |
2493 | { |
2494 | if (__len1 == 0 || __len2 == 0) |
2495 | return; |
2496 | |
2497 | if (__len1 + __len2 == 2) |
2498 | { |
2499 | if (__comp(__middle, __first)) |
2500 | std::iter_swap(__first, __middle); |
2501 | return; |
2502 | } |
2503 | |
2504 | _BidirectionalIterator __first_cut = __first; |
2505 | _BidirectionalIterator __second_cut = __middle; |
2506 | _Distance __len11 = 0; |
2507 | _Distance __len22 = 0; |
2508 | if (__len1 > __len2) |
2509 | { |
2510 | __len11 = __len1 / 2; |
2511 | std::advance(__first_cut, __len11); |
2512 | __second_cut |
2513 | = std::__lower_bound(__middle, __last, *__first_cut, |
2514 | __gnu_cxx::__ops::__iter_comp_val(__comp)); |
2515 | __len22 = std::distance(__middle, __second_cut); |
2516 | } |
2517 | else |
2518 | { |
2519 | __len22 = __len2 / 2; |
2520 | std::advance(__second_cut, __len22); |
2521 | __first_cut |
2522 | = std::__upper_bound(__first, __middle, *__second_cut, |
2523 | __gnu_cxx::__ops::__val_comp_iter(__comp)); |
2524 | __len11 = std::distance(__first, __first_cut); |
2525 | } |
2526 | |
2527 | _BidirectionalIterator __new_middle |
2528 | = std::rotate(__first_cut, __middle, __second_cut); |
2529 | std::__merge_without_buffer(__first, __first_cut, __new_middle, |
2530 | __len11, __len22, __comp); |
2531 | std::__merge_without_buffer(__new_middle, __second_cut, __last, |
2532 | __len1 - __len11, __len2 - __len22, __comp); |
2533 | } |
2534 | |
2535 | template<typename _BidirectionalIterator, typename _Compare> |
2536 | void |
2537 | __inplace_merge(_BidirectionalIterator __first, |
2538 | _BidirectionalIterator __middle, |
2539 | _BidirectionalIterator __last, |
2540 | _Compare __comp) |
2541 | { |
2542 | typedef typename iterator_traits<_BidirectionalIterator>::value_type |
2543 | _ValueType; |
2544 | typedef typename iterator_traits<_BidirectionalIterator>::difference_type |
2545 | _DistanceType; |
2546 | |
2547 | if (__first == __middle || __middle == __last) |
2548 | return; |
2549 | |
2550 | const _DistanceType __len1 = std::distance(__first, __middle); |
2551 | const _DistanceType __len2 = std::distance(__middle, __last); |
2552 | |
2553 | typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf; |
2554 | _TmpBuf __buf(__first, __len1 + __len2); |
2555 | |
2556 | if (__buf.begin() == 0) |
2557 | std::__merge_without_buffer |
2558 | (__first, __middle, __last, __len1, __len2, __comp); |
2559 | else |
2560 | std::__merge_adaptive |
2561 | (__first, __middle, __last, __len1, __len2, __buf.begin(), |
2562 | _DistanceType(__buf.size()), __comp); |
2563 | } |
2564 | |
2565 | /** |
2566 | * @brief Merges two sorted ranges in place. |
2567 | * @ingroup sorting_algorithms |
2568 | * @param __first An iterator. |
2569 | * @param __middle Another iterator. |
2570 | * @param __last Another iterator. |
2571 | * @return Nothing. |
2572 | * |
2573 | * Merges two sorted and consecutive ranges, [__first,__middle) and |
2574 | * [__middle,__last), and puts the result in [__first,__last). The |
2575 | * output will be sorted. The sort is @e stable, that is, for |
2576 | * equivalent elements in the two ranges, elements from the first |
2577 | * range will always come before elements from the second. |
2578 | * |
2579 | * If enough additional memory is available, this takes (__last-__first)-1 |
2580 | * comparisons. Otherwise an NlogN algorithm is used, where N is |
2581 | * distance(__first,__last). |
2582 | */ |
2583 | template<typename _BidirectionalIterator> |
2584 | inline void |
2585 | inplace_merge(_BidirectionalIterator __first, |
2586 | _BidirectionalIterator __middle, |
2587 | _BidirectionalIterator __last) |
2588 | { |
2589 | // concept requirements |
2590 | __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< |
2591 | _BidirectionalIterator>) |
2592 | __glibcxx_function_requires(_LessThanComparableConcept< |
2593 | typename iterator_traits<_BidirectionalIterator>::value_type>) |
2594 | __glibcxx_requires_sorted(__first, __middle); |
2595 | __glibcxx_requires_sorted(__middle, __last); |
2596 | __glibcxx_requires_irreflexive(__first, __last); |
2597 | |
2598 | std::__inplace_merge(__first, __middle, __last, |
2599 | __gnu_cxx::__ops::__iter_less_iter()); |
2600 | } |
2601 | |
2602 | /** |
2603 | * @brief Merges two sorted ranges in place. |
2604 | * @ingroup sorting_algorithms |
2605 | * @param __first An iterator. |
2606 | * @param __middle Another iterator. |
2607 | * @param __last Another iterator. |
2608 | * @param __comp A functor to use for comparisons. |
2609 | * @return Nothing. |
2610 | * |
2611 | * Merges two sorted and consecutive ranges, [__first,__middle) and |
2612 | * [middle,last), and puts the result in [__first,__last). The output will |
2613 | * be sorted. The sort is @e stable, that is, for equivalent |
2614 | * elements in the two ranges, elements from the first range will always |
2615 | * come before elements from the second. |
2616 | * |
2617 | * If enough additional memory is available, this takes (__last-__first)-1 |
2618 | * comparisons. Otherwise an NlogN algorithm is used, where N is |
2619 | * distance(__first,__last). |
2620 | * |
2621 | * The comparison function should have the same effects on ordering as |
2622 | * the function used for the initial sort. |
2623 | */ |
2624 | template<typename _BidirectionalIterator, typename _Compare> |
2625 | inline void |
2626 | inplace_merge(_BidirectionalIterator __first, |
2627 | _BidirectionalIterator __middle, |
2628 | _BidirectionalIterator __last, |
2629 | _Compare __comp) |
2630 | { |
2631 | // concept requirements |
2632 | __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< |
2633 | _BidirectionalIterator>) |
2634 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2635 | typename iterator_traits<_BidirectionalIterator>::value_type, |
2636 | typename iterator_traits<_BidirectionalIterator>::value_type>) |
2637 | __glibcxx_requires_sorted_pred(__first, __middle, __comp); |
2638 | __glibcxx_requires_sorted_pred(__middle, __last, __comp); |
2639 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
2640 | |
2641 | std::__inplace_merge(__first, __middle, __last, |
2642 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
2643 | } |
2644 | |
2645 | |
2646 | /// This is a helper function for the __merge_sort_loop routines. |
2647 | template<typename _InputIterator, typename _OutputIterator, |
2648 | typename _Compare> |
2649 | _OutputIterator |
2650 | __move_merge(_InputIterator __first1, _InputIterator __last1, |
2651 | _InputIterator __first2, _InputIterator __last2, |
2652 | _OutputIterator __result, _Compare __comp) |
2653 | { |
2654 | while (__first1 != __last1 && __first2 != __last2) |
2655 | { |
2656 | if (__comp(__first2, __first1)) |
2657 | { |
2658 | *__result = _GLIBCXX_MOVE(*__first2)std::move(*__first2); |
2659 | ++__first2; |
2660 | } |
2661 | else |
2662 | { |
2663 | *__result = _GLIBCXX_MOVE(*__first1)std::move(*__first1); |
2664 | ++__first1; |
2665 | } |
2666 | ++__result; |
2667 | } |
2668 | return _GLIBCXX_MOVE3(__first2, __last2,std::move(__first2, __last2, std::move(__first1, __last1, __result )) |
2669 | _GLIBCXX_MOVE3(__first1, __last1,std::move(__first2, __last2, std::move(__first1, __last1, __result )) |
2670 | __result))std::move(__first2, __last2, std::move(__first1, __last1, __result )); |
2671 | } |
2672 | |
2673 | template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, |
2674 | typename _Distance, typename _Compare> |
2675 | void |
2676 | __merge_sort_loop(_RandomAccessIterator1 __first, |
2677 | _RandomAccessIterator1 __last, |
2678 | _RandomAccessIterator2 __result, _Distance __step_size, |
2679 | _Compare __comp) |
2680 | { |
2681 | const _Distance __two_step = 2 * __step_size; |
2682 | |
2683 | while (__last - __first >= __two_step) |
2684 | { |
2685 | __result = std::__move_merge(__first, __first + __step_size, |
2686 | __first + __step_size, |
2687 | __first + __two_step, |
2688 | __result, __comp); |
2689 | __first += __two_step; |
2690 | } |
2691 | __step_size = std::min(_Distance(__last - __first), __step_size); |
2692 | |
2693 | std::__move_merge(__first, __first + __step_size, |
2694 | __first + __step_size, __last, __result, __comp); |
2695 | } |
2696 | |
2697 | template<typename _RandomAccessIterator, typename _Distance, |
2698 | typename _Compare> |
2699 | _GLIBCXX20_CONSTEXPR |
2700 | void |
2701 | __chunk_insertion_sort(_RandomAccessIterator __first, |
2702 | _RandomAccessIterator __last, |
2703 | _Distance __chunk_size, _Compare __comp) |
2704 | { |
2705 | while (__last - __first >= __chunk_size) |
2706 | { |
2707 | std::__insertion_sort(__first, __first + __chunk_size, __comp); |
2708 | __first += __chunk_size; |
2709 | } |
2710 | std::__insertion_sort(__first, __last, __comp); |
2711 | } |
2712 | |
2713 | enum { _S_chunk_size = 7 }; |
2714 | |
2715 | template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> |
2716 | void |
2717 | __merge_sort_with_buffer(_RandomAccessIterator __first, |
2718 | _RandomAccessIterator __last, |
2719 | _Pointer __buffer, _Compare __comp) |
2720 | { |
2721 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type |
2722 | _Distance; |
2723 | |
2724 | const _Distance __len = __last - __first; |
2725 | const _Pointer __buffer_last = __buffer + __len; |
2726 | |
2727 | _Distance __step_size = _S_chunk_size; |
2728 | std::__chunk_insertion_sort(__first, __last, __step_size, __comp); |
2729 | |
2730 | while (__step_size < __len) |
2731 | { |
2732 | std::__merge_sort_loop(__first, __last, __buffer, |
2733 | __step_size, __comp); |
2734 | __step_size *= 2; |
2735 | std::__merge_sort_loop(__buffer, __buffer_last, __first, |
2736 | __step_size, __comp); |
2737 | __step_size *= 2; |
2738 | } |
2739 | } |
2740 | |
2741 | template<typename _RandomAccessIterator, typename _Pointer, |
2742 | typename _Distance, typename _Compare> |
2743 | void |
2744 | __stable_sort_adaptive(_RandomAccessIterator __first, |
2745 | _RandomAccessIterator __last, |
2746 | _Pointer __buffer, _Distance __buffer_size, |
2747 | _Compare __comp) |
2748 | { |
2749 | const _Distance __len = (__last - __first + 1) / 2; |
2750 | const _RandomAccessIterator __middle = __first + __len; |
2751 | if (__len > __buffer_size) |
2752 | { |
2753 | std::__stable_sort_adaptive(__first, __middle, __buffer, |
2754 | __buffer_size, __comp); |
2755 | std::__stable_sort_adaptive(__middle, __last, __buffer, |
2756 | __buffer_size, __comp); |
2757 | } |
2758 | else |
2759 | { |
2760 | std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); |
2761 | std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); |
2762 | } |
2763 | std::__merge_adaptive(__first, __middle, __last, |
2764 | _Distance(__middle - __first), |
2765 | _Distance(__last - __middle), |
2766 | __buffer, __buffer_size, |
2767 | __comp); |
2768 | } |
2769 | |
2770 | /// This is a helper function for the stable sorting routines. |
2771 | template<typename _RandomAccessIterator, typename _Compare> |
2772 | void |
2773 | __inplace_stable_sort(_RandomAccessIterator __first, |
2774 | _RandomAccessIterator __last, _Compare __comp) |
2775 | { |
2776 | if (__last - __first < 15) |
2777 | { |
2778 | std::__insertion_sort(__first, __last, __comp); |
2779 | return; |
2780 | } |
2781 | _RandomAccessIterator __middle = __first + (__last - __first) / 2; |
2782 | std::__inplace_stable_sort(__first, __middle, __comp); |
2783 | std::__inplace_stable_sort(__middle, __last, __comp); |
2784 | std::__merge_without_buffer(__first, __middle, __last, |
2785 | __middle - __first, |
2786 | __last - __middle, |
2787 | __comp); |
2788 | } |
2789 | |
2790 | // stable_sort |
2791 | |
2792 | // Set algorithms: includes, set_union, set_intersection, set_difference, |
2793 | // set_symmetric_difference. All of these algorithms have the precondition |
2794 | // that their input ranges are sorted and the postcondition that their output |
2795 | // ranges are sorted. |
2796 | |
2797 | template<typename _InputIterator1, typename _InputIterator2, |
2798 | typename _Compare> |
2799 | _GLIBCXX20_CONSTEXPR |
2800 | bool |
2801 | __includes(_InputIterator1 __first1, _InputIterator1 __last1, |
2802 | _InputIterator2 __first2, _InputIterator2 __last2, |
2803 | _Compare __comp) |
2804 | { |
2805 | while (__first1 != __last1 && __first2 != __last2) |
2806 | if (__comp(__first2, __first1)) |
2807 | return false; |
2808 | else if (__comp(__first1, __first2)) |
2809 | ++__first1; |
2810 | else |
2811 | { |
2812 | ++__first1; |
2813 | ++__first2; |
2814 | } |
2815 | |
2816 | return __first2 == __last2; |
2817 | } |
2818 | |
2819 | /** |
2820 | * @brief Determines whether all elements of a sequence exists in a range. |
2821 | * @param __first1 Start of search range. |
2822 | * @param __last1 End of search range. |
2823 | * @param __first2 Start of sequence |
2824 | * @param __last2 End of sequence. |
2825 | * @return True if each element in [__first2,__last2) is contained in order |
2826 | * within [__first1,__last1). False otherwise. |
2827 | * @ingroup set_algorithms |
2828 | * |
2829 | * This operation expects both [__first1,__last1) and |
2830 | * [__first2,__last2) to be sorted. Searches for the presence of |
2831 | * each element in [__first2,__last2) within [__first1,__last1). |
2832 | * The iterators over each range only move forward, so this is a |
2833 | * linear algorithm. If an element in [__first2,__last2) is not |
2834 | * found before the search iterator reaches @p __last2, false is |
2835 | * returned. |
2836 | */ |
2837 | template<typename _InputIterator1, typename _InputIterator2> |
2838 | _GLIBCXX20_CONSTEXPR |
2839 | inline bool |
2840 | includes(_InputIterator1 __first1, _InputIterator1 __last1, |
2841 | _InputIterator2 __first2, _InputIterator2 __last2) |
2842 | { |
2843 | // concept requirements |
2844 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
2845 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
2846 | __glibcxx_function_requires(_LessThanOpConcept< |
2847 | typename iterator_traits<_InputIterator1>::value_type, |
2848 | typename iterator_traits<_InputIterator2>::value_type>) |
2849 | __glibcxx_function_requires(_LessThanOpConcept< |
2850 | typename iterator_traits<_InputIterator2>::value_type, |
2851 | typename iterator_traits<_InputIterator1>::value_type>) |
2852 | __glibcxx_requires_sorted_set(__first1, __last1, __first2); |
2853 | __glibcxx_requires_sorted_set(__first2, __last2, __first1); |
2854 | __glibcxx_requires_irreflexive2(__first1, __last1); |
2855 | __glibcxx_requires_irreflexive2(__first2, __last2); |
2856 | |
2857 | return std::__includes(__first1, __last1, __first2, __last2, |
2858 | __gnu_cxx::__ops::__iter_less_iter()); |
2859 | } |
2860 | |
2861 | /** |
2862 | * @brief Determines whether all elements of a sequence exists in a range |
2863 | * using comparison. |
2864 | * @ingroup set_algorithms |
2865 | * @param __first1 Start of search range. |
2866 | * @param __last1 End of search range. |
2867 | * @param __first2 Start of sequence |
2868 | * @param __last2 End of sequence. |
2869 | * @param __comp Comparison function to use. |
2870 | * @return True if each element in [__first2,__last2) is contained |
2871 | * in order within [__first1,__last1) according to comp. False |
2872 | * otherwise. @ingroup set_algorithms |
2873 | * |
2874 | * This operation expects both [__first1,__last1) and |
2875 | * [__first2,__last2) to be sorted. Searches for the presence of |
2876 | * each element in [__first2,__last2) within [__first1,__last1), |
2877 | * using comp to decide. The iterators over each range only move |
2878 | * forward, so this is a linear algorithm. If an element in |
2879 | * [__first2,__last2) is not found before the search iterator |
2880 | * reaches @p __last2, false is returned. |
2881 | */ |
2882 | template<typename _InputIterator1, typename _InputIterator2, |
2883 | typename _Compare> |
2884 | _GLIBCXX20_CONSTEXPR |
2885 | inline bool |
2886 | includes(_InputIterator1 __first1, _InputIterator1 __last1, |
2887 | _InputIterator2 __first2, _InputIterator2 __last2, |
2888 | _Compare __comp) |
2889 | { |
2890 | // concept requirements |
2891 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
2892 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
2893 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2894 | typename iterator_traits<_InputIterator1>::value_type, |
2895 | typename iterator_traits<_InputIterator2>::value_type>) |
2896 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
2897 | typename iterator_traits<_InputIterator2>::value_type, |
2898 | typename iterator_traits<_InputIterator1>::value_type>) |
2899 | __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); |
2900 | __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); |
2901 | __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); |
2902 | __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); |
2903 | |
2904 | return std::__includes(__first1, __last1, __first2, __last2, |
2905 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
2906 | } |
2907 | |
2908 | // nth_element |
2909 | // merge |
2910 | // set_difference |
2911 | // set_intersection |
2912 | // set_union |
2913 | // stable_sort |
2914 | // set_symmetric_difference |
2915 | // min_element |
2916 | // max_element |
2917 | |
2918 | template<typename _BidirectionalIterator, typename _Compare> |
2919 | _GLIBCXX20_CONSTEXPR |
2920 | bool |
2921 | __next_permutation(_BidirectionalIterator __first, |
2922 | _BidirectionalIterator __last, _Compare __comp) |
2923 | { |
2924 | if (__first == __last) |
2925 | return false; |
2926 | _BidirectionalIterator __i = __first; |
2927 | ++__i; |
2928 | if (__i == __last) |
2929 | return false; |
2930 | __i = __last; |
2931 | --__i; |
2932 | |
2933 | for(;;) |
2934 | { |
2935 | _BidirectionalIterator __ii = __i; |
2936 | --__i; |
2937 | if (__comp(__i, __ii)) |
2938 | { |
2939 | _BidirectionalIterator __j = __last; |
2940 | while (!__comp(__i, --__j)) |
2941 | {} |
2942 | std::iter_swap(__i, __j); |
2943 | std::__reverse(__ii, __last, |
2944 | std::__iterator_category(__first)); |
2945 | return true; |
2946 | } |
2947 | if (__i == __first) |
2948 | { |
2949 | std::__reverse(__first, __last, |
2950 | std::__iterator_category(__first)); |
2951 | return false; |
2952 | } |
2953 | } |
2954 | } |
2955 | |
2956 | /** |
2957 | * @brief Permute range into the next @e dictionary ordering. |
2958 | * @ingroup sorting_algorithms |
2959 | * @param __first Start of range. |
2960 | * @param __last End of range. |
2961 | * @return False if wrapped to first permutation, true otherwise. |
2962 | * |
2963 | * Treats all permutations of the range as a set of @e dictionary sorted |
2964 | * sequences. Permutes the current sequence into the next one of this set. |
2965 | * Returns true if there are more sequences to generate. If the sequence |
2966 | * is the largest of the set, the smallest is generated and false returned. |
2967 | */ |
2968 | template<typename _BidirectionalIterator> |
2969 | _GLIBCXX20_CONSTEXPR |
2970 | inline bool |
2971 | next_permutation(_BidirectionalIterator __first, |
2972 | _BidirectionalIterator __last) |
2973 | { |
2974 | // concept requirements |
2975 | __glibcxx_function_requires(_BidirectionalIteratorConcept< |
2976 | _BidirectionalIterator>) |
2977 | __glibcxx_function_requires(_LessThanComparableConcept< |
2978 | typename iterator_traits<_BidirectionalIterator>::value_type>) |
2979 | __glibcxx_requires_valid_range(__first, __last); |
2980 | __glibcxx_requires_irreflexive(__first, __last); |
2981 | |
2982 | return std::__next_permutation |
2983 | (__first, __last, __gnu_cxx::__ops::__iter_less_iter()); |
2984 | } |
2985 | |
2986 | /** |
2987 | * @brief Permute range into the next @e dictionary ordering using |
2988 | * comparison functor. |
2989 | * @ingroup sorting_algorithms |
2990 | * @param __first Start of range. |
2991 | * @param __last End of range. |
2992 | * @param __comp A comparison functor. |
2993 | * @return False if wrapped to first permutation, true otherwise. |
2994 | * |
2995 | * Treats all permutations of the range [__first,__last) as a set of |
2996 | * @e dictionary sorted sequences ordered by @p __comp. Permutes the current |
2997 | * sequence into the next one of this set. Returns true if there are more |
2998 | * sequences to generate. If the sequence is the largest of the set, the |
2999 | * smallest is generated and false returned. |
3000 | */ |
3001 | template<typename _BidirectionalIterator, typename _Compare> |
3002 | _GLIBCXX20_CONSTEXPR |
3003 | inline bool |
3004 | next_permutation(_BidirectionalIterator __first, |
3005 | _BidirectionalIterator __last, _Compare __comp) |
3006 | { |
3007 | // concept requirements |
3008 | __glibcxx_function_requires(_BidirectionalIteratorConcept< |
3009 | _BidirectionalIterator>) |
3010 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
3011 | typename iterator_traits<_BidirectionalIterator>::value_type, |
3012 | typename iterator_traits<_BidirectionalIterator>::value_type>) |
3013 | __glibcxx_requires_valid_range(__first, __last); |
3014 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
3015 | |
3016 | return std::__next_permutation |
3017 | (__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
3018 | } |
3019 | |
3020 | template<typename _BidirectionalIterator, typename _Compare> |
3021 | _GLIBCXX20_CONSTEXPR |
3022 | bool |
3023 | __prev_permutation(_BidirectionalIterator __first, |
3024 | _BidirectionalIterator __last, _Compare __comp) |
3025 | { |
3026 | if (__first == __last) |
3027 | return false; |
3028 | _BidirectionalIterator __i = __first; |
3029 | ++__i; |
3030 | if (__i == __last) |
3031 | return false; |
3032 | __i = __last; |
3033 | --__i; |
3034 | |
3035 | for(;;) |
3036 | { |
3037 | _BidirectionalIterator __ii = __i; |
3038 | --__i; |
3039 | if (__comp(__ii, __i)) |
3040 | { |
3041 | _BidirectionalIterator __j = __last; |
3042 | while (!__comp(--__j, __i)) |
3043 | {} |
3044 | std::iter_swap(__i, __j); |
3045 | std::__reverse(__ii, __last, |
3046 | std::__iterator_category(__first)); |
3047 | return true; |
3048 | } |
3049 | if (__i == __first) |
3050 | { |
3051 | std::__reverse(__first, __last, |
3052 | std::__iterator_category(__first)); |
3053 | return false; |
3054 | } |
3055 | } |
3056 | } |
3057 | |
3058 | /** |
3059 | * @brief Permute range into the previous @e dictionary ordering. |
3060 | * @ingroup sorting_algorithms |
3061 | * @param __first Start of range. |
3062 | * @param __last End of range. |
3063 | * @return False if wrapped to last permutation, true otherwise. |
3064 | * |
3065 | * Treats all permutations of the range as a set of @e dictionary sorted |
3066 | * sequences. Permutes the current sequence into the previous one of this |
3067 | * set. Returns true if there are more sequences to generate. If the |
3068 | * sequence is the smallest of the set, the largest is generated and false |
3069 | * returned. |
3070 | */ |
3071 | template<typename _BidirectionalIterator> |
3072 | _GLIBCXX20_CONSTEXPR |
3073 | inline bool |
3074 | prev_permutation(_BidirectionalIterator __first, |
3075 | _BidirectionalIterator __last) |
3076 | { |
3077 | // concept requirements |
3078 | __glibcxx_function_requires(_BidirectionalIteratorConcept< |
3079 | _BidirectionalIterator>) |
3080 | __glibcxx_function_requires(_LessThanComparableConcept< |
3081 | typename iterator_traits<_BidirectionalIterator>::value_type>) |
3082 | __glibcxx_requires_valid_range(__first, __last); |
3083 | __glibcxx_requires_irreflexive(__first, __last); |
3084 | |
3085 | return std::__prev_permutation(__first, __last, |
3086 | __gnu_cxx::__ops::__iter_less_iter()); |
3087 | } |
3088 | |
3089 | /** |
3090 | * @brief Permute range into the previous @e dictionary ordering using |
3091 | * comparison functor. |
3092 | * @ingroup sorting_algorithms |
3093 | * @param __first Start of range. |
3094 | * @param __last End of range. |
3095 | * @param __comp A comparison functor. |
3096 | * @return False if wrapped to last permutation, true otherwise. |
3097 | * |
3098 | * Treats all permutations of the range [__first,__last) as a set of |
3099 | * @e dictionary sorted sequences ordered by @p __comp. Permutes the current |
3100 | * sequence into the previous one of this set. Returns true if there are |
3101 | * more sequences to generate. If the sequence is the smallest of the set, |
3102 | * the largest is generated and false returned. |
3103 | */ |
3104 | template<typename _BidirectionalIterator, typename _Compare> |
3105 | _GLIBCXX20_CONSTEXPR |
3106 | inline bool |
3107 | prev_permutation(_BidirectionalIterator __first, |
3108 | _BidirectionalIterator __last, _Compare __comp) |
3109 | { |
3110 | // concept requirements |
3111 | __glibcxx_function_requires(_BidirectionalIteratorConcept< |
3112 | _BidirectionalIterator>) |
3113 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
3114 | typename iterator_traits<_BidirectionalIterator>::value_type, |
3115 | typename iterator_traits<_BidirectionalIterator>::value_type>) |
3116 | __glibcxx_requires_valid_range(__first, __last); |
3117 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
3118 | |
3119 | return std::__prev_permutation(__first, __last, |
3120 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
3121 | } |
3122 | |
3123 | // replace |
3124 | // replace_if |
3125 | |
3126 | template<typename _InputIterator, typename _OutputIterator, |
3127 | typename _Predicate, typename _Tp> |
3128 | _GLIBCXX20_CONSTEXPR |
3129 | _OutputIterator |
3130 | __replace_copy_if(_InputIterator __first, _InputIterator __last, |
3131 | _OutputIterator __result, |
3132 | _Predicate __pred, const _Tp& __new_value) |
3133 | { |
3134 | for (; __first != __last; ++__first, (void)++__result) |
3135 | if (__pred(__first)) |
3136 | *__result = __new_value; |
3137 | else |
3138 | *__result = *__first; |
3139 | return __result; |
3140 | } |
3141 | |
3142 | /** |
3143 | * @brief Copy a sequence, replacing each element of one value with another |
3144 | * value. |
3145 | * @param __first An input iterator. |
3146 | * @param __last An input iterator. |
3147 | * @param __result An output iterator. |
3148 | * @param __old_value The value to be replaced. |
3149 | * @param __new_value The replacement value. |
3150 | * @return The end of the output sequence, @p result+(last-first). |
3151 | * |
3152 | * Copies each element in the input range @p [__first,__last) to the |
3153 | * output range @p [__result,__result+(__last-__first)) replacing elements |
3154 | * equal to @p __old_value with @p __new_value. |
3155 | */ |
3156 | template<typename _InputIterator, typename _OutputIterator, typename _Tp> |
3157 | _GLIBCXX20_CONSTEXPR |
3158 | inline _OutputIterator |
3159 | replace_copy(_InputIterator __first, _InputIterator __last, |
3160 | _OutputIterator __result, |
3161 | const _Tp& __old_value, const _Tp& __new_value) |
3162 | { |
3163 | // concept requirements |
3164 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
3165 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
3166 | typename iterator_traits<_InputIterator>::value_type>) |
3167 | __glibcxx_function_requires(_EqualOpConcept< |
3168 | typename iterator_traits<_InputIterator>::value_type, _Tp>) |
3169 | __glibcxx_requires_valid_range(__first, __last); |
3170 | |
3171 | return std::__replace_copy_if(__first, __last, __result, |
3172 | __gnu_cxx::__ops::__iter_equals_val(__old_value), |
3173 | __new_value); |
3174 | } |
3175 | |
3176 | /** |
3177 | * @brief Copy a sequence, replacing each value for which a predicate |
3178 | * returns true with another value. |
3179 | * @ingroup mutating_algorithms |
3180 | * @param __first An input iterator. |
3181 | * @param __last An input iterator. |
3182 | * @param __result An output iterator. |
3183 | * @param __pred A predicate. |
3184 | * @param __new_value The replacement value. |
3185 | * @return The end of the output sequence, @p __result+(__last-__first). |
3186 | * |
3187 | * Copies each element in the range @p [__first,__last) to the range |
3188 | * @p [__result,__result+(__last-__first)) replacing elements for which |
3189 | * @p __pred returns true with @p __new_value. |
3190 | */ |
3191 | template<typename _InputIterator, typename _OutputIterator, |
3192 | typename _Predicate, typename _Tp> |
3193 | _GLIBCXX20_CONSTEXPR |
3194 | inline _OutputIterator |
3195 | replace_copy_if(_InputIterator __first, _InputIterator __last, |
3196 | _OutputIterator __result, |
3197 | _Predicate __pred, const _Tp& __new_value) |
3198 | { |
3199 | // concept requirements |
3200 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
3201 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
3202 | typename iterator_traits<_InputIterator>::value_type>) |
3203 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
3204 | typename iterator_traits<_InputIterator>::value_type>) |
3205 | __glibcxx_requires_valid_range(__first, __last); |
3206 | |
3207 | return std::__replace_copy_if(__first, __last, __result, |
3208 | __gnu_cxx::__ops::__pred_iter(__pred), |
3209 | __new_value); |
3210 | } |
3211 | |
3212 | #if __cplusplus201703L >= 201103L |
3213 | /** |
3214 | * @brief Determines whether the elements of a sequence are sorted. |
3215 | * @ingroup sorting_algorithms |
3216 | * @param __first An iterator. |
3217 | * @param __last Another iterator. |
3218 | * @return True if the elements are sorted, false otherwise. |
3219 | */ |
3220 | template<typename _ForwardIterator> |
3221 | _GLIBCXX20_CONSTEXPR |
3222 | inline bool |
3223 | is_sorted(_ForwardIterator __first, _ForwardIterator __last) |
3224 | { return std::is_sorted_until(__first, __last) == __last; } |
3225 | |
3226 | /** |
3227 | * @brief Determines whether the elements of a sequence are sorted |
3228 | * according to a comparison functor. |
3229 | * @ingroup sorting_algorithms |
3230 | * @param __first An iterator. |
3231 | * @param __last Another iterator. |
3232 | * @param __comp A comparison functor. |
3233 | * @return True if the elements are sorted, false otherwise. |
3234 | */ |
3235 | template<typename _ForwardIterator, typename _Compare> |
3236 | _GLIBCXX20_CONSTEXPR |
3237 | inline bool |
3238 | is_sorted(_ForwardIterator __first, _ForwardIterator __last, |
3239 | _Compare __comp) |
3240 | { return std::is_sorted_until(__first, __last, __comp) == __last; } |
3241 | |
3242 | template<typename _ForwardIterator, typename _Compare> |
3243 | _GLIBCXX20_CONSTEXPR |
3244 | _ForwardIterator |
3245 | __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, |
3246 | _Compare __comp) |
3247 | { |
3248 | if (__first == __last) |
3249 | return __last; |
3250 | |
3251 | _ForwardIterator __next = __first; |
3252 | for (++__next; __next != __last; __first = __next, (void)++__next) |
3253 | if (__comp(__next, __first)) |
3254 | return __next; |
3255 | return __next; |
3256 | } |
3257 | |
3258 | /** |
3259 | * @brief Determines the end of a sorted sequence. |
3260 | * @ingroup sorting_algorithms |
3261 | * @param __first An iterator. |
3262 | * @param __last Another iterator. |
3263 | * @return An iterator pointing to the last iterator i in [__first, __last) |
3264 | * for which the range [__first, i) is sorted. |
3265 | */ |
3266 | template<typename _ForwardIterator> |
3267 | _GLIBCXX20_CONSTEXPR |
3268 | inline _ForwardIterator |
3269 | is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) |
3270 | { |
3271 | // concept requirements |
3272 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
3273 | __glibcxx_function_requires(_LessThanComparableConcept< |
3274 | typename iterator_traits<_ForwardIterator>::value_type>) |
3275 | __glibcxx_requires_valid_range(__first, __last); |
3276 | __glibcxx_requires_irreflexive(__first, __last); |
3277 | |
3278 | return std::__is_sorted_until(__first, __last, |
3279 | __gnu_cxx::__ops::__iter_less_iter()); |
3280 | } |
3281 | |
3282 | /** |
3283 | * @brief Determines the end of a sorted sequence using comparison functor. |
3284 | * @ingroup sorting_algorithms |
3285 | * @param __first An iterator. |
3286 | * @param __last Another iterator. |
3287 | * @param __comp A comparison functor. |
3288 | * @return An iterator pointing to the last iterator i in [__first, __last) |
3289 | * for which the range [__first, i) is sorted. |
3290 | */ |
3291 | template<typename _ForwardIterator, typename _Compare> |
3292 | _GLIBCXX20_CONSTEXPR |
3293 | inline _ForwardIterator |
3294 | is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, |
3295 | _Compare __comp) |
3296 | { |
3297 | // concept requirements |
3298 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
3299 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
3300 | typename iterator_traits<_ForwardIterator>::value_type, |
3301 | typename iterator_traits<_ForwardIterator>::value_type>) |
3302 | __glibcxx_requires_valid_range(__first, __last); |
3303 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
3304 | |
3305 | return std::__is_sorted_until(__first, __last, |
3306 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
3307 | } |
3308 | |
3309 | /** |
3310 | * @brief Determines min and max at once as an ordered pair. |
3311 | * @ingroup sorting_algorithms |
3312 | * @param __a A thing of arbitrary type. |
3313 | * @param __b Another thing of arbitrary type. |
3314 | * @return A pair(__b, __a) if __b is smaller than __a, pair(__a, |
3315 | * __b) otherwise. |
3316 | */ |
3317 | template<typename _Tp> |
3318 | _GLIBCXX14_CONSTEXPRconstexpr |
3319 | inline pair<const _Tp&, const _Tp&> |
3320 | minmax(const _Tp& __a, const _Tp& __b) |
3321 | { |
3322 | // concept requirements |
3323 | __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) |
3324 | |
3325 | return __b < __a ? pair<const _Tp&, const _Tp&>(__b, __a) |
3326 | : pair<const _Tp&, const _Tp&>(__a, __b); |
3327 | } |
3328 | |
3329 | /** |
3330 | * @brief Determines min and max at once as an ordered pair. |
3331 | * @ingroup sorting_algorithms |
3332 | * @param __a A thing of arbitrary type. |
3333 | * @param __b Another thing of arbitrary type. |
3334 | * @param __comp A @link comparison_functors comparison functor @endlink. |
3335 | * @return A pair(__b, __a) if __b is smaller than __a, pair(__a, |
3336 | * __b) otherwise. |
3337 | */ |
3338 | template<typename _Tp, typename _Compare> |
3339 | _GLIBCXX14_CONSTEXPRconstexpr |
3340 | inline pair<const _Tp&, const _Tp&> |
3341 | minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) |
3342 | { |
3343 | return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) |
3344 | : pair<const _Tp&, const _Tp&>(__a, __b); |
3345 | } |
3346 | |
3347 | template<typename _ForwardIterator, typename _Compare> |
3348 | _GLIBCXX14_CONSTEXPRconstexpr |
3349 | pair<_ForwardIterator, _ForwardIterator> |
3350 | __minmax_element(_ForwardIterator __first, _ForwardIterator __last, |
3351 | _Compare __comp) |
3352 | { |
3353 | _ForwardIterator __next = __first; |
3354 | if (__first == __last |
3355 | || ++__next == __last) |
3356 | return std::make_pair(__first, __first); |
3357 | |
3358 | _ForwardIterator __min{}, __max{}; |
3359 | if (__comp(__next, __first)) |
3360 | { |
3361 | __min = __next; |
3362 | __max = __first; |
3363 | } |
3364 | else |
3365 | { |
3366 | __min = __first; |
3367 | __max = __next; |
3368 | } |
3369 | |
3370 | __first = __next; |
3371 | ++__first; |
3372 | |
3373 | while (__first != __last) |
3374 | { |
3375 | __next = __first; |
3376 | if (++__next == __last) |
3377 | { |
3378 | if (__comp(__first, __min)) |
3379 | __min = __first; |
3380 | else if (!__comp(__first, __max)) |
3381 | __max = __first; |
3382 | break; |
3383 | } |
3384 | |
3385 | if (__comp(__next, __first)) |
3386 | { |
3387 | if (__comp(__next, __min)) |
3388 | __min = __next; |
3389 | if (!__comp(__first, __max)) |
3390 | __max = __first; |
3391 | } |
3392 | else |
3393 | { |
3394 | if (__comp(__first, __min)) |
3395 | __min = __first; |
3396 | if (!__comp(__next, __max)) |
3397 | __max = __next; |
3398 | } |
3399 | |
3400 | __first = __next; |
3401 | ++__first; |
3402 | } |
3403 | |
3404 | return std::make_pair(__min, __max); |
3405 | } |
3406 | |
3407 | /** |
3408 | * @brief Return a pair of iterators pointing to the minimum and maximum |
3409 | * elements in a range. |
3410 | * @ingroup sorting_algorithms |
3411 | * @param __first Start of range. |
3412 | * @param __last End of range. |
3413 | * @return make_pair(m, M), where m is the first iterator i in |
3414 | * [__first, __last) such that no other element in the range is |
3415 | * smaller, and where M is the last iterator i in [__first, __last) |
3416 | * such that no other element in the range is larger. |
3417 | */ |
3418 | template<typename _ForwardIterator> |
3419 | _GLIBCXX14_CONSTEXPRconstexpr |
3420 | inline pair<_ForwardIterator, _ForwardIterator> |
3421 | minmax_element(_ForwardIterator __first, _ForwardIterator __last) |
3422 | { |
3423 | // concept requirements |
3424 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
3425 | __glibcxx_function_requires(_LessThanComparableConcept< |
3426 | typename iterator_traits<_ForwardIterator>::value_type>) |
3427 | __glibcxx_requires_valid_range(__first, __last); |
3428 | __glibcxx_requires_irreflexive(__first, __last); |
3429 | |
3430 | return std::__minmax_element(__first, __last, |
3431 | __gnu_cxx::__ops::__iter_less_iter()); |
3432 | } |
3433 | |
3434 | /** |
3435 | * @brief Return a pair of iterators pointing to the minimum and maximum |
3436 | * elements in a range. |
3437 | * @ingroup sorting_algorithms |
3438 | * @param __first Start of range. |
3439 | * @param __last End of range. |
3440 | * @param __comp Comparison functor. |
3441 | * @return make_pair(m, M), where m is the first iterator i in |
3442 | * [__first, __last) such that no other element in the range is |
3443 | * smaller, and where M is the last iterator i in [__first, __last) |
3444 | * such that no other element in the range is larger. |
3445 | */ |
3446 | template<typename _ForwardIterator, typename _Compare> |
3447 | _GLIBCXX14_CONSTEXPRconstexpr |
3448 | inline pair<_ForwardIterator, _ForwardIterator> |
3449 | minmax_element(_ForwardIterator __first, _ForwardIterator __last, |
3450 | _Compare __comp) |
3451 | { |
3452 | // concept requirements |
3453 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
3454 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
3455 | typename iterator_traits<_ForwardIterator>::value_type, |
3456 | typename iterator_traits<_ForwardIterator>::value_type>) |
3457 | __glibcxx_requires_valid_range(__first, __last); |
3458 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
3459 | |
3460 | return std::__minmax_element(__first, __last, |
3461 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
3462 | } |
3463 | |
3464 | // N2722 + DR 915. |
3465 | template<typename _Tp> |
3466 | _GLIBCXX14_CONSTEXPRconstexpr |
3467 | inline _Tp |
3468 | min(initializer_list<_Tp> __l) |
3469 | { return *std::min_element(__l.begin(), __l.end()); } |
3470 | |
3471 | template<typename _Tp, typename _Compare> |
3472 | _GLIBCXX14_CONSTEXPRconstexpr |
3473 | inline _Tp |
3474 | min(initializer_list<_Tp> __l, _Compare __comp) |
3475 | { return *std::min_element(__l.begin(), __l.end(), __comp); } |
3476 | |
3477 | template<typename _Tp> |
3478 | _GLIBCXX14_CONSTEXPRconstexpr |
3479 | inline _Tp |
3480 | max(initializer_list<_Tp> __l) |
3481 | { return *std::max_element(__l.begin(), __l.end()); } |
3482 | |
3483 | template<typename _Tp, typename _Compare> |
3484 | _GLIBCXX14_CONSTEXPRconstexpr |
3485 | inline _Tp |
3486 | max(initializer_list<_Tp> __l, _Compare __comp) |
3487 | { return *std::max_element(__l.begin(), __l.end(), __comp); } |
3488 | |
3489 | template<typename _Tp> |
3490 | _GLIBCXX14_CONSTEXPRconstexpr |
3491 | inline pair<_Tp, _Tp> |
3492 | minmax(initializer_list<_Tp> __l) |
3493 | { |
3494 | pair<const _Tp*, const _Tp*> __p = |
3495 | std::minmax_element(__l.begin(), __l.end()); |
3496 | return std::make_pair(*__p.first, *__p.second); |
3497 | } |
3498 | |
3499 | template<typename _Tp, typename _Compare> |
3500 | _GLIBCXX14_CONSTEXPRconstexpr |
3501 | inline pair<_Tp, _Tp> |
3502 | minmax(initializer_list<_Tp> __l, _Compare __comp) |
3503 | { |
3504 | pair<const _Tp*, const _Tp*> __p = |
3505 | std::minmax_element(__l.begin(), __l.end(), __comp); |
3506 | return std::make_pair(*__p.first, *__p.second); |
3507 | } |
3508 | |
3509 | /** |
3510 | * @brief Checks whether a permutation of the second sequence is equal |
3511 | * to the first sequence. |
3512 | * @ingroup non_mutating_algorithms |
3513 | * @param __first1 Start of first range. |
3514 | * @param __last1 End of first range. |
3515 | * @param __first2 Start of second range. |
3516 | * @param __pred A binary predicate. |
3517 | * @return true if there exists a permutation of the elements in |
3518 | * the range [__first2, __first2 + (__last1 - __first1)), |
3519 | * beginning with ForwardIterator2 begin, such that |
3520 | * equal(__first1, __last1, __begin, __pred) returns true; |
3521 | * otherwise, returns false. |
3522 | */ |
3523 | template<typename _ForwardIterator1, typename _ForwardIterator2, |
3524 | typename _BinaryPredicate> |
3525 | _GLIBCXX20_CONSTEXPR |
3526 | inline bool |
3527 | is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
3528 | _ForwardIterator2 __first2, _BinaryPredicate __pred) |
3529 | { |
3530 | // concept requirements |
3531 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) |
3532 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) |
3533 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
3534 | typename iterator_traits<_ForwardIterator1>::value_type, |
3535 | typename iterator_traits<_ForwardIterator2>::value_type>) |
3536 | __glibcxx_requires_valid_range(__first1, __last1); |
3537 | |
3538 | return std::__is_permutation(__first1, __last1, __first2, |
3539 | __gnu_cxx::__ops::__iter_comp_iter(__pred)); |
3540 | } |
3541 | |
3542 | #if __cplusplus201703L > 201103L |
3543 | template<typename _ForwardIterator1, typename _ForwardIterator2, |
3544 | typename _BinaryPredicate> |
3545 | _GLIBCXX20_CONSTEXPR |
3546 | bool |
3547 | __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
3548 | _ForwardIterator2 __first2, _ForwardIterator2 __last2, |
3549 | _BinaryPredicate __pred) |
3550 | { |
3551 | using _Cat1 |
3552 | = typename iterator_traits<_ForwardIterator1>::iterator_category; |
3553 | using _Cat2 |
3554 | = typename iterator_traits<_ForwardIterator2>::iterator_category; |
3555 | using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; |
3556 | using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; |
3557 | constexpr bool __ra_iters = _It1_is_RA() && _It2_is_RA(); |
3558 | if (__ra_iters) |
3559 | { |
3560 | auto __d1 = std::distance(__first1, __last1); |
3561 | auto __d2 = std::distance(__first2, __last2); |
3562 | if (__d1 != __d2) |
3563 | return false; |
3564 | } |
3565 | |
3566 | // Efficiently compare identical prefixes: O(N) if sequences |
3567 | // have the same elements in the same order. |
3568 | for (; __first1 != __last1 && __first2 != __last2; |
3569 | ++__first1, (void)++__first2) |
3570 | if (!__pred(__first1, __first2)) |
3571 | break; |
3572 | |
3573 | if (__ra_iters) |
3574 | { |
3575 | if (__first1 == __last1) |
3576 | return true; |
3577 | } |
3578 | else |
3579 | { |
3580 | auto __d1 = std::distance(__first1, __last1); |
3581 | auto __d2 = std::distance(__first2, __last2); |
3582 | if (__d1 == 0 && __d2 == 0) |
3583 | return true; |
3584 | if (__d1 != __d2) |
3585 | return false; |
3586 | } |
3587 | |
3588 | for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) |
3589 | { |
3590 | if (__scan != std::__find_if(__first1, __scan, |
3591 | __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))) |
3592 | continue; // We've seen this one before. |
3593 | |
3594 | auto __matches = std::__count_if(__first2, __last2, |
3595 | __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)); |
3596 | if (0 == __matches |
3597 | || std::__count_if(__scan, __last1, |
3598 | __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)) |
3599 | != __matches) |
3600 | return false; |
3601 | } |
3602 | return true; |
3603 | } |
3604 | |
3605 | /** |
3606 | * @brief Checks whether a permutaion of the second sequence is equal |
3607 | * to the first sequence. |
3608 | * @ingroup non_mutating_algorithms |
3609 | * @param __first1 Start of first range. |
3610 | * @param __last1 End of first range. |
3611 | * @param __first2 Start of second range. |
3612 | * @param __last2 End of first range. |
3613 | * @return true if there exists a permutation of the elements in the range |
3614 | * [__first2, __last2), beginning with ForwardIterator2 begin, |
3615 | * such that equal(__first1, __last1, begin) returns true; |
3616 | * otherwise, returns false. |
3617 | */ |
3618 | template<typename _ForwardIterator1, typename _ForwardIterator2> |
3619 | _GLIBCXX20_CONSTEXPR |
3620 | inline bool |
3621 | is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
3622 | _ForwardIterator2 __first2, _ForwardIterator2 __last2) |
3623 | { |
3624 | __glibcxx_requires_valid_range(__first1, __last1); |
3625 | __glibcxx_requires_valid_range(__first2, __last2); |
3626 | |
3627 | return |
3628 | std::__is_permutation(__first1, __last1, __first2, __last2, |
3629 | __gnu_cxx::__ops::__iter_equal_to_iter()); |
3630 | } |
3631 | |
3632 | /** |
3633 | * @brief Checks whether a permutation of the second sequence is equal |
3634 | * to the first sequence. |
3635 | * @ingroup non_mutating_algorithms |
3636 | * @param __first1 Start of first range. |
3637 | * @param __last1 End of first range. |
3638 | * @param __first2 Start of second range. |
3639 | * @param __last2 End of first range. |
3640 | * @param __pred A binary predicate. |
3641 | * @return true if there exists a permutation of the elements in the range |
3642 | * [__first2, __last2), beginning with ForwardIterator2 begin, |
3643 | * such that equal(__first1, __last1, __begin, __pred) returns true; |
3644 | * otherwise, returns false. |
3645 | */ |
3646 | template<typename _ForwardIterator1, typename _ForwardIterator2, |
3647 | typename _BinaryPredicate> |
3648 | _GLIBCXX20_CONSTEXPR |
3649 | inline bool |
3650 | is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
3651 | _ForwardIterator2 __first2, _ForwardIterator2 __last2, |
3652 | _BinaryPredicate __pred) |
3653 | { |
3654 | __glibcxx_requires_valid_range(__first1, __last1); |
3655 | __glibcxx_requires_valid_range(__first2, __last2); |
3656 | |
3657 | return std::__is_permutation(__first1, __last1, __first2, __last2, |
3658 | __gnu_cxx::__ops::__iter_comp_iter(__pred)); |
3659 | } |
3660 | |
3661 | #if __cplusplus201703L > 201402L |
3662 | |
3663 | #define __cpp_lib_clamp201603 201603 |
3664 | |
3665 | /** |
3666 | * @brief Returns the value clamped between lo and hi. |
3667 | * @ingroup sorting_algorithms |
3668 | * @param __val A value of arbitrary type. |
3669 | * @param __lo A lower limit of arbitrary type. |
3670 | * @param __hi An upper limit of arbitrary type. |
3671 | * @return max(__val, __lo) if __val < __hi or min(__val, __hi) otherwise. |
3672 | */ |
3673 | template<typename _Tp> |
3674 | constexpr const _Tp& |
3675 | clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi) |
3676 | { |
3677 | __glibcxx_assert(!(__hi < __lo)); |
3678 | return (__val < __lo) ? __lo : (__hi < __val) ? __hi : __val; |
3679 | } |
3680 | |
3681 | /** |
3682 | * @brief Returns the value clamped between lo and hi. |
3683 | * @ingroup sorting_algorithms |
3684 | * @param __val A value of arbitrary type. |
3685 | * @param __lo A lower limit of arbitrary type. |
3686 | * @param __hi An upper limit of arbitrary type. |
3687 | * @param __comp A comparison functor. |
3688 | * @return max(__val, __lo, __comp) if __comp(__val, __hi) |
3689 | * or min(__val, __hi, __comp) otherwise. |
3690 | */ |
3691 | template<typename _Tp, typename _Compare> |
3692 | constexpr const _Tp& |
3693 | clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi, _Compare __comp) |
3694 | { |
3695 | __glibcxx_assert(!__comp(__hi, __lo)); |
3696 | return __comp(__val, __lo) ? __lo : __comp(__hi, __val) ? __hi : __val; |
3697 | } |
3698 | #endif // C++17 |
3699 | #endif // C++14 |
3700 | |
3701 | #ifdef _GLIBCXX_USE_C99_STDINT_TR11 |
3702 | /** |
3703 | * @brief Generate two uniformly distributed integers using a |
3704 | * single distribution invocation. |
3705 | * @param __b0 The upper bound for the first integer. |
3706 | * @param __b1 The upper bound for the second integer. |
3707 | * @param __g A UniformRandomBitGenerator. |
3708 | * @return A pair (i, j) with i and j uniformly distributed |
3709 | * over [0, __b0) and [0, __b1), respectively. |
3710 | * |
3711 | * Requires: __b0 * __b1 <= __g.max() - __g.min(). |
3712 | * |
3713 | * Using uniform_int_distribution with a range that is very |
3714 | * small relative to the range of the generator ends up wasting |
3715 | * potentially expensively generated randomness, since |
3716 | * uniform_int_distribution does not store leftover randomness |
3717 | * between invocations. |
3718 | * |
3719 | * If we know we want two integers in ranges that are sufficiently |
3720 | * small, we can compose the ranges, use a single distribution |
3721 | * invocation, and significantly reduce the waste. |
3722 | */ |
3723 | template<typename _IntType, typename _UniformRandomBitGenerator> |
3724 | pair<_IntType, _IntType> |
3725 | __gen_two_uniform_ints(_IntType __b0, _IntType __b1, |
3726 | _UniformRandomBitGenerator&& __g) |
3727 | { |
3728 | _IntType __x |
3729 | = uniform_int_distribution<_IntType>{0, (__b0 * __b1) - 1}(__g); |
3730 | return std::make_pair(__x / __b1, __x % __b1); |
3731 | } |
3732 | |
3733 | /** |
3734 | * @brief Shuffle the elements of a sequence using a uniform random |
3735 | * number generator. |
3736 | * @ingroup mutating_algorithms |
3737 | * @param __first A forward iterator. |
3738 | * @param __last A forward iterator. |
3739 | * @param __g A UniformRandomNumberGenerator (26.5.1.3). |
3740 | * @return Nothing. |
3741 | * |
3742 | * Reorders the elements in the range @p [__first,__last) using @p __g to |
3743 | * provide random numbers. |
3744 | */ |
3745 | template<typename _RandomAccessIterator, |
3746 | typename _UniformRandomNumberGenerator> |
3747 | void |
3748 | shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, |
3749 | _UniformRandomNumberGenerator&& __g) |
3750 | { |
3751 | // concept requirements |
3752 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
3753 | _RandomAccessIterator>) |
3754 | __glibcxx_requires_valid_range(__first, __last); |
3755 | |
3756 | if (__first == __last) |
3757 | return; |
3758 | |
3759 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type |
3760 | _DistanceType; |
3761 | |
3762 | typedef typename std::make_unsigned<_DistanceType>::type __ud_type; |
3763 | typedef typename std::uniform_int_distribution<__ud_type> __distr_type; |
3764 | typedef typename __distr_type::param_type __p_type; |
3765 | |
3766 | typedef typename remove_reference<_UniformRandomNumberGenerator>::type |
3767 | _Gen; |
3768 | typedef typename common_type<typename _Gen::result_type, __ud_type>::type |
3769 | __uc_type; |
3770 | |
3771 | const __uc_type __urngrange = __g.max() - __g.min(); |
3772 | const __uc_type __urange = __uc_type(__last - __first); |
3773 | |
3774 | if (__urngrange / __urange >= __urange) |
3775 | // I.e. (__urngrange >= __urange * __urange) but without wrap issues. |
3776 | { |
3777 | _RandomAccessIterator __i = __first + 1; |
3778 | |
3779 | // Since we know the range isn't empty, an even number of elements |
3780 | // means an uneven number of elements /to swap/, in which case we |
3781 | // do the first one up front: |
3782 | |
3783 | if ((__urange % 2) == 0) |
3784 | { |
3785 | __distr_type __d{0, 1}; |
3786 | std::iter_swap(__i++, __first + __d(__g)); |
3787 | } |
3788 | |
3789 | // Now we know that __last - __i is even, so we do the rest in pairs, |
3790 | // using a single distribution invocation to produce swap positions |
3791 | // for two successive elements at a time: |
3792 | |
3793 | while (__i != __last) |
3794 | { |
3795 | const __uc_type __swap_range = __uc_type(__i - __first) + 1; |
3796 | |
3797 | const pair<__uc_type, __uc_type> __pospos = |
3798 | __gen_two_uniform_ints(__swap_range, __swap_range + 1, __g); |
3799 | |
3800 | std::iter_swap(__i++, __first + __pospos.first); |
3801 | std::iter_swap(__i++, __first + __pospos.second); |
3802 | } |
3803 | |
3804 | return; |
3805 | } |
3806 | |
3807 | __distr_type __d; |
3808 | |
3809 | for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) |
3810 | std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first))); |
3811 | } |
3812 | #endif |
3813 | |
3814 | #endif // C++11 |
3815 | |
3816 | _GLIBCXX_BEGIN_NAMESPACE_ALGO |
3817 | |
3818 | /** |
3819 | * @brief Apply a function to every element of a sequence. |
3820 | * @ingroup non_mutating_algorithms |
3821 | * @param __first An input iterator. |
3822 | * @param __last An input iterator. |
3823 | * @param __f A unary function object. |
3824 | * @return @p __f |
3825 | * |
3826 | * Applies the function object @p __f to each element in the range |
3827 | * @p [first,last). @p __f must not modify the order of the sequence. |
3828 | * If @p __f has a return value it is ignored. |
3829 | */ |
3830 | template<typename _InputIterator, typename _Function> |
3831 | _GLIBCXX20_CONSTEXPR |
3832 | _Function |
3833 | for_each(_InputIterator __first, _InputIterator __last, _Function __f) |
3834 | { |
3835 | // concept requirements |
3836 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
3837 | __glibcxx_requires_valid_range(__first, __last); |
3838 | for (; __first != __last; ++__first) |
3839 | __f(*__first); |
3840 | return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant. |
3841 | } |
3842 | |
3843 | #if __cplusplus201703L >= 201703L |
3844 | /** |
3845 | * @brief Apply a function to every element of a sequence. |
3846 | * @ingroup non_mutating_algorithms |
3847 | * @param __first An input iterator. |
3848 | * @param __n A value convertible to an integer. |
3849 | * @param __f A unary function object. |
3850 | * @return `__first+__n` |
3851 | * |
3852 | * Applies the function object `__f` to each element in the range |
3853 | * `[first, first+n)`. `__f` must not modify the order of the sequence. |
3854 | * If `__f` has a return value it is ignored. |
3855 | */ |
3856 | template<typename _InputIterator, typename _Size, typename _Function> |
3857 | _InputIterator |
3858 | for_each_n(_InputIterator __first, _Size __n, _Function __f) |
3859 | { |
3860 | auto __n2 = std::__size_to_integer(__n); |
3861 | using _Cat = typename iterator_traits<_InputIterator>::iterator_category; |
3862 | if constexpr (is_base_of_v<random_access_iterator_tag, _Cat>) |
3863 | { |
3864 | if (__n2 <= 0) |
3865 | return __first; |
3866 | auto __last = __first + __n2; |
3867 | std::for_each(__first, __last, std::move(__f)); |
3868 | return __last; |
3869 | } |
3870 | else |
3871 | { |
3872 | while (__n2-->0) |
3873 | { |
3874 | __f(*__first); |
3875 | ++__first; |
3876 | } |
3877 | return __first; |
3878 | } |
3879 | } |
3880 | #endif // C++17 |
3881 | |
3882 | /** |
3883 | * @brief Find the first occurrence of a value in a sequence. |
3884 | * @ingroup non_mutating_algorithms |
3885 | * @param __first An input iterator. |
3886 | * @param __last An input iterator. |
3887 | * @param __val The value to find. |
3888 | * @return The first iterator @c i in the range @p [__first,__last) |
3889 | * such that @c *i == @p __val, or @p __last if no such iterator exists. |
3890 | */ |
3891 | template<typename _InputIterator, typename _Tp> |
3892 | _GLIBCXX20_CONSTEXPR |
3893 | inline _InputIterator |
3894 | find(_InputIterator __first, _InputIterator __last, |
3895 | const _Tp& __val) |
3896 | { |
3897 | // concept requirements |
3898 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
3899 | __glibcxx_function_requires(_EqualOpConcept< |
3900 | typename iterator_traits<_InputIterator>::value_type, _Tp>) |
3901 | __glibcxx_requires_valid_range(__first, __last); |
3902 | return std::__find_if(__first, __last, |
3903 | __gnu_cxx::__ops::__iter_equals_val(__val)); |
3904 | } |
3905 | |
3906 | /** |
3907 | * @brief Find the first element in a sequence for which a |
3908 | * predicate is true. |
3909 | * @ingroup non_mutating_algorithms |
3910 | * @param __first An input iterator. |
3911 | * @param __last An input iterator. |
3912 | * @param __pred A predicate. |
3913 | * @return The first iterator @c i in the range @p [__first,__last) |
3914 | * such that @p __pred(*i) is true, or @p __last if no such iterator exists. |
3915 | */ |
3916 | template<typename _InputIterator, typename _Predicate> |
3917 | _GLIBCXX20_CONSTEXPR |
3918 | inline _InputIterator |
3919 | find_if(_InputIterator __first, _InputIterator __last, |
3920 | _Predicate __pred) |
3921 | { |
3922 | // concept requirements |
3923 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
3924 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
3925 | typename iterator_traits<_InputIterator>::value_type>) |
3926 | __glibcxx_requires_valid_range(__first, __last); |
3927 | |
3928 | return std::__find_if(__first, __last, |
3929 | __gnu_cxx::__ops::__pred_iter(__pred)); |
3930 | } |
3931 | |
3932 | /** |
3933 | * @brief Find element from a set in a sequence. |
3934 | * @ingroup non_mutating_algorithms |
3935 | * @param __first1 Start of range to search. |
3936 | * @param __last1 End of range to search. |
3937 | * @param __first2 Start of match candidates. |
3938 | * @param __last2 End of match candidates. |
3939 | * @return The first iterator @c i in the range |
3940 | * @p [__first1,__last1) such that @c *i == @p *(i2) such that i2 is an |
3941 | * iterator in [__first2,__last2), or @p __last1 if no such iterator exists. |
3942 | * |
3943 | * Searches the range @p [__first1,__last1) for an element that is |
3944 | * equal to some element in the range [__first2,__last2). If |
3945 | * found, returns an iterator in the range [__first1,__last1), |
3946 | * otherwise returns @p __last1. |
3947 | */ |
3948 | template<typename _InputIterator, typename _ForwardIterator> |
3949 | _GLIBCXX20_CONSTEXPR |
3950 | _InputIterator |
3951 | find_first_of(_InputIterator __first1, _InputIterator __last1, |
3952 | _ForwardIterator __first2, _ForwardIterator __last2) |
3953 | { |
3954 | // concept requirements |
3955 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
3956 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
3957 | __glibcxx_function_requires(_EqualOpConcept< |
3958 | typename iterator_traits<_InputIterator>::value_type, |
3959 | typename iterator_traits<_ForwardIterator>::value_type>) |
3960 | __glibcxx_requires_valid_range(__first1, __last1); |
3961 | __glibcxx_requires_valid_range(__first2, __last2); |
3962 | |
3963 | for (; __first1 != __last1; ++__first1) |
3964 | for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) |
3965 | if (*__first1 == *__iter) |
3966 | return __first1; |
3967 | return __last1; |
3968 | } |
3969 | |
3970 | /** |
3971 | * @brief Find element from a set in a sequence using a predicate. |
3972 | * @ingroup non_mutating_algorithms |
3973 | * @param __first1 Start of range to search. |
3974 | * @param __last1 End of range to search. |
3975 | * @param __first2 Start of match candidates. |
3976 | * @param __last2 End of match candidates. |
3977 | * @param __comp Predicate to use. |
3978 | * @return The first iterator @c i in the range |
3979 | * @p [__first1,__last1) such that @c comp(*i, @p *(i2)) is true |
3980 | * and i2 is an iterator in [__first2,__last2), or @p __last1 if no |
3981 | * such iterator exists. |
3982 | * |
3983 | |
3984 | * Searches the range @p [__first1,__last1) for an element that is |
3985 | * equal to some element in the range [__first2,__last2). If |
3986 | * found, returns an iterator in the range [__first1,__last1), |
3987 | * otherwise returns @p __last1. |
3988 | */ |
3989 | template<typename _InputIterator, typename _ForwardIterator, |
3990 | typename _BinaryPredicate> |
3991 | _GLIBCXX20_CONSTEXPR |
3992 | _InputIterator |
3993 | find_first_of(_InputIterator __first1, _InputIterator __last1, |
3994 | _ForwardIterator __first2, _ForwardIterator __last2, |
3995 | _BinaryPredicate __comp) |
3996 | { |
3997 | // concept requirements |
3998 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
3999 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
4000 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
4001 | typename iterator_traits<_InputIterator>::value_type, |
4002 | typename iterator_traits<_ForwardIterator>::value_type>) |
4003 | __glibcxx_requires_valid_range(__first1, __last1); |
4004 | __glibcxx_requires_valid_range(__first2, __last2); |
4005 | |
4006 | for (; __first1 != __last1; ++__first1) |
4007 | for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) |
4008 | if (__comp(*__first1, *__iter)) |
4009 | return __first1; |
4010 | return __last1; |
4011 | } |
4012 | |
4013 | /** |
4014 | * @brief Find two adjacent values in a sequence that are equal. |
4015 | * @ingroup non_mutating_algorithms |
4016 | * @param __first A forward iterator. |
4017 | * @param __last A forward iterator. |
4018 | * @return The first iterator @c i such that @c i and @c i+1 are both |
4019 | * valid iterators in @p [__first,__last) and such that @c *i == @c *(i+1), |
4020 | * or @p __last if no such iterator exists. |
4021 | */ |
4022 | template<typename _ForwardIterator> |
4023 | _GLIBCXX20_CONSTEXPR |
4024 | inline _ForwardIterator |
4025 | adjacent_find(_ForwardIterator __first, _ForwardIterator __last) |
4026 | { |
4027 | // concept requirements |
4028 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
4029 | __glibcxx_function_requires(_EqualityComparableConcept< |
4030 | typename iterator_traits<_ForwardIterator>::value_type>) |
4031 | __glibcxx_requires_valid_range(__first, __last); |
4032 | |
4033 | return std::__adjacent_find(__first, __last, |
4034 | __gnu_cxx::__ops::__iter_equal_to_iter()); |
4035 | } |
4036 | |
4037 | /** |
4038 | * @brief Find two adjacent values in a sequence using a predicate. |
4039 | * @ingroup non_mutating_algorithms |
4040 | * @param __first A forward iterator. |
4041 | * @param __last A forward iterator. |
4042 | * @param __binary_pred A binary predicate. |
4043 | * @return The first iterator @c i such that @c i and @c i+1 are both |
4044 | * valid iterators in @p [__first,__last) and such that |
4045 | * @p __binary_pred(*i,*(i+1)) is true, or @p __last if no such iterator |
4046 | * exists. |
4047 | */ |
4048 | template<typename _ForwardIterator, typename _BinaryPredicate> |
4049 | _GLIBCXX20_CONSTEXPR |
4050 | inline _ForwardIterator |
4051 | adjacent_find(_ForwardIterator __first, _ForwardIterator __last, |
4052 | _BinaryPredicate __binary_pred) |
4053 | { |
4054 | // concept requirements |
4055 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
4056 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
4057 | typename iterator_traits<_ForwardIterator>::value_type, |
4058 | typename iterator_traits<_ForwardIterator>::value_type>) |
4059 | __glibcxx_requires_valid_range(__first, __last); |
4060 | |
4061 | return std::__adjacent_find(__first, __last, |
4062 | __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); |
4063 | } |
4064 | |
4065 | /** |
4066 | * @brief Count the number of copies of a value in a sequence. |
4067 | * @ingroup non_mutating_algorithms |
4068 | * @param __first An input iterator. |
4069 | * @param __last An input iterator. |
4070 | * @param __value The value to be counted. |
4071 | * @return The number of iterators @c i in the range @p [__first,__last) |
4072 | * for which @c *i == @p __value |
4073 | */ |
4074 | template<typename _InputIterator, typename _Tp> |
4075 | _GLIBCXX20_CONSTEXPR |
4076 | inline typename iterator_traits<_InputIterator>::difference_type |
4077 | count(_InputIterator __first, _InputIterator __last, const _Tp& __value) |
4078 | { |
4079 | // concept requirements |
4080 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
4081 | __glibcxx_function_requires(_EqualOpConcept< |
4082 | typename iterator_traits<_InputIterator>::value_type, _Tp>) |
4083 | __glibcxx_requires_valid_range(__first, __last); |
4084 | |
4085 | return std::__count_if(__first, __last, |
4086 | __gnu_cxx::__ops::__iter_equals_val(__value)); |
4087 | } |
4088 | |
4089 | /** |
4090 | * @brief Count the elements of a sequence for which a predicate is true. |
4091 | * @ingroup non_mutating_algorithms |
4092 | * @param __first An input iterator. |
4093 | * @param __last An input iterator. |
4094 | * @param __pred A predicate. |
4095 | * @return The number of iterators @c i in the range @p [__first,__last) |
4096 | * for which @p __pred(*i) is true. |
4097 | */ |
4098 | template<typename _InputIterator, typename _Predicate> |
4099 | _GLIBCXX20_CONSTEXPR |
4100 | inline typename iterator_traits<_InputIterator>::difference_type |
4101 | count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) |
4102 | { |
4103 | // concept requirements |
4104 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
4105 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
4106 | typename iterator_traits<_InputIterator>::value_type>) |
4107 | __glibcxx_requires_valid_range(__first, __last); |
4108 | |
4109 | return std::__count_if(__first, __last, |
4110 | __gnu_cxx::__ops::__pred_iter(__pred)); |
4111 | } |
4112 | |
4113 | /** |
4114 | * @brief Search a sequence for a matching sub-sequence. |
4115 | * @ingroup non_mutating_algorithms |
4116 | * @param __first1 A forward iterator. |
4117 | * @param __last1 A forward iterator. |
4118 | * @param __first2 A forward iterator. |
4119 | * @param __last2 A forward iterator. |
4120 | * @return The first iterator @c i in the range @p |
4121 | * [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == @p |
4122 | * *(__first2+N) for each @c N in the range @p |
4123 | * [0,__last2-__first2), or @p __last1 if no such iterator exists. |
4124 | * |
4125 | * Searches the range @p [__first1,__last1) for a sub-sequence that |
4126 | * compares equal value-by-value with the sequence given by @p |
4127 | * [__first2,__last2) and returns an iterator to the first element |
4128 | * of the sub-sequence, or @p __last1 if the sub-sequence is not |
4129 | * found. |
4130 | * |
4131 | * Because the sub-sequence must lie completely within the range @p |
4132 | * [__first1,__last1) it must start at a position less than @p |
4133 | * __last1-(__last2-__first2) where @p __last2-__first2 is the |
4134 | * length of the sub-sequence. |
4135 | * |
4136 | * This means that the returned iterator @c i will be in the range |
4137 | * @p [__first1,__last1-(__last2-__first2)) |
4138 | */ |
4139 | template<typename _ForwardIterator1, typename _ForwardIterator2> |
4140 | _GLIBCXX20_CONSTEXPR |
4141 | inline _ForwardIterator1 |
4142 | search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
4143 | _ForwardIterator2 __first2, _ForwardIterator2 __last2) |
4144 | { |
4145 | // concept requirements |
4146 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) |
4147 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) |
4148 | __glibcxx_function_requires(_EqualOpConcept< |
4149 | typename iterator_traits<_ForwardIterator1>::value_type, |
4150 | typename iterator_traits<_ForwardIterator2>::value_type>) |
4151 | __glibcxx_requires_valid_range(__first1, __last1); |
4152 | __glibcxx_requires_valid_range(__first2, __last2); |
4153 | |
4154 | return std::__search(__first1, __last1, __first2, __last2, |
4155 | __gnu_cxx::__ops::__iter_equal_to_iter()); |
4156 | } |
4157 | |
4158 | /** |
4159 | * @brief Search a sequence for a matching sub-sequence using a predicate. |
4160 | * @ingroup non_mutating_algorithms |
4161 | * @param __first1 A forward iterator. |
4162 | * @param __last1 A forward iterator. |
4163 | * @param __first2 A forward iterator. |
4164 | * @param __last2 A forward iterator. |
4165 | * @param __predicate A binary predicate. |
4166 | * @return The first iterator @c i in the range |
4167 | * @p [__first1,__last1-(__last2-__first2)) such that |
4168 | * @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range |
4169 | * @p [0,__last2-__first2), or @p __last1 if no such iterator exists. |
4170 | * |
4171 | * Searches the range @p [__first1,__last1) for a sub-sequence that |
4172 | * compares equal value-by-value with the sequence given by @p |
4173 | * [__first2,__last2), using @p __predicate to determine equality, |
4174 | * and returns an iterator to the first element of the |
4175 | * sub-sequence, or @p __last1 if no such iterator exists. |
4176 | * |
4177 | * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) |
4178 | */ |
4179 | template<typename _ForwardIterator1, typename _ForwardIterator2, |
4180 | typename _BinaryPredicate> |
4181 | _GLIBCXX20_CONSTEXPR |
4182 | inline _ForwardIterator1 |
4183 | search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
4184 | _ForwardIterator2 __first2, _ForwardIterator2 __last2, |
4185 | _BinaryPredicate __predicate) |
4186 | { |
4187 | // concept requirements |
4188 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) |
4189 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) |
4190 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
4191 | typename iterator_traits<_ForwardIterator1>::value_type, |
4192 | typename iterator_traits<_ForwardIterator2>::value_type>) |
4193 | __glibcxx_requires_valid_range(__first1, __last1); |
4194 | __glibcxx_requires_valid_range(__first2, __last2); |
4195 | |
4196 | return std::__search(__first1, __last1, __first2, __last2, |
4197 | __gnu_cxx::__ops::__iter_comp_iter(__predicate)); |
4198 | } |
4199 | |
4200 | /** |
4201 | * @brief Search a sequence for a number of consecutive values. |
4202 | * @ingroup non_mutating_algorithms |
4203 | * @param __first A forward iterator. |
4204 | * @param __last A forward iterator. |
4205 | * @param __count The number of consecutive values. |
4206 | * @param __val The value to find. |
4207 | * @return The first iterator @c i in the range @p |
4208 | * [__first,__last-__count) such that @c *(i+N) == @p __val for |
4209 | * each @c N in the range @p [0,__count), or @p __last if no such |
4210 | * iterator exists. |
4211 | * |
4212 | * Searches the range @p [__first,__last) for @p count consecutive elements |
4213 | * equal to @p __val. |
4214 | */ |
4215 | template<typename _ForwardIterator, typename _Integer, typename _Tp> |
4216 | _GLIBCXX20_CONSTEXPR |
4217 | inline _ForwardIterator |
4218 | search_n(_ForwardIterator __first, _ForwardIterator __last, |
4219 | _Integer __count, const _Tp& __val) |
4220 | { |
4221 | // concept requirements |
4222 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
4223 | __glibcxx_function_requires(_EqualOpConcept< |
4224 | typename iterator_traits<_ForwardIterator>::value_type, _Tp>) |
4225 | __glibcxx_requires_valid_range(__first, __last); |
4226 | |
4227 | return std::__search_n(__first, __last, __count, |
4228 | __gnu_cxx::__ops::__iter_equals_val(__val)); |
4229 | } |
4230 | |
4231 | |
4232 | /** |
4233 | * @brief Search a sequence for a number of consecutive values using a |
4234 | * predicate. |
4235 | * @ingroup non_mutating_algorithms |
4236 | * @param __first A forward iterator. |
4237 | * @param __last A forward iterator. |
4238 | * @param __count The number of consecutive values. |
4239 | * @param __val The value to find. |
4240 | * @param __binary_pred A binary predicate. |
4241 | * @return The first iterator @c i in the range @p |
4242 | * [__first,__last-__count) such that @p |
4243 | * __binary_pred(*(i+N),__val) is true for each @c N in the range |
4244 | * @p [0,__count), or @p __last if no such iterator exists. |
4245 | * |
4246 | * Searches the range @p [__first,__last) for @p __count |
4247 | * consecutive elements for which the predicate returns true. |
4248 | */ |
4249 | template<typename _ForwardIterator, typename _Integer, typename _Tp, |
4250 | typename _BinaryPredicate> |
4251 | _GLIBCXX20_CONSTEXPR |
4252 | inline _ForwardIterator |
4253 | search_n(_ForwardIterator __first, _ForwardIterator __last, |
4254 | _Integer __count, const _Tp& __val, |
4255 | _BinaryPredicate __binary_pred) |
4256 | { |
4257 | // concept requirements |
4258 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
4259 | __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, |
4260 | typename iterator_traits<_ForwardIterator>::value_type, _Tp>) |
4261 | __glibcxx_requires_valid_range(__first, __last); |
4262 | |
4263 | return std::__search_n(__first, __last, __count, |
4264 | __gnu_cxx::__ops::__iter_comp_val(__binary_pred, __val)); |
4265 | } |
4266 | |
4267 | #if __cplusplus201703L > 201402L |
4268 | /** @brief Search a sequence using a Searcher object. |
4269 | * |
4270 | * @param __first A forward iterator. |
4271 | * @param __last A forward iterator. |
4272 | * @param __searcher A callable object. |
4273 | * @return @p __searcher(__first,__last).first |
4274 | */ |
4275 | template<typename _ForwardIterator, typename _Searcher> |
4276 | inline _ForwardIterator |
4277 | search(_ForwardIterator __first, _ForwardIterator __last, |
4278 | const _Searcher& __searcher) |
4279 | { return __searcher(__first, __last).first; } |
4280 | #endif |
4281 | |
4282 | /** |
4283 | * @brief Perform an operation on a sequence. |
4284 | * @ingroup mutating_algorithms |
4285 | * @param __first An input iterator. |
4286 | * @param __last An input iterator. |
4287 | * @param __result An output iterator. |
4288 | * @param __unary_op A unary operator. |
4289 | * @return An output iterator equal to @p __result+(__last-__first). |
4290 | * |
4291 | * Applies the operator to each element in the input range and assigns |
4292 | * the results to successive elements of the output sequence. |
4293 | * Evaluates @p *(__result+N)=unary_op(*(__first+N)) for each @c N in the |
4294 | * range @p [0,__last-__first). |
4295 | * |
4296 | * @p unary_op must not alter its argument. |
4297 | */ |
4298 | template<typename _InputIterator, typename _OutputIterator, |
4299 | typename _UnaryOperation> |
4300 | _GLIBCXX20_CONSTEXPR |
4301 | _OutputIterator |
4302 | transform(_InputIterator __first, _InputIterator __last, |
4303 | _OutputIterator __result, _UnaryOperation __unary_op) |
4304 | { |
4305 | // concept requirements |
4306 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
4307 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
4308 | // "the type returned by a _UnaryOperation" |
4309 | __typeof__(__unary_op(*__first))>) |
4310 | __glibcxx_requires_valid_range(__first, __last); |
4311 | |
4312 | for (; __first != __last; ++__first, (void)++__result) |
4313 | *__result = __unary_op(*__first); |
4314 | return __result; |
4315 | } |
4316 | |
4317 | /** |
4318 | * @brief Perform an operation on corresponding elements of two sequences. |
4319 | * @ingroup mutating_algorithms |
4320 | * @param __first1 An input iterator. |
4321 | * @param __last1 An input iterator. |
4322 | * @param __first2 An input iterator. |
4323 | * @param __result An output iterator. |
4324 | * @param __binary_op A binary operator. |
4325 | * @return An output iterator equal to @p result+(last-first). |
4326 | * |
4327 | * Applies the operator to the corresponding elements in the two |
4328 | * input ranges and assigns the results to successive elements of the |
4329 | * output sequence. |
4330 | * Evaluates @p |
4331 | * *(__result+N)=__binary_op(*(__first1+N),*(__first2+N)) for each |
4332 | * @c N in the range @p [0,__last1-__first1). |
4333 | * |
4334 | * @p binary_op must not alter either of its arguments. |
4335 | */ |
4336 | template<typename _InputIterator1, typename _InputIterator2, |
4337 | typename _OutputIterator, typename _BinaryOperation> |
4338 | _GLIBCXX20_CONSTEXPR |
4339 | _OutputIterator |
4340 | transform(_InputIterator1 __first1, _InputIterator1 __last1, |
4341 | _InputIterator2 __first2, _OutputIterator __result, |
4342 | _BinaryOperation __binary_op) |
4343 | { |
4344 | // concept requirements |
4345 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
4346 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
4347 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
4348 | // "the type returned by a _BinaryOperation" |
4349 | __typeof__(__binary_op(*__first1,*__first2))>) |
4350 | __glibcxx_requires_valid_range(__first1, __last1); |
4351 | |
4352 | for (; __first1 != __last1; ++__first1, (void)++__first2, ++__result) |
4353 | *__result = __binary_op(*__first1, *__first2); |
4354 | return __result; |
4355 | } |
4356 | |
4357 | /** |
4358 | * @brief Replace each occurrence of one value in a sequence with another |
4359 | * value. |
4360 | * @ingroup mutating_algorithms |
4361 | * @param __first A forward iterator. |
4362 | * @param __last A forward iterator. |
4363 | * @param __old_value The value to be replaced. |
4364 | * @param __new_value The replacement value. |
4365 | * @return replace() returns no value. |
4366 | * |
4367 | * For each iterator @c i in the range @p [__first,__last) if @c *i == |
4368 | * @p __old_value then the assignment @c *i = @p __new_value is performed. |
4369 | */ |
4370 | template<typename _ForwardIterator, typename _Tp> |
4371 | _GLIBCXX20_CONSTEXPR |
4372 | void |
4373 | replace(_ForwardIterator __first, _ForwardIterator __last, |
4374 | const _Tp& __old_value, const _Tp& __new_value) |
4375 | { |
4376 | // concept requirements |
4377 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
4378 | _ForwardIterator>) |
4379 | __glibcxx_function_requires(_EqualOpConcept< |
4380 | typename iterator_traits<_ForwardIterator>::value_type, _Tp>) |
4381 | __glibcxx_function_requires(_ConvertibleConcept<_Tp, |
4382 | typename iterator_traits<_ForwardIterator>::value_type>) |
4383 | __glibcxx_requires_valid_range(__first, __last); |
4384 | |
4385 | for (; __first != __last; ++__first) |
4386 | if (*__first == __old_value) |
4387 | *__first = __new_value; |
4388 | } |
4389 | |
4390 | /** |
4391 | * @brief Replace each value in a sequence for which a predicate returns |
4392 | * true with another value. |
4393 | * @ingroup mutating_algorithms |
4394 | * @param __first A forward iterator. |
4395 | * @param __last A forward iterator. |
4396 | * @param __pred A predicate. |
4397 | * @param __new_value The replacement value. |
4398 | * @return replace_if() returns no value. |
4399 | * |
4400 | * For each iterator @c i in the range @p [__first,__last) if @p __pred(*i) |
4401 | * is true then the assignment @c *i = @p __new_value is performed. |
4402 | */ |
4403 | template<typename _ForwardIterator, typename _Predicate, typename _Tp> |
4404 | _GLIBCXX20_CONSTEXPR |
4405 | void |
4406 | replace_if(_ForwardIterator __first, _ForwardIterator __last, |
4407 | _Predicate __pred, const _Tp& __new_value) |
4408 | { |
4409 | // concept requirements |
4410 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
4411 | _ForwardIterator>) |
4412 | __glibcxx_function_requires(_ConvertibleConcept<_Tp, |
4413 | typename iterator_traits<_ForwardIterator>::value_type>) |
4414 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
4415 | typename iterator_traits<_ForwardIterator>::value_type>) |
4416 | __glibcxx_requires_valid_range(__first, __last); |
4417 | |
4418 | for (; __first != __last; ++__first) |
4419 | if (__pred(*__first)) |
4420 | *__first = __new_value; |
4421 | } |
4422 | |
4423 | /** |
4424 | * @brief Assign the result of a function object to each value in a |
4425 | * sequence. |
4426 | * @ingroup mutating_algorithms |
4427 | * @param __first A forward iterator. |
4428 | * @param __last A forward iterator. |
4429 | * @param __gen A function object taking no arguments and returning |
4430 | * std::iterator_traits<_ForwardIterator>::value_type |
4431 | * @return generate() returns no value. |
4432 | * |
4433 | * Performs the assignment @c *i = @p __gen() for each @c i in the range |
4434 | * @p [__first,__last). |
4435 | */ |
4436 | template<typename _ForwardIterator, typename _Generator> |
4437 | _GLIBCXX20_CONSTEXPR |
4438 | void |
4439 | generate(_ForwardIterator __first, _ForwardIterator __last, |
4440 | _Generator __gen) |
4441 | { |
4442 | // concept requirements |
4443 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
4444 | __glibcxx_function_requires(_GeneratorConcept<_Generator, |
4445 | typename iterator_traits<_ForwardIterator>::value_type>) |
4446 | __glibcxx_requires_valid_range(__first, __last); |
4447 | |
4448 | for (; __first != __last; ++__first) |
4449 | *__first = __gen(); |
4450 | } |
4451 | |
4452 | /** |
4453 | * @brief Assign the result of a function object to each value in a |
4454 | * sequence. |
4455 | * @ingroup mutating_algorithms |
4456 | * @param __first A forward iterator. |
4457 | * @param __n The length of the sequence. |
4458 | * @param __gen A function object taking no arguments and returning |
4459 | * std::iterator_traits<_ForwardIterator>::value_type |
4460 | * @return The end of the sequence, @p __first+__n |
4461 | * |
4462 | * Performs the assignment @c *i = @p __gen() for each @c i in the range |
4463 | * @p [__first,__first+__n). |
4464 | * |
4465 | * If @p __n is negative, the function does nothing and returns @p __first. |
4466 | */ |
4467 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
4468 | // DR 865. More algorithms that throw away information |
4469 | // DR 426. search_n(), fill_n(), and generate_n() with negative n |
4470 | template<typename _OutputIterator, typename _Size, typename _Generator> |
4471 | _GLIBCXX20_CONSTEXPR |
4472 | _OutputIterator |
4473 | generate_n(_OutputIterator __first, _Size __n, _Generator __gen) |
4474 | { |
4475 | // concept requirements |
4476 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
4477 | // "the type returned by a _Generator" |
4478 | __typeof__(__gen())>) |
4479 | |
4480 | typedef __decltype(std::__size_to_integer(__n)) _IntSize; |
4481 | for (_IntSize __niter = std::__size_to_integer(__n); |
4482 | __niter > 0; --__niter, (void) ++__first) |
4483 | *__first = __gen(); |
4484 | return __first; |
4485 | } |
4486 | |
4487 | /** |
4488 | * @brief Copy a sequence, removing consecutive duplicate values. |
4489 | * @ingroup mutating_algorithms |
4490 | * @param __first An input iterator. |
4491 | * @param __last An input iterator. |
4492 | * @param __result An output iterator. |
4493 | * @return An iterator designating the end of the resulting sequence. |
4494 | * |
4495 | * Copies each element in the range @p [__first,__last) to the range |
4496 | * beginning at @p __result, except that only the first element is copied |
4497 | * from groups of consecutive elements that compare equal. |
4498 | * unique_copy() is stable, so the relative order of elements that are |
4499 | * copied is unchanged. |
4500 | * |
4501 | * _GLIBCXX_RESOLVE_LIB_DEFECTS |
4502 | * DR 241. Does unique_copy() require CopyConstructible and Assignable? |
4503 | * |
4504 | * _GLIBCXX_RESOLVE_LIB_DEFECTS |
4505 | * DR 538. 241 again: Does unique_copy() require CopyConstructible and |
4506 | * Assignable? |
4507 | */ |
4508 | template<typename _InputIterator, typename _OutputIterator> |
4509 | _GLIBCXX20_CONSTEXPR |
4510 | inline _OutputIterator |
4511 | unique_copy(_InputIterator __first, _InputIterator __last, |
4512 | _OutputIterator __result) |
4513 | { |
4514 | // concept requirements |
4515 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
4516 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
4517 | typename iterator_traits<_InputIterator>::value_type>) |
4518 | __glibcxx_function_requires(_EqualityComparableConcept< |
4519 | typename iterator_traits<_InputIterator>::value_type>) |
4520 | __glibcxx_requires_valid_range(__first, __last); |
4521 | |
4522 | if (__first == __last) |
4523 | return __result; |
4524 | return std::__unique_copy(__first, __last, __result, |
4525 | __gnu_cxx::__ops::__iter_equal_to_iter(), |
4526 | std::__iterator_category(__first), |
4527 | std::__iterator_category(__result)); |
4528 | } |
4529 | |
4530 | /** |
4531 | * @brief Copy a sequence, removing consecutive values using a predicate. |
4532 | * @ingroup mutating_algorithms |
4533 | * @param __first An input iterator. |
4534 | * @param __last An input iterator. |
4535 | * @param __result An output iterator. |
4536 | * @param __binary_pred A binary predicate. |
4537 | * @return An iterator designating the end of the resulting sequence. |
4538 | * |
4539 | * Copies each element in the range @p [__first,__last) to the range |
4540 | * beginning at @p __result, except that only the first element is copied |
4541 | * from groups of consecutive elements for which @p __binary_pred returns |
4542 | * true. |
4543 | * unique_copy() is stable, so the relative order of elements that are |
4544 | * copied is unchanged. |
4545 | * |
4546 | * _GLIBCXX_RESOLVE_LIB_DEFECTS |
4547 | * DR 241. Does unique_copy() require CopyConstructible and Assignable? |
4548 | */ |
4549 | template<typename _InputIterator, typename _OutputIterator, |
4550 | typename _BinaryPredicate> |
4551 | _GLIBCXX20_CONSTEXPR |
4552 | inline _OutputIterator |
4553 | unique_copy(_InputIterator __first, _InputIterator __last, |
4554 | _OutputIterator __result, |
4555 | _BinaryPredicate __binary_pred) |
4556 | { |
4557 | // concept requirements -- predicates checked later |
4558 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) |
4559 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
4560 | typename iterator_traits<_InputIterator>::value_type>) |
4561 | __glibcxx_requires_valid_range(__first, __last); |
4562 | |
4563 | if (__first == __last) |
4564 | return __result; |
4565 | return std::__unique_copy(__first, __last, __result, |
4566 | __gnu_cxx::__ops::__iter_comp_iter(__binary_pred), |
4567 | std::__iterator_category(__first), |
4568 | std::__iterator_category(__result)); |
4569 | } |
4570 | |
4571 | #if _GLIBCXX_HOSTED1 |
4572 | /** |
4573 | * @brief Randomly shuffle the elements of a sequence. |
4574 | * @ingroup mutating_algorithms |
4575 | * @param __first A forward iterator. |
4576 | * @param __last A forward iterator. |
4577 | * @return Nothing. |
4578 | * |
4579 | * Reorder the elements in the range @p [__first,__last) using a random |
4580 | * distribution, so that every possible ordering of the sequence is |
4581 | * equally likely. |
4582 | */ |
4583 | template<typename _RandomAccessIterator> |
4584 | inline void |
4585 | random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) |
4586 | { |
4587 | // concept requirements |
4588 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4589 | _RandomAccessIterator>) |
4590 | __glibcxx_requires_valid_range(__first, __last); |
4591 | |
4592 | if (__first != __last) |
4593 | for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) |
4594 | { |
4595 | // XXX rand() % N is not uniformly distributed |
4596 | _RandomAccessIterator __j = __first |
4597 | + std::rand() % ((__i - __first) + 1); |
4598 | if (__i != __j) |
4599 | std::iter_swap(__i, __j); |
4600 | } |
4601 | } |
4602 | #endif |
4603 | |
4604 | /** |
4605 | * @brief Shuffle the elements of a sequence using a random number |
4606 | * generator. |
4607 | * @ingroup mutating_algorithms |
4608 | * @param __first A forward iterator. |
4609 | * @param __last A forward iterator. |
4610 | * @param __rand The RNG functor or function. |
4611 | * @return Nothing. |
4612 | * |
4613 | * Reorders the elements in the range @p [__first,__last) using @p __rand to |
4614 | * provide a random distribution. Calling @p __rand(N) for a positive |
4615 | * integer @p N should return a randomly chosen integer from the |
4616 | * range [0,N). |
4617 | */ |
4618 | template<typename _RandomAccessIterator, typename _RandomNumberGenerator> |
4619 | void |
4620 | random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, |
4621 | #if __cplusplus201703L >= 201103L |
4622 | _RandomNumberGenerator&& __rand) |
4623 | #else |
4624 | _RandomNumberGenerator& __rand) |
4625 | #endif |
4626 | { |
4627 | // concept requirements |
4628 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4629 | _RandomAccessIterator>) |
4630 | __glibcxx_requires_valid_range(__first, __last); |
4631 | |
4632 | if (__first == __last) |
4633 | return; |
4634 | for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) |
4635 | { |
4636 | _RandomAccessIterator __j = __first + __rand((__i - __first) + 1); |
4637 | if (__i != __j) |
4638 | std::iter_swap(__i, __j); |
4639 | } |
4640 | } |
4641 | |
4642 | |
4643 | /** |
4644 | * @brief Move elements for which a predicate is true to the beginning |
4645 | * of a sequence. |
4646 | * @ingroup mutating_algorithms |
4647 | * @param __first A forward iterator. |
4648 | * @param __last A forward iterator. |
4649 | * @param __pred A predicate functor. |
4650 | * @return An iterator @p middle such that @p __pred(i) is true for each |
4651 | * iterator @p i in the range @p [__first,middle) and false for each @p i |
4652 | * in the range @p [middle,__last). |
4653 | * |
4654 | * @p __pred must not modify its operand. @p partition() does not preserve |
4655 | * the relative ordering of elements in each group, use |
4656 | * @p stable_partition() if this is needed. |
4657 | */ |
4658 | template<typename _ForwardIterator, typename _Predicate> |
4659 | _GLIBCXX20_CONSTEXPR |
4660 | inline _ForwardIterator |
4661 | partition(_ForwardIterator __first, _ForwardIterator __last, |
4662 | _Predicate __pred) |
4663 | { |
4664 | // concept requirements |
4665 | __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< |
4666 | _ForwardIterator>) |
4667 | __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, |
4668 | typename iterator_traits<_ForwardIterator>::value_type>) |
4669 | __glibcxx_requires_valid_range(__first, __last); |
4670 | |
4671 | return std::__partition(__first, __last, __pred, |
4672 | std::__iterator_category(__first)); |
4673 | } |
4674 | |
4675 | |
4676 | /** |
4677 | * @brief Sort the smallest elements of a sequence. |
4678 | * @ingroup sorting_algorithms |
4679 | * @param __first An iterator. |
4680 | * @param __middle Another iterator. |
4681 | * @param __last Another iterator. |
4682 | * @return Nothing. |
4683 | * |
4684 | * Sorts the smallest @p (__middle-__first) elements in the range |
4685 | * @p [first,last) and moves them to the range @p [__first,__middle). The |
4686 | * order of the remaining elements in the range @p [__middle,__last) is |
4687 | * undefined. |
4688 | * After the sort if @e i and @e j are iterators in the range |
4689 | * @p [__first,__middle) such that i precedes j and @e k is an iterator in |
4690 | * the range @p [__middle,__last) then *j<*i and *k<*i are both false. |
4691 | */ |
4692 | template<typename _RandomAccessIterator> |
4693 | _GLIBCXX20_CONSTEXPR |
4694 | inline void |
4695 | partial_sort(_RandomAccessIterator __first, |
4696 | _RandomAccessIterator __middle, |
4697 | _RandomAccessIterator __last) |
4698 | { |
4699 | // concept requirements |
4700 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4701 | _RandomAccessIterator>) |
4702 | __glibcxx_function_requires(_LessThanComparableConcept< |
4703 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
4704 | __glibcxx_requires_valid_range(__first, __middle); |
4705 | __glibcxx_requires_valid_range(__middle, __last); |
4706 | __glibcxx_requires_irreflexive(__first, __last); |
4707 | |
4708 | std::__partial_sort(__first, __middle, __last, |
4709 | __gnu_cxx::__ops::__iter_less_iter()); |
4710 | } |
4711 | |
4712 | /** |
4713 | * @brief Sort the smallest elements of a sequence using a predicate |
4714 | * for comparison. |
4715 | * @ingroup sorting_algorithms |
4716 | * @param __first An iterator. |
4717 | * @param __middle Another iterator. |
4718 | * @param __last Another iterator. |
4719 | * @param __comp A comparison functor. |
4720 | * @return Nothing. |
4721 | * |
4722 | * Sorts the smallest @p (__middle-__first) elements in the range |
4723 | * @p [__first,__last) and moves them to the range @p [__first,__middle). The |
4724 | * order of the remaining elements in the range @p [__middle,__last) is |
4725 | * undefined. |
4726 | * After the sort if @e i and @e j are iterators in the range |
4727 | * @p [__first,__middle) such that i precedes j and @e k is an iterator in |
4728 | * the range @p [__middle,__last) then @p *__comp(j,*i) and @p __comp(*k,*i) |
4729 | * are both false. |
4730 | */ |
4731 | template<typename _RandomAccessIterator, typename _Compare> |
4732 | _GLIBCXX20_CONSTEXPR |
4733 | inline void |
4734 | partial_sort(_RandomAccessIterator __first, |
4735 | _RandomAccessIterator __middle, |
4736 | _RandomAccessIterator __last, |
4737 | _Compare __comp) |
4738 | { |
4739 | // concept requirements |
4740 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4741 | _RandomAccessIterator>) |
4742 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
4743 | typename iterator_traits<_RandomAccessIterator>::value_type, |
4744 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
4745 | __glibcxx_requires_valid_range(__first, __middle); |
4746 | __glibcxx_requires_valid_range(__middle, __last); |
4747 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
4748 | |
4749 | std::__partial_sort(__first, __middle, __last, |
4750 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
4751 | } |
4752 | |
4753 | /** |
4754 | * @brief Sort a sequence just enough to find a particular position. |
4755 | * @ingroup sorting_algorithms |
4756 | * @param __first An iterator. |
4757 | * @param __nth Another iterator. |
4758 | * @param __last Another iterator. |
4759 | * @return Nothing. |
4760 | * |
4761 | * Rearranges the elements in the range @p [__first,__last) so that @p *__nth |
4762 | * is the same element that would have been in that position had the |
4763 | * whole sequence been sorted. The elements either side of @p *__nth are |
4764 | * not completely sorted, but for any iterator @e i in the range |
4765 | * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it |
4766 | * holds that *j < *i is false. |
4767 | */ |
4768 | template<typename _RandomAccessIterator> |
4769 | _GLIBCXX20_CONSTEXPR |
4770 | inline void |
4771 | nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, |
4772 | _RandomAccessIterator __last) |
4773 | { |
4774 | // concept requirements |
4775 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4776 | _RandomAccessIterator>) |
4777 | __glibcxx_function_requires(_LessThanComparableConcept< |
4778 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
4779 | __glibcxx_requires_valid_range(__first, __nth); |
4780 | __glibcxx_requires_valid_range(__nth, __last); |
4781 | __glibcxx_requires_irreflexive(__first, __last); |
4782 | |
4783 | if (__first == __last || __nth == __last) |
4784 | return; |
4785 | |
4786 | std::__introselect(__first, __nth, __last, |
4787 | std::__lg(__last - __first) * 2, |
4788 | __gnu_cxx::__ops::__iter_less_iter()); |
4789 | } |
4790 | |
4791 | /** |
4792 | * @brief Sort a sequence just enough to find a particular position |
4793 | * using a predicate for comparison. |
4794 | * @ingroup sorting_algorithms |
4795 | * @param __first An iterator. |
4796 | * @param __nth Another iterator. |
4797 | * @param __last Another iterator. |
4798 | * @param __comp A comparison functor. |
4799 | * @return Nothing. |
4800 | * |
4801 | * Rearranges the elements in the range @p [__first,__last) so that @p *__nth |
4802 | * is the same element that would have been in that position had the |
4803 | * whole sequence been sorted. The elements either side of @p *__nth are |
4804 | * not completely sorted, but for any iterator @e i in the range |
4805 | * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it |
4806 | * holds that @p __comp(*j,*i) is false. |
4807 | */ |
4808 | template<typename _RandomAccessIterator, typename _Compare> |
4809 | _GLIBCXX20_CONSTEXPR |
4810 | inline void |
4811 | nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, |
4812 | _RandomAccessIterator __last, _Compare __comp) |
4813 | { |
4814 | // concept requirements |
4815 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4816 | _RandomAccessIterator>) |
4817 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
4818 | typename iterator_traits<_RandomAccessIterator>::value_type, |
4819 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
4820 | __glibcxx_requires_valid_range(__first, __nth); |
4821 | __glibcxx_requires_valid_range(__nth, __last); |
4822 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
4823 | |
4824 | if (__first == __last || __nth == __last) |
4825 | return; |
4826 | |
4827 | std::__introselect(__first, __nth, __last, |
4828 | std::__lg(__last - __first) * 2, |
4829 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
4830 | } |
4831 | |
4832 | /** |
4833 | * @brief Sort the elements of a sequence. |
4834 | * @ingroup sorting_algorithms |
4835 | * @param __first An iterator. |
4836 | * @param __last Another iterator. |
4837 | * @return Nothing. |
4838 | * |
4839 | * Sorts the elements in the range @p [__first,__last) in ascending order, |
4840 | * such that for each iterator @e i in the range @p [__first,__last-1), |
4841 | * *(i+1)<*i is false. |
4842 | * |
4843 | * The relative ordering of equivalent elements is not preserved, use |
4844 | * @p stable_sort() if this is needed. |
4845 | */ |
4846 | template<typename _RandomAccessIterator> |
4847 | _GLIBCXX20_CONSTEXPR |
4848 | inline void |
4849 | sort(_RandomAccessIterator __first, _RandomAccessIterator __last) |
4850 | { |
4851 | // concept requirements |
4852 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4853 | _RandomAccessIterator>) |
4854 | __glibcxx_function_requires(_LessThanComparableConcept< |
4855 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
4856 | __glibcxx_requires_valid_range(__first, __last); |
4857 | __glibcxx_requires_irreflexive(__first, __last); |
4858 | |
4859 | std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); |
4860 | } |
4861 | |
4862 | /** |
4863 | * @brief Sort the elements of a sequence using a predicate for comparison. |
4864 | * @ingroup sorting_algorithms |
4865 | * @param __first An iterator. |
4866 | * @param __last Another iterator. |
4867 | * @param __comp A comparison functor. |
4868 | * @return Nothing. |
4869 | * |
4870 | * Sorts the elements in the range @p [__first,__last) in ascending order, |
4871 | * such that @p __comp(*(i+1),*i) is false for every iterator @e i in the |
4872 | * range @p [__first,__last-1). |
4873 | * |
4874 | * The relative ordering of equivalent elements is not preserved, use |
4875 | * @p stable_sort() if this is needed. |
4876 | */ |
4877 | template<typename _RandomAccessIterator, typename _Compare> |
4878 | _GLIBCXX20_CONSTEXPR |
4879 | inline void |
4880 | sort(_RandomAccessIterator __first, _RandomAccessIterator __last, |
4881 | _Compare __comp) |
4882 | { |
4883 | // concept requirements |
4884 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
4885 | _RandomAccessIterator>) |
4886 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
4887 | typename iterator_traits<_RandomAccessIterator>::value_type, |
4888 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
4889 | __glibcxx_requires_valid_range(__first, __last); |
4890 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
4891 | |
4892 | std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
4893 | } |
4894 | |
4895 | template<typename _InputIterator1, typename _InputIterator2, |
4896 | typename _OutputIterator, typename _Compare> |
4897 | _GLIBCXX20_CONSTEXPR |
4898 | _OutputIterator |
4899 | __merge(_InputIterator1 __first1, _InputIterator1 __last1, |
4900 | _InputIterator2 __first2, _InputIterator2 __last2, |
4901 | _OutputIterator __result, _Compare __comp) |
4902 | { |
4903 | while (__first1 != __last1 && __first2 != __last2) |
4904 | { |
4905 | if (__comp(__first2, __first1)) |
4906 | { |
4907 | *__result = *__first2; |
4908 | ++__first2; |
4909 | } |
4910 | else |
4911 | { |
4912 | *__result = *__first1; |
4913 | ++__first1; |
4914 | } |
4915 | ++__result; |
4916 | } |
4917 | return std::copy(__first2, __last2, |
4918 | std::copy(__first1, __last1, __result)); |
4919 | } |
4920 | |
4921 | /** |
4922 | * @brief Merges two sorted ranges. |
4923 | * @ingroup sorting_algorithms |
4924 | * @param __first1 An iterator. |
4925 | * @param __first2 Another iterator. |
4926 | * @param __last1 Another iterator. |
4927 | * @param __last2 Another iterator. |
4928 | * @param __result An iterator pointing to the end of the merged range. |
4929 | * @return An output iterator equal to @p __result + (__last1 - __first1) |
4930 | * + (__last2 - __first2). |
4931 | * |
4932 | * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into |
4933 | * the sorted range @p [__result, __result + (__last1-__first1) + |
4934 | * (__last2-__first2)). Both input ranges must be sorted, and the |
4935 | * output range must not overlap with either of the input ranges. |
4936 | * The sort is @e stable, that is, for equivalent elements in the |
4937 | * two ranges, elements from the first range will always come |
4938 | * before elements from the second. |
4939 | */ |
4940 | template<typename _InputIterator1, typename _InputIterator2, |
4941 | typename _OutputIterator> |
4942 | _GLIBCXX20_CONSTEXPR |
4943 | inline _OutputIterator |
4944 | merge(_InputIterator1 __first1, _InputIterator1 __last1, |
4945 | _InputIterator2 __first2, _InputIterator2 __last2, |
4946 | _OutputIterator __result) |
4947 | { |
4948 | // concept requirements |
4949 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
4950 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
4951 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
4952 | typename iterator_traits<_InputIterator1>::value_type>) |
4953 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
4954 | typename iterator_traits<_InputIterator2>::value_type>) |
4955 | __glibcxx_function_requires(_LessThanOpConcept< |
4956 | typename iterator_traits<_InputIterator2>::value_type, |
4957 | typename iterator_traits<_InputIterator1>::value_type>) |
4958 | __glibcxx_requires_sorted_set(__first1, __last1, __first2); |
4959 | __glibcxx_requires_sorted_set(__first2, __last2, __first1); |
4960 | __glibcxx_requires_irreflexive2(__first1, __last1); |
4961 | __glibcxx_requires_irreflexive2(__first2, __last2); |
4962 | |
4963 | return _GLIBCXX_STD_Astd::__merge(__first1, __last1, |
4964 | __first2, __last2, __result, |
4965 | __gnu_cxx::__ops::__iter_less_iter()); |
4966 | } |
4967 | |
4968 | /** |
4969 | * @brief Merges two sorted ranges. |
4970 | * @ingroup sorting_algorithms |
4971 | * @param __first1 An iterator. |
4972 | * @param __first2 Another iterator. |
4973 | * @param __last1 Another iterator. |
4974 | * @param __last2 Another iterator. |
4975 | * @param __result An iterator pointing to the end of the merged range. |
4976 | * @param __comp A functor to use for comparisons. |
4977 | * @return An output iterator equal to @p __result + (__last1 - __first1) |
4978 | * + (__last2 - __first2). |
4979 | * |
4980 | * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into |
4981 | * the sorted range @p [__result, __result + (__last1-__first1) + |
4982 | * (__last2-__first2)). Both input ranges must be sorted, and the |
4983 | * output range must not overlap with either of the input ranges. |
4984 | * The sort is @e stable, that is, for equivalent elements in the |
4985 | * two ranges, elements from the first range will always come |
4986 | * before elements from the second. |
4987 | * |
4988 | * The comparison function should have the same effects on ordering as |
4989 | * the function used for the initial sort. |
4990 | */ |
4991 | template<typename _InputIterator1, typename _InputIterator2, |
4992 | typename _OutputIterator, typename _Compare> |
4993 | _GLIBCXX20_CONSTEXPR |
4994 | inline _OutputIterator |
4995 | merge(_InputIterator1 __first1, _InputIterator1 __last1, |
4996 | _InputIterator2 __first2, _InputIterator2 __last2, |
4997 | _OutputIterator __result, _Compare __comp) |
4998 | { |
4999 | // concept requirements |
5000 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5001 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5002 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5003 | typename iterator_traits<_InputIterator1>::value_type>) |
5004 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5005 | typename iterator_traits<_InputIterator2>::value_type>) |
5006 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5007 | typename iterator_traits<_InputIterator2>::value_type, |
5008 | typename iterator_traits<_InputIterator1>::value_type>) |
5009 | __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); |
5010 | __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); |
5011 | __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); |
5012 | __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); |
5013 | |
5014 | return _GLIBCXX_STD_Astd::__merge(__first1, __last1, |
5015 | __first2, __last2, __result, |
5016 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5017 | } |
5018 | |
5019 | template<typename _RandomAccessIterator, typename _Compare> |
5020 | inline void |
5021 | __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, |
5022 | _Compare __comp) |
5023 | { |
5024 | typedef typename iterator_traits<_RandomAccessIterator>::value_type |
5025 | _ValueType; |
5026 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type |
5027 | _DistanceType; |
5028 | |
5029 | typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf; |
5030 | _TmpBuf __buf(__first, std::distance(__first, __last)); |
5031 | |
5032 | if (__buf.begin() == 0) |
5033 | std::__inplace_stable_sort(__first, __last, __comp); |
5034 | else |
5035 | std::__stable_sort_adaptive(__first, __last, __buf.begin(), |
5036 | _DistanceType(__buf.size()), __comp); |
5037 | } |
5038 | |
5039 | /** |
5040 | * @brief Sort the elements of a sequence, preserving the relative order |
5041 | * of equivalent elements. |
5042 | * @ingroup sorting_algorithms |
5043 | * @param __first An iterator. |
5044 | * @param __last Another iterator. |
5045 | * @return Nothing. |
5046 | * |
5047 | * Sorts the elements in the range @p [__first,__last) in ascending order, |
5048 | * such that for each iterator @p i in the range @p [__first,__last-1), |
5049 | * @p *(i+1)<*i is false. |
5050 | * |
5051 | * The relative ordering of equivalent elements is preserved, so any two |
5052 | * elements @p x and @p y in the range @p [__first,__last) such that |
5053 | * @p x<y is false and @p y<x is false will have the same relative |
5054 | * ordering after calling @p stable_sort(). |
5055 | */ |
5056 | template<typename _RandomAccessIterator> |
5057 | inline void |
5058 | stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) |
5059 | { |
5060 | // concept requirements |
5061 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
5062 | _RandomAccessIterator>) |
5063 | __glibcxx_function_requires(_LessThanComparableConcept< |
5064 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
5065 | __glibcxx_requires_valid_range(__first, __last); |
5066 | __glibcxx_requires_irreflexive(__first, __last); |
5067 | |
5068 | _GLIBCXX_STD_Astd::__stable_sort(__first, __last, |
5069 | __gnu_cxx::__ops::__iter_less_iter()); |
5070 | } |
5071 | |
5072 | /** |
5073 | * @brief Sort the elements of a sequence using a predicate for comparison, |
5074 | * preserving the relative order of equivalent elements. |
5075 | * @ingroup sorting_algorithms |
5076 | * @param __first An iterator. |
5077 | * @param __last Another iterator. |
5078 | * @param __comp A comparison functor. |
5079 | * @return Nothing. |
5080 | * |
5081 | * Sorts the elements in the range @p [__first,__last) in ascending order, |
5082 | * such that for each iterator @p i in the range @p [__first,__last-1), |
5083 | * @p __comp(*(i+1),*i) is false. |
5084 | * |
5085 | * The relative ordering of equivalent elements is preserved, so any two |
5086 | * elements @p x and @p y in the range @p [__first,__last) such that |
5087 | * @p __comp(x,y) is false and @p __comp(y,x) is false will have the same |
5088 | * relative ordering after calling @p stable_sort(). |
5089 | */ |
5090 | template<typename _RandomAccessIterator, typename _Compare> |
5091 | inline void |
5092 | stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, |
5093 | _Compare __comp) |
5094 | { |
5095 | // concept requirements |
5096 | __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< |
5097 | _RandomAccessIterator>) |
5098 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5099 | typename iterator_traits<_RandomAccessIterator>::value_type, |
5100 | typename iterator_traits<_RandomAccessIterator>::value_type>) |
5101 | __glibcxx_requires_valid_range(__first, __last); |
5102 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
5103 | |
5104 | _GLIBCXX_STD_Astd::__stable_sort(__first, __last, |
5105 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5106 | } |
5107 | |
5108 | template<typename _InputIterator1, typename _InputIterator2, |
5109 | typename _OutputIterator, |
5110 | typename _Compare> |
5111 | _GLIBCXX20_CONSTEXPR |
5112 | _OutputIterator |
5113 | __set_union(_InputIterator1 __first1, _InputIterator1 __last1, |
5114 | _InputIterator2 __first2, _InputIterator2 __last2, |
5115 | _OutputIterator __result, _Compare __comp) |
5116 | { |
5117 | while (__first1 != __last1 && __first2 != __last2) |
5118 | { |
5119 | if (__comp(__first1, __first2)) |
5120 | { |
5121 | *__result = *__first1; |
5122 | ++__first1; |
5123 | } |
5124 | else if (__comp(__first2, __first1)) |
5125 | { |
5126 | *__result = *__first2; |
5127 | ++__first2; |
5128 | } |
5129 | else |
5130 | { |
5131 | *__result = *__first1; |
5132 | ++__first1; |
5133 | ++__first2; |
5134 | } |
5135 | ++__result; |
5136 | } |
5137 | return std::copy(__first2, __last2, |
5138 | std::copy(__first1, __last1, __result)); |
5139 | } |
5140 | |
5141 | /** |
5142 | * @brief Return the union of two sorted ranges. |
5143 | * @ingroup set_algorithms |
5144 | * @param __first1 Start of first range. |
5145 | * @param __last1 End of first range. |
5146 | * @param __first2 Start of second range. |
5147 | * @param __last2 End of second range. |
5148 | * @param __result Start of output range. |
5149 | * @return End of the output range. |
5150 | * @ingroup set_algorithms |
5151 | * |
5152 | * This operation iterates over both ranges, copying elements present in |
5153 | * each range in order to the output range. Iterators increment for each |
5154 | * range. When the current element of one range is less than the other, |
5155 | * that element is copied and the iterator advanced. If an element is |
5156 | * contained in both ranges, the element from the first range is copied and |
5157 | * both ranges advance. The output range may not overlap either input |
5158 | * range. |
5159 | */ |
5160 | template<typename _InputIterator1, typename _InputIterator2, |
5161 | typename _OutputIterator> |
5162 | _GLIBCXX20_CONSTEXPR |
5163 | inline _OutputIterator |
5164 | set_union(_InputIterator1 __first1, _InputIterator1 __last1, |
5165 | _InputIterator2 __first2, _InputIterator2 __last2, |
5166 | _OutputIterator __result) |
5167 | { |
5168 | // concept requirements |
5169 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5170 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5171 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5172 | typename iterator_traits<_InputIterator1>::value_type>) |
5173 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5174 | typename iterator_traits<_InputIterator2>::value_type>) |
5175 | __glibcxx_function_requires(_LessThanOpConcept< |
5176 | typename iterator_traits<_InputIterator1>::value_type, |
5177 | typename iterator_traits<_InputIterator2>::value_type>) |
5178 | __glibcxx_function_requires(_LessThanOpConcept< |
5179 | typename iterator_traits<_InputIterator2>::value_type, |
5180 | typename iterator_traits<_InputIterator1>::value_type>) |
5181 | __glibcxx_requires_sorted_set(__first1, __last1, __first2); |
5182 | __glibcxx_requires_sorted_set(__first2, __last2, __first1); |
5183 | __glibcxx_requires_irreflexive2(__first1, __last1); |
5184 | __glibcxx_requires_irreflexive2(__first2, __last2); |
5185 | |
5186 | return _GLIBCXX_STD_Astd::__set_union(__first1, __last1, |
5187 | __first2, __last2, __result, |
5188 | __gnu_cxx::__ops::__iter_less_iter()); |
5189 | } |
5190 | |
5191 | /** |
5192 | * @brief Return the union of two sorted ranges using a comparison functor. |
5193 | * @ingroup set_algorithms |
5194 | * @param __first1 Start of first range. |
5195 | * @param __last1 End of first range. |
5196 | * @param __first2 Start of second range. |
5197 | * @param __last2 End of second range. |
5198 | * @param __result Start of output range. |
5199 | * @param __comp The comparison functor. |
5200 | * @return End of the output range. |
5201 | * @ingroup set_algorithms |
5202 | * |
5203 | * This operation iterates over both ranges, copying elements present in |
5204 | * each range in order to the output range. Iterators increment for each |
5205 | * range. When the current element of one range is less than the other |
5206 | * according to @p __comp, that element is copied and the iterator advanced. |
5207 | * If an equivalent element according to @p __comp is contained in both |
5208 | * ranges, the element from the first range is copied and both ranges |
5209 | * advance. The output range may not overlap either input range. |
5210 | */ |
5211 | template<typename _InputIterator1, typename _InputIterator2, |
5212 | typename _OutputIterator, typename _Compare> |
5213 | _GLIBCXX20_CONSTEXPR |
5214 | inline _OutputIterator |
5215 | set_union(_InputIterator1 __first1, _InputIterator1 __last1, |
5216 | _InputIterator2 __first2, _InputIterator2 __last2, |
5217 | _OutputIterator __result, _Compare __comp) |
5218 | { |
5219 | // concept requirements |
5220 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5221 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5222 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5223 | typename iterator_traits<_InputIterator1>::value_type>) |
5224 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5225 | typename iterator_traits<_InputIterator2>::value_type>) |
5226 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5227 | typename iterator_traits<_InputIterator1>::value_type, |
5228 | typename iterator_traits<_InputIterator2>::value_type>) |
5229 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5230 | typename iterator_traits<_InputIterator2>::value_type, |
5231 | typename iterator_traits<_InputIterator1>::value_type>) |
5232 | __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); |
5233 | __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); |
5234 | __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); |
5235 | __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); |
5236 | |
5237 | return _GLIBCXX_STD_Astd::__set_union(__first1, __last1, |
5238 | __first2, __last2, __result, |
5239 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5240 | } |
5241 | |
5242 | template<typename _InputIterator1, typename _InputIterator2, |
5243 | typename _OutputIterator, |
5244 | typename _Compare> |
5245 | _GLIBCXX20_CONSTEXPR |
5246 | _OutputIterator |
5247 | __set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, |
5248 | _InputIterator2 __first2, _InputIterator2 __last2, |
5249 | _OutputIterator __result, _Compare __comp) |
5250 | { |
5251 | while (__first1 != __last1 && __first2 != __last2) |
5252 | if (__comp(__first1, __first2)) |
5253 | ++__first1; |
5254 | else if (__comp(__first2, __first1)) |
5255 | ++__first2; |
5256 | else |
5257 | { |
5258 | *__result = *__first1; |
5259 | ++__first1; |
5260 | ++__first2; |
5261 | ++__result; |
5262 | } |
5263 | return __result; |
5264 | } |
5265 | |
5266 | /** |
5267 | * @brief Return the intersection of two sorted ranges. |
5268 | * @ingroup set_algorithms |
5269 | * @param __first1 Start of first range. |
5270 | * @param __last1 End of first range. |
5271 | * @param __first2 Start of second range. |
5272 | * @param __last2 End of second range. |
5273 | * @param __result Start of output range. |
5274 | * @return End of the output range. |
5275 | * @ingroup set_algorithms |
5276 | * |
5277 | * This operation iterates over both ranges, copying elements present in |
5278 | * both ranges in order to the output range. Iterators increment for each |
5279 | * range. When the current element of one range is less than the other, |
5280 | * that iterator advances. If an element is contained in both ranges, the |
5281 | * element from the first range is copied and both ranges advance. The |
5282 | * output range may not overlap either input range. |
5283 | */ |
5284 | template<typename _InputIterator1, typename _InputIterator2, |
5285 | typename _OutputIterator> |
5286 | _GLIBCXX20_CONSTEXPR |
5287 | inline _OutputIterator |
5288 | set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, |
5289 | _InputIterator2 __first2, _InputIterator2 __last2, |
5290 | _OutputIterator __result) |
5291 | { |
5292 | // concept requirements |
5293 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5294 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5295 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5296 | typename iterator_traits<_InputIterator1>::value_type>) |
5297 | __glibcxx_function_requires(_LessThanOpConcept< |
5298 | typename iterator_traits<_InputIterator1>::value_type, |
5299 | typename iterator_traits<_InputIterator2>::value_type>) |
5300 | __glibcxx_function_requires(_LessThanOpConcept< |
5301 | typename iterator_traits<_InputIterator2>::value_type, |
5302 | typename iterator_traits<_InputIterator1>::value_type>) |
5303 | __glibcxx_requires_sorted_set(__first1, __last1, __first2); |
5304 | __glibcxx_requires_sorted_set(__first2, __last2, __first1); |
5305 | __glibcxx_requires_irreflexive2(__first1, __last1); |
5306 | __glibcxx_requires_irreflexive2(__first2, __last2); |
5307 | |
5308 | return _GLIBCXX_STD_Astd::__set_intersection(__first1, __last1, |
5309 | __first2, __last2, __result, |
5310 | __gnu_cxx::__ops::__iter_less_iter()); |
5311 | } |
5312 | |
5313 | /** |
5314 | * @brief Return the intersection of two sorted ranges using comparison |
5315 | * functor. |
5316 | * @ingroup set_algorithms |
5317 | * @param __first1 Start of first range. |
5318 | * @param __last1 End of first range. |
5319 | * @param __first2 Start of second range. |
5320 | * @param __last2 End of second range. |
5321 | * @param __result Start of output range. |
5322 | * @param __comp The comparison functor. |
5323 | * @return End of the output range. |
5324 | * @ingroup set_algorithms |
5325 | * |
5326 | * This operation iterates over both ranges, copying elements present in |
5327 | * both ranges in order to the output range. Iterators increment for each |
5328 | * range. When the current element of one range is less than the other |
5329 | * according to @p __comp, that iterator advances. If an element is |
5330 | * contained in both ranges according to @p __comp, the element from the |
5331 | * first range is copied and both ranges advance. The output range may not |
5332 | * overlap either input range. |
5333 | */ |
5334 | template<typename _InputIterator1, typename _InputIterator2, |
5335 | typename _OutputIterator, typename _Compare> |
5336 | _GLIBCXX20_CONSTEXPR |
5337 | inline _OutputIterator |
5338 | set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, |
5339 | _InputIterator2 __first2, _InputIterator2 __last2, |
5340 | _OutputIterator __result, _Compare __comp) |
5341 | { |
5342 | // concept requirements |
5343 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5344 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5345 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5346 | typename iterator_traits<_InputIterator1>::value_type>) |
5347 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5348 | typename iterator_traits<_InputIterator1>::value_type, |
5349 | typename iterator_traits<_InputIterator2>::value_type>) |
5350 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5351 | typename iterator_traits<_InputIterator2>::value_type, |
5352 | typename iterator_traits<_InputIterator1>::value_type>) |
5353 | __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); |
5354 | __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); |
5355 | __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); |
5356 | __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); |
5357 | |
5358 | return _GLIBCXX_STD_Astd::__set_intersection(__first1, __last1, |
5359 | __first2, __last2, __result, |
5360 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5361 | } |
5362 | |
5363 | template<typename _InputIterator1, typename _InputIterator2, |
5364 | typename _OutputIterator, |
5365 | typename _Compare> |
5366 | _GLIBCXX20_CONSTEXPR |
5367 | _OutputIterator |
5368 | __set_difference(_InputIterator1 __first1, _InputIterator1 __last1, |
5369 | _InputIterator2 __first2, _InputIterator2 __last2, |
5370 | _OutputIterator __result, _Compare __comp) |
5371 | { |
5372 | while (__first1 != __last1 && __first2 != __last2) |
5373 | if (__comp(__first1, __first2)) |
5374 | { |
5375 | *__result = *__first1; |
5376 | ++__first1; |
5377 | ++__result; |
5378 | } |
5379 | else if (__comp(__first2, __first1)) |
5380 | ++__first2; |
5381 | else |
5382 | { |
5383 | ++__first1; |
5384 | ++__first2; |
5385 | } |
5386 | return std::copy(__first1, __last1, __result); |
5387 | } |
5388 | |
5389 | /** |
5390 | * @brief Return the difference of two sorted ranges. |
5391 | * @ingroup set_algorithms |
5392 | * @param __first1 Start of first range. |
5393 | * @param __last1 End of first range. |
5394 | * @param __first2 Start of second range. |
5395 | * @param __last2 End of second range. |
5396 | * @param __result Start of output range. |
5397 | * @return End of the output range. |
5398 | * @ingroup set_algorithms |
5399 | * |
5400 | * This operation iterates over both ranges, copying elements present in |
5401 | * the first range but not the second in order to the output range. |
5402 | * Iterators increment for each range. When the current element of the |
5403 | * first range is less than the second, that element is copied and the |
5404 | * iterator advances. If the current element of the second range is less, |
5405 | * the iterator advances, but no element is copied. If an element is |
5406 | * contained in both ranges, no elements are copied and both ranges |
5407 | * advance. The output range may not overlap either input range. |
5408 | */ |
5409 | template<typename _InputIterator1, typename _InputIterator2, |
5410 | typename _OutputIterator> |
5411 | _GLIBCXX20_CONSTEXPR |
5412 | inline _OutputIterator |
5413 | set_difference(_InputIterator1 __first1, _InputIterator1 __last1, |
5414 | _InputIterator2 __first2, _InputIterator2 __last2, |
5415 | _OutputIterator __result) |
5416 | { |
5417 | // concept requirements |
5418 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5419 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5420 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5421 | typename iterator_traits<_InputIterator1>::value_type>) |
5422 | __glibcxx_function_requires(_LessThanOpConcept< |
5423 | typename iterator_traits<_InputIterator1>::value_type, |
5424 | typename iterator_traits<_InputIterator2>::value_type>) |
5425 | __glibcxx_function_requires(_LessThanOpConcept< |
5426 | typename iterator_traits<_InputIterator2>::value_type, |
5427 | typename iterator_traits<_InputIterator1>::value_type>) |
5428 | __glibcxx_requires_sorted_set(__first1, __last1, __first2); |
5429 | __glibcxx_requires_sorted_set(__first2, __last2, __first1); |
5430 | __glibcxx_requires_irreflexive2(__first1, __last1); |
5431 | __glibcxx_requires_irreflexive2(__first2, __last2); |
5432 | |
5433 | return _GLIBCXX_STD_Astd::__set_difference(__first1, __last1, |
5434 | __first2, __last2, __result, |
5435 | __gnu_cxx::__ops::__iter_less_iter()); |
5436 | } |
5437 | |
5438 | /** |
5439 | * @brief Return the difference of two sorted ranges using comparison |
5440 | * functor. |
5441 | * @ingroup set_algorithms |
5442 | * @param __first1 Start of first range. |
5443 | * @param __last1 End of first range. |
5444 | * @param __first2 Start of second range. |
5445 | * @param __last2 End of second range. |
5446 | * @param __result Start of output range. |
5447 | * @param __comp The comparison functor. |
5448 | * @return End of the output range. |
5449 | * @ingroup set_algorithms |
5450 | * |
5451 | * This operation iterates over both ranges, copying elements present in |
5452 | * the first range but not the second in order to the output range. |
5453 | * Iterators increment for each range. When the current element of the |
5454 | * first range is less than the second according to @p __comp, that element |
5455 | * is copied and the iterator advances. If the current element of the |
5456 | * second range is less, no element is copied and the iterator advances. |
5457 | * If an element is contained in both ranges according to @p __comp, no |
5458 | * elements are copied and both ranges advance. The output range may not |
5459 | * overlap either input range. |
5460 | */ |
5461 | template<typename _InputIterator1, typename _InputIterator2, |
5462 | typename _OutputIterator, typename _Compare> |
5463 | _GLIBCXX20_CONSTEXPR |
5464 | inline _OutputIterator |
5465 | set_difference(_InputIterator1 __first1, _InputIterator1 __last1, |
5466 | _InputIterator2 __first2, _InputIterator2 __last2, |
5467 | _OutputIterator __result, _Compare __comp) |
5468 | { |
5469 | // concept requirements |
5470 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5471 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5472 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5473 | typename iterator_traits<_InputIterator1>::value_type>) |
5474 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5475 | typename iterator_traits<_InputIterator1>::value_type, |
5476 | typename iterator_traits<_InputIterator2>::value_type>) |
5477 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5478 | typename iterator_traits<_InputIterator2>::value_type, |
5479 | typename iterator_traits<_InputIterator1>::value_type>) |
5480 | __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); |
5481 | __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); |
5482 | __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); |
5483 | __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); |
5484 | |
5485 | return _GLIBCXX_STD_Astd::__set_difference(__first1, __last1, |
5486 | __first2, __last2, __result, |
5487 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5488 | } |
5489 | |
5490 | template<typename _InputIterator1, typename _InputIterator2, |
5491 | typename _OutputIterator, |
5492 | typename _Compare> |
5493 | _GLIBCXX20_CONSTEXPR |
5494 | _OutputIterator |
5495 | __set_symmetric_difference(_InputIterator1 __first1, |
5496 | _InputIterator1 __last1, |
5497 | _InputIterator2 __first2, |
5498 | _InputIterator2 __last2, |
5499 | _OutputIterator __result, |
5500 | _Compare __comp) |
5501 | { |
5502 | while (__first1 != __last1 && __first2 != __last2) |
5503 | if (__comp(__first1, __first2)) |
5504 | { |
5505 | *__result = *__first1; |
5506 | ++__first1; |
5507 | ++__result; |
5508 | } |
5509 | else if (__comp(__first2, __first1)) |
5510 | { |
5511 | *__result = *__first2; |
5512 | ++__first2; |
5513 | ++__result; |
5514 | } |
5515 | else |
5516 | { |
5517 | ++__first1; |
5518 | ++__first2; |
5519 | } |
5520 | return std::copy(__first2, __last2, |
5521 | std::copy(__first1, __last1, __result)); |
5522 | } |
5523 | |
5524 | /** |
5525 | * @brief Return the symmetric difference of two sorted ranges. |
5526 | * @ingroup set_algorithms |
5527 | * @param __first1 Start of first range. |
5528 | * @param __last1 End of first range. |
5529 | * @param __first2 Start of second range. |
5530 | * @param __last2 End of second range. |
5531 | * @param __result Start of output range. |
5532 | * @return End of the output range. |
5533 | * @ingroup set_algorithms |
5534 | * |
5535 | * This operation iterates over both ranges, copying elements present in |
5536 | * one range but not the other in order to the output range. Iterators |
5537 | * increment for each range. When the current element of one range is less |
5538 | * than the other, that element is copied and the iterator advances. If an |
5539 | * element is contained in both ranges, no elements are copied and both |
5540 | * ranges advance. The output range may not overlap either input range. |
5541 | */ |
5542 | template<typename _InputIterator1, typename _InputIterator2, |
5543 | typename _OutputIterator> |
5544 | _GLIBCXX20_CONSTEXPR |
5545 | inline _OutputIterator |
5546 | set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, |
5547 | _InputIterator2 __first2, _InputIterator2 __last2, |
5548 | _OutputIterator __result) |
5549 | { |
5550 | // concept requirements |
5551 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5552 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5553 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5554 | typename iterator_traits<_InputIterator1>::value_type>) |
5555 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5556 | typename iterator_traits<_InputIterator2>::value_type>) |
5557 | __glibcxx_function_requires(_LessThanOpConcept< |
5558 | typename iterator_traits<_InputIterator1>::value_type, |
5559 | typename iterator_traits<_InputIterator2>::value_type>) |
5560 | __glibcxx_function_requires(_LessThanOpConcept< |
5561 | typename iterator_traits<_InputIterator2>::value_type, |
5562 | typename iterator_traits<_InputIterator1>::value_type>) |
5563 | __glibcxx_requires_sorted_set(__first1, __last1, __first2); |
5564 | __glibcxx_requires_sorted_set(__first2, __last2, __first1); |
5565 | __glibcxx_requires_irreflexive2(__first1, __last1); |
5566 | __glibcxx_requires_irreflexive2(__first2, __last2); |
5567 | |
5568 | return _GLIBCXX_STD_Astd::__set_symmetric_difference(__first1, __last1, |
5569 | __first2, __last2, __result, |
5570 | __gnu_cxx::__ops::__iter_less_iter()); |
5571 | } |
5572 | |
5573 | /** |
5574 | * @brief Return the symmetric difference of two sorted ranges using |
5575 | * comparison functor. |
5576 | * @ingroup set_algorithms |
5577 | * @param __first1 Start of first range. |
5578 | * @param __last1 End of first range. |
5579 | * @param __first2 Start of second range. |
5580 | * @param __last2 End of second range. |
5581 | * @param __result Start of output range. |
5582 | * @param __comp The comparison functor. |
5583 | * @return End of the output range. |
5584 | * @ingroup set_algorithms |
5585 | * |
5586 | * This operation iterates over both ranges, copying elements present in |
5587 | * one range but not the other in order to the output range. Iterators |
5588 | * increment for each range. When the current element of one range is less |
5589 | * than the other according to @p comp, that element is copied and the |
5590 | * iterator advances. If an element is contained in both ranges according |
5591 | * to @p __comp, no elements are copied and both ranges advance. The output |
5592 | * range may not overlap either input range. |
5593 | */ |
5594 | template<typename _InputIterator1, typename _InputIterator2, |
5595 | typename _OutputIterator, typename _Compare> |
5596 | _GLIBCXX20_CONSTEXPR |
5597 | inline _OutputIterator |
5598 | set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, |
5599 | _InputIterator2 __first2, _InputIterator2 __last2, |
5600 | _OutputIterator __result, |
5601 | _Compare __comp) |
5602 | { |
5603 | // concept requirements |
5604 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) |
5605 | __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) |
5606 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5607 | typename iterator_traits<_InputIterator1>::value_type>) |
5608 | __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, |
5609 | typename iterator_traits<_InputIterator2>::value_type>) |
5610 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5611 | typename iterator_traits<_InputIterator1>::value_type, |
5612 | typename iterator_traits<_InputIterator2>::value_type>) |
5613 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5614 | typename iterator_traits<_InputIterator2>::value_type, |
5615 | typename iterator_traits<_InputIterator1>::value_type>) |
5616 | __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); |
5617 | __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); |
5618 | __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); |
5619 | __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); |
5620 | |
5621 | return _GLIBCXX_STD_Astd::__set_symmetric_difference(__first1, __last1, |
5622 | __first2, __last2, __result, |
5623 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5624 | } |
5625 | |
5626 | template<typename _ForwardIterator, typename _Compare> |
5627 | _GLIBCXX14_CONSTEXPRconstexpr |
5628 | _ForwardIterator |
5629 | __min_element(_ForwardIterator __first, _ForwardIterator __last, |
5630 | _Compare __comp) |
5631 | { |
5632 | if (__first == __last) |
5633 | return __first; |
5634 | _ForwardIterator __result = __first; |
5635 | while (++__first != __last) |
5636 | if (__comp(__first, __result)) |
5637 | __result = __first; |
5638 | return __result; |
5639 | } |
5640 | |
5641 | /** |
5642 | * @brief Return the minimum element in a range. |
5643 | * @ingroup sorting_algorithms |
5644 | * @param __first Start of range. |
5645 | * @param __last End of range. |
5646 | * @return Iterator referencing the first instance of the smallest value. |
5647 | */ |
5648 | template<typename _ForwardIterator> |
5649 | _GLIBCXX14_CONSTEXPRconstexpr |
5650 | _ForwardIterator |
5651 | inline min_element(_ForwardIterator __first, _ForwardIterator __last) |
5652 | { |
5653 | // concept requirements |
5654 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
5655 | __glibcxx_function_requires(_LessThanComparableConcept< |
5656 | typename iterator_traits<_ForwardIterator>::value_type>) |
5657 | __glibcxx_requires_valid_range(__first, __last); |
5658 | __glibcxx_requires_irreflexive(__first, __last); |
5659 | |
5660 | return _GLIBCXX_STD_Astd::__min_element(__first, __last, |
5661 | __gnu_cxx::__ops::__iter_less_iter()); |
5662 | } |
5663 | |
5664 | /** |
5665 | * @brief Return the minimum element in a range using comparison functor. |
5666 | * @ingroup sorting_algorithms |
5667 | * @param __first Start of range. |
5668 | * @param __last End of range. |
5669 | * @param __comp Comparison functor. |
5670 | * @return Iterator referencing the first instance of the smallest value |
5671 | * according to __comp. |
5672 | */ |
5673 | template<typename _ForwardIterator, typename _Compare> |
5674 | _GLIBCXX14_CONSTEXPRconstexpr |
5675 | inline _ForwardIterator |
5676 | min_element(_ForwardIterator __first, _ForwardIterator __last, |
5677 | _Compare __comp) |
5678 | { |
5679 | // concept requirements |
5680 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
5681 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5682 | typename iterator_traits<_ForwardIterator>::value_type, |
5683 | typename iterator_traits<_ForwardIterator>::value_type>) |
5684 | __glibcxx_requires_valid_range(__first, __last); |
5685 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
5686 | |
5687 | return _GLIBCXX_STD_Astd::__min_element(__first, __last, |
5688 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5689 | } |
5690 | |
5691 | template<typename _ForwardIterator, typename _Compare> |
5692 | _GLIBCXX14_CONSTEXPRconstexpr |
5693 | _ForwardIterator |
5694 | __max_element(_ForwardIterator __first, _ForwardIterator __last, |
5695 | _Compare __comp) |
5696 | { |
5697 | if (__first == __last) return __first; |
5698 | _ForwardIterator __result = __first; |
5699 | while (++__first != __last) |
5700 | if (__comp(__result, __first)) |
5701 | __result = __first; |
5702 | return __result; |
5703 | } |
5704 | |
5705 | /** |
5706 | * @brief Return the maximum element in a range. |
5707 | * @ingroup sorting_algorithms |
5708 | * @param __first Start of range. |
5709 | * @param __last End of range. |
5710 | * @return Iterator referencing the first instance of the largest value. |
5711 | */ |
5712 | template<typename _ForwardIterator> |
5713 | _GLIBCXX14_CONSTEXPRconstexpr |
5714 | inline _ForwardIterator |
5715 | max_element(_ForwardIterator __first, _ForwardIterator __last) |
5716 | { |
5717 | // concept requirements |
5718 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
5719 | __glibcxx_function_requires(_LessThanComparableConcept< |
5720 | typename iterator_traits<_ForwardIterator>::value_type>) |
5721 | __glibcxx_requires_valid_range(__first, __last); |
5722 | __glibcxx_requires_irreflexive(__first, __last); |
5723 | |
5724 | return _GLIBCXX_STD_Astd::__max_element(__first, __last, |
5725 | __gnu_cxx::__ops::__iter_less_iter()); |
5726 | } |
5727 | |
5728 | /** |
5729 | * @brief Return the maximum element in a range using comparison functor. |
5730 | * @ingroup sorting_algorithms |
5731 | * @param __first Start of range. |
5732 | * @param __last End of range. |
5733 | * @param __comp Comparison functor. |
5734 | * @return Iterator referencing the first instance of the largest value |
5735 | * according to __comp. |
5736 | */ |
5737 | template<typename _ForwardIterator, typename _Compare> |
5738 | _GLIBCXX14_CONSTEXPRconstexpr |
5739 | inline _ForwardIterator |
5740 | max_element(_ForwardIterator __first, _ForwardIterator __last, |
5741 | _Compare __comp) |
5742 | { |
5743 | // concept requirements |
5744 | __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) |
5745 | __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, |
5746 | typename iterator_traits<_ForwardIterator>::value_type, |
5747 | typename iterator_traits<_ForwardIterator>::value_type>) |
5748 | __glibcxx_requires_valid_range(__first, __last); |
5749 | __glibcxx_requires_irreflexive_pred(__first, __last, __comp); |
5750 | |
5751 | return _GLIBCXX_STD_Astd::__max_element(__first, __last, |
5752 | __gnu_cxx::__ops::__iter_comp_iter(__comp)); |
5753 | } |
5754 | |
5755 | #if __cplusplus201703L >= 201402L |
5756 | /// Reservoir sampling algorithm. |
5757 | template<typename _InputIterator, typename _RandomAccessIterator, |
5758 | typename _Size, typename _UniformRandomBitGenerator> |
5759 | _RandomAccessIterator |
5760 | __sample(_InputIterator __first, _InputIterator __last, input_iterator_tag, |
5761 | _RandomAccessIterator __out, random_access_iterator_tag, |
5762 | _Size __n, _UniformRandomBitGenerator&& __g) |
5763 | { |
5764 | using __distrib_type = uniform_int_distribution<_Size>; |
5765 | using __param_type = typename __distrib_type::param_type; |
5766 | __distrib_type __d{}; |
5767 | _Size __sample_sz = 0; |
5768 | while (__first != __last && __sample_sz != __n) |
5769 | { |
5770 | __out[__sample_sz++] = *__first; |
5771 | ++__first; |
5772 | } |
5773 | for (auto __pop_sz = __sample_sz; __first != __last; |
5774 | ++__first, (void) ++__pop_sz) |
5775 | { |
5776 | const auto __k = __d(__g, __param_type{0, __pop_sz}); |
5777 | if (__k < __n) |
5778 | __out[__k] = *__first; |
5779 | } |
5780 | return __out + __sample_sz; |
5781 | } |
5782 | |
5783 | /// Selection sampling algorithm. |
5784 | template<typename _ForwardIterator, typename _OutputIterator, typename _Cat, |
5785 | typename _Size, typename _UniformRandomBitGenerator> |
5786 | _OutputIterator |
5787 | __sample(_ForwardIterator __first, _ForwardIterator __last, |
5788 | forward_iterator_tag, |
5789 | _OutputIterator __out, _Cat, |
5790 | _Size __n, _UniformRandomBitGenerator&& __g) |
5791 | { |
5792 | using __distrib_type = uniform_int_distribution<_Size>; |
5793 | using __param_type = typename __distrib_type::param_type; |
5794 | using _USize = make_unsigned_t<_Size>; |
5795 | using _Gen = remove_reference_t<_UniformRandomBitGenerator>; |
5796 | using __uc_type = common_type_t<typename _Gen::result_type, _USize>; |
5797 | |
5798 | __distrib_type __d{}; |
5799 | _Size __unsampled_sz = std::distance(__first, __last); |
5800 | __n = std::min(__n, __unsampled_sz); |
5801 | |
5802 | // If possible, we use __gen_two_uniform_ints to efficiently produce |
5803 | // two random numbers using a single distribution invocation: |
5804 | |
5805 | const __uc_type __urngrange = __g.max() - __g.min(); |
5806 | if (__urngrange / __uc_type(__unsampled_sz) >= __uc_type(__unsampled_sz)) |
5807 | // I.e. (__urngrange >= __unsampled_sz * __unsampled_sz) but without |
5808 | // wrapping issues. |
5809 | { |
5810 | while (__n != 0 && __unsampled_sz >= 2) |
5811 | { |
5812 | const pair<_Size, _Size> __p = |
5813 | __gen_two_uniform_ints(__unsampled_sz, __unsampled_sz - 1, __g); |
5814 | |
5815 | --__unsampled_sz; |
5816 | if (__p.first < __n) |
5817 | { |
5818 | *__out++ = *__first; |
5819 | --__n; |
5820 | } |
5821 | |
5822 | ++__first; |
5823 | |
5824 | if (__n == 0) break; |
5825 | |
5826 | --__unsampled_sz; |
5827 | if (__p.second < __n) |
5828 | { |
5829 | *__out++ = *__first; |
5830 | --__n; |
5831 | } |
5832 | |
5833 | ++__first; |
5834 | } |
5835 | } |
5836 | |
5837 | // The loop above is otherwise equivalent to this one-at-a-time version: |
5838 | |
5839 | for (; __n != 0; ++__first) |
5840 | if (__d(__g, __param_type{0, --__unsampled_sz}) < __n) |
5841 | { |
5842 | *__out++ = *__first; |
5843 | --__n; |
5844 | } |
5845 | return __out; |
5846 | } |
5847 | |
5848 | #if __cplusplus201703L > 201402L |
5849 | #define __cpp_lib_sample201603 201603 |
5850 | /// Take a random sample from a population. |
5851 | template<typename _PopulationIterator, typename _SampleIterator, |
5852 | typename _Distance, typename _UniformRandomBitGenerator> |
5853 | _SampleIterator |
5854 | sample(_PopulationIterator __first, _PopulationIterator __last, |
5855 | _SampleIterator __out, _Distance __n, |
5856 | _UniformRandomBitGenerator&& __g) |
5857 | { |
5858 | using __pop_cat = typename |
5859 | std::iterator_traits<_PopulationIterator>::iterator_category; |
5860 | using __samp_cat = typename |
5861 | std::iterator_traits<_SampleIterator>::iterator_category; |
5862 | |
5863 | static_assert( |
5864 | __or_<is_convertible<__pop_cat, forward_iterator_tag>, |
5865 | is_convertible<__samp_cat, random_access_iterator_tag>>::value, |
5866 | "output range must use a RandomAccessIterator when input range" |
5867 | " does not meet the ForwardIterator requirements"); |
5868 | |
5869 | static_assert(is_integral<_Distance>::value, |
5870 | "sample size must be an integer type"); |
5871 | |
5872 | typename iterator_traits<_PopulationIterator>::difference_type __d = __n; |
5873 | return _GLIBCXX_STD_Astd:: |
5874 | __sample(__first, __last, __pop_cat{}, __out, __samp_cat{}, __d, |
5875 | std::forward<_UniformRandomBitGenerator>(__g)); |
5876 | } |
5877 | #endif // C++17 |
5878 | #endif // C++14 |
5879 | |
5880 | _GLIBCXX_END_NAMESPACE_ALGO |
5881 | _GLIBCXX_END_NAMESPACE_VERSION |
5882 | } // namespace std |
5883 | |
5884 | #endif /* _STL_ALGO_H */ |
1 | // Iterators -*- C++ -*- |
2 | |
3 | // Copyright (C) 2001-2020 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /* |
26 | * |
27 | * Copyright (c) 1994 |
28 | * Hewlett-Packard Company |
29 | * |
30 | * Permission to use, copy, modify, distribute and sell this software |
31 | * and its documentation for any purpose is hereby granted without fee, |
32 | * provided that the above copyright notice appear in all copies and |
33 | * that both that copyright notice and this permission notice appear |
34 | * in supporting documentation. Hewlett-Packard Company makes no |
35 | * representations about the suitability of this software for any |
36 | * purpose. It is provided "as is" without express or implied warranty. |
37 | * |
38 | * |
39 | * Copyright (c) 1996-1998 |
40 | * Silicon Graphics Computer Systems, Inc. |
41 | * |
42 | * Permission to use, copy, modify, distribute and sell this software |
43 | * and its documentation for any purpose is hereby granted without fee, |
44 | * provided that the above copyright notice appear in all copies and |
45 | * that both that copyright notice and this permission notice appear |
46 | * in supporting documentation. Silicon Graphics makes no |
47 | * representations about the suitability of this software for any |
48 | * purpose. It is provided "as is" without express or implied warranty. |
49 | */ |
50 | |
51 | /** @file bits/stl_iterator.h |
52 | * This is an internal header file, included by other library headers. |
53 | * Do not attempt to use it directly. @headername{iterator} |
54 | * |
55 | * This file implements reverse_iterator, back_insert_iterator, |
56 | * front_insert_iterator, insert_iterator, __normal_iterator, and their |
57 | * supporting functions and overloaded operators. |
58 | */ |
59 | |
60 | #ifndef _STL_ITERATOR_H1 |
61 | #define _STL_ITERATOR_H1 1 |
62 | |
63 | #include <bits/cpp_type_traits.h> |
64 | #include <ext/type_traits.h> |
65 | #include <bits/move.h> |
66 | #include <bits/ptr_traits.h> |
67 | |
68 | #if __cplusplus201703L >= 201103L |
69 | # include <type_traits> |
70 | #endif |
71 | |
72 | #if __cplusplus201703L > 201703L |
73 | # define __cpp_lib_array_constexpr201803L 201811L |
74 | # define __cpp_lib_constexpr_iterator 201811L |
75 | #elif __cplusplus201703L == 201703L |
76 | # define __cpp_lib_array_constexpr201803L 201803L |
77 | #endif |
78 | |
79 | #if __cplusplus201703L > 201703L |
80 | # include <compare> |
81 | # include <new> |
82 | # include <bits/iterator_concepts.h> |
83 | #endif |
84 | |
85 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
86 | { |
87 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
88 | |
89 | /** |
90 | * @addtogroup iterators |
91 | * @{ |
92 | */ |
93 | |
94 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
95 | namespace __detail |
96 | { |
97 | // Weaken iterator_category _Cat to _Limit if it is derived from that, |
98 | // otherwise use _Otherwise. |
99 | template<typename _Cat, typename _Limit, typename _Otherwise = _Cat> |
100 | using __clamp_iter_cat |
101 | = conditional_t<derived_from<_Cat, _Limit>, _Limit, _Otherwise>; |
102 | } |
103 | #endif |
104 | |
105 | // 24.4.1 Reverse iterators |
106 | /** |
107 | * Bidirectional and random access iterators have corresponding reverse |
108 | * %iterator adaptors that iterate through the data structure in the |
109 | * opposite direction. They have the same signatures as the corresponding |
110 | * iterators. The fundamental relation between a reverse %iterator and its |
111 | * corresponding %iterator @c i is established by the identity: |
112 | * @code |
113 | * &*(reverse_iterator(i)) == &*(i - 1) |
114 | * @endcode |
115 | * |
116 | * <em>This mapping is dictated by the fact that while there is always a |
117 | * pointer past the end of an array, there might not be a valid pointer |
118 | * before the beginning of an array.</em> [24.4.1]/1,2 |
119 | * |
120 | * Reverse iterators can be tricky and surprising at first. Their |
121 | * semantics make sense, however, and the trickiness is a side effect of |
122 | * the requirement that the iterators must be safe. |
123 | */ |
124 | template<typename _Iterator> |
125 | class reverse_iterator |
126 | : public iterator<typename iterator_traits<_Iterator>::iterator_category, |
127 | typename iterator_traits<_Iterator>::value_type, |
128 | typename iterator_traits<_Iterator>::difference_type, |
129 | typename iterator_traits<_Iterator>::pointer, |
130 | typename iterator_traits<_Iterator>::reference> |
131 | { |
132 | protected: |
133 | _Iterator current; |
134 | |
135 | typedef iterator_traits<_Iterator> __traits_type; |
136 | |
137 | public: |
138 | typedef _Iterator iterator_type; |
139 | typedef typename __traits_type::difference_type difference_type; |
140 | typedef typename __traits_type::pointer pointer; |
141 | typedef typename __traits_type::reference reference; |
142 | |
143 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
144 | using iterator_concept |
145 | = conditional_t<random_access_iterator<_Iterator>, |
146 | random_access_iterator_tag, |
147 | bidirectional_iterator_tag>; |
148 | using iterator_category |
149 | = __detail::__clamp_iter_cat<typename __traits_type::iterator_category, |
150 | random_access_iterator_tag>; |
151 | #endif |
152 | |
153 | /** |
154 | * The default constructor value-initializes member @p current. |
155 | * If it is a pointer, that means it is zero-initialized. |
156 | */ |
157 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
158 | // 235 No specification of default ctor for reverse_iterator |
159 | // 1012. reverse_iterator default ctor should value initialize |
160 | _GLIBCXX17_CONSTEXPRconstexpr |
161 | reverse_iterator() : current() { } |
162 | |
163 | /** |
164 | * This %iterator will move in the opposite direction that @p x does. |
165 | */ |
166 | explicit _GLIBCXX17_CONSTEXPRconstexpr |
167 | reverse_iterator(iterator_type __x) : current(__x) { } |
168 | |
169 | /** |
170 | * The copy constructor is normal. |
171 | */ |
172 | _GLIBCXX17_CONSTEXPRconstexpr |
173 | reverse_iterator(const reverse_iterator& __x) |
174 | : current(__x.current) { } |
175 | |
176 | #if __cplusplus201703L >= 201103L |
177 | reverse_iterator& operator=(const reverse_iterator&) = default; |
178 | #endif |
179 | |
180 | /** |
181 | * A %reverse_iterator across other types can be copied if the |
182 | * underlying %iterator can be converted to the type of @c current. |
183 | */ |
184 | template<typename _Iter> |
185 | _GLIBCXX17_CONSTEXPRconstexpr |
186 | reverse_iterator(const reverse_iterator<_Iter>& __x) |
187 | : current(__x.base()) { } |
188 | |
189 | /** |
190 | * @return @c current, the %iterator used for underlying work. |
191 | */ |
192 | _GLIBCXX17_CONSTEXPRconstexpr iterator_type |
193 | base() const |
194 | { return current; } |
195 | |
196 | /** |
197 | * @return A reference to the value at @c --current |
198 | * |
199 | * This requires that @c --current is dereferenceable. |
200 | * |
201 | * @warning This implementation requires that for an iterator of the |
202 | * underlying iterator type, @c x, a reference obtained by |
203 | * @c *x remains valid after @c x has been modified or |
204 | * destroyed. This is a bug: http://gcc.gnu.org/PR51823 |
205 | */ |
206 | _GLIBCXX17_CONSTEXPRconstexpr reference |
207 | operator*() const |
208 | { |
209 | _Iterator __tmp = current; |
210 | return *--__tmp; |
211 | } |
212 | |
213 | /** |
214 | * @return A pointer to the value at @c --current |
215 | * |
216 | * This requires that @c --current is dereferenceable. |
217 | */ |
218 | _GLIBCXX17_CONSTEXPRconstexpr pointer |
219 | operator->() const |
220 | #if __cplusplus201703L > 201703L && __cpp_concepts >= 201907L |
221 | requires is_pointer_v<_Iterator> |
222 | || requires(const _Iterator __i) { __i.operator->(); } |
223 | #endif |
224 | { |
225 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
226 | // 1052. operator-> should also support smart pointers |
227 | _Iterator __tmp = current; |
228 | --__tmp; |
229 | return _S_to_pointer(__tmp); |
230 | } |
231 | |
232 | /** |
233 | * @return @c *this |
234 | * |
235 | * Decrements the underlying iterator. |
236 | */ |
237 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator& |
238 | operator++() |
239 | { |
240 | --current; |
241 | return *this; |
242 | } |
243 | |
244 | /** |
245 | * @return The original value of @c *this |
246 | * |
247 | * Decrements the underlying iterator. |
248 | */ |
249 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator |
250 | operator++(int) |
251 | { |
252 | reverse_iterator __tmp = *this; |
253 | --current; |
254 | return __tmp; |
255 | } |
256 | |
257 | /** |
258 | * @return @c *this |
259 | * |
260 | * Increments the underlying iterator. |
261 | */ |
262 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator& |
263 | operator--() |
264 | { |
265 | ++current; |
266 | return *this; |
267 | } |
268 | |
269 | /** |
270 | * @return A reverse_iterator with the previous value of @c *this |
271 | * |
272 | * Increments the underlying iterator. |
273 | */ |
274 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator |
275 | operator--(int) |
276 | { |
277 | reverse_iterator __tmp = *this; |
278 | ++current; |
279 | return __tmp; |
280 | } |
281 | |
282 | /** |
283 | * @return A reverse_iterator that refers to @c current - @a __n |
284 | * |
285 | * The underlying iterator must be a Random Access Iterator. |
286 | */ |
287 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator |
288 | operator+(difference_type __n) const |
289 | { return reverse_iterator(current - __n); } |
290 | |
291 | /** |
292 | * @return *this |
293 | * |
294 | * Moves the underlying iterator backwards @a __n steps. |
295 | * The underlying iterator must be a Random Access Iterator. |
296 | */ |
297 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator& |
298 | operator+=(difference_type __n) |
299 | { |
300 | current -= __n; |
301 | return *this; |
302 | } |
303 | |
304 | /** |
305 | * @return A reverse_iterator that refers to @c current - @a __n |
306 | * |
307 | * The underlying iterator must be a Random Access Iterator. |
308 | */ |
309 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator |
310 | operator-(difference_type __n) const |
311 | { return reverse_iterator(current + __n); } |
312 | |
313 | /** |
314 | * @return *this |
315 | * |
316 | * Moves the underlying iterator forwards @a __n steps. |
317 | * The underlying iterator must be a Random Access Iterator. |
318 | */ |
319 | _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator& |
320 | operator-=(difference_type __n) |
321 | { |
322 | current += __n; |
323 | return *this; |
324 | } |
325 | |
326 | /** |
327 | * @return The value at @c current - @a __n - 1 |
328 | * |
329 | * The underlying iterator must be a Random Access Iterator. |
330 | */ |
331 | _GLIBCXX17_CONSTEXPRconstexpr reference |
332 | operator[](difference_type __n) const |
333 | { return *(*this + __n); } |
334 | |
335 | private: |
336 | template<typename _Tp> |
337 | static _GLIBCXX17_CONSTEXPRconstexpr _Tp* |
338 | _S_to_pointer(_Tp* __p) |
339 | { return __p; } |
340 | |
341 | template<typename _Tp> |
342 | static _GLIBCXX17_CONSTEXPRconstexpr pointer |
343 | _S_to_pointer(_Tp __t) |
344 | { return __t.operator->(); } |
345 | }; |
346 | |
347 | //@{ |
348 | /** |
349 | * @param __x A %reverse_iterator. |
350 | * @param __y A %reverse_iterator. |
351 | * @return A simple bool. |
352 | * |
353 | * Reverse iterators forward comparisons to their underlying base() |
354 | * iterators. |
355 | * |
356 | */ |
357 | #if __cplusplus201703L <= 201703L || ! defined __cpp_lib_concepts |
358 | template<typename _Iterator> |
359 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
360 | operator==(const reverse_iterator<_Iterator>& __x, |
361 | const reverse_iterator<_Iterator>& __y) |
362 | { return __x.base() == __y.base(); } |
363 | |
364 | template<typename _Iterator> |
365 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
366 | operator<(const reverse_iterator<_Iterator>& __x, |
367 | const reverse_iterator<_Iterator>& __y) |
368 | { return __y.base() < __x.base(); } |
369 | |
370 | template<typename _Iterator> |
371 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
372 | operator!=(const reverse_iterator<_Iterator>& __x, |
373 | const reverse_iterator<_Iterator>& __y) |
374 | { return !(__x == __y); } |
375 | |
376 | template<typename _Iterator> |
377 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
378 | operator>(const reverse_iterator<_Iterator>& __x, |
379 | const reverse_iterator<_Iterator>& __y) |
380 | { return __y < __x; } |
381 | |
382 | template<typename _Iterator> |
383 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
384 | operator<=(const reverse_iterator<_Iterator>& __x, |
385 | const reverse_iterator<_Iterator>& __y) |
386 | { return !(__y < __x); } |
387 | |
388 | template<typename _Iterator> |
389 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
390 | operator>=(const reverse_iterator<_Iterator>& __x, |
391 | const reverse_iterator<_Iterator>& __y) |
392 | { return !(__x < __y); } |
393 | |
394 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
395 | // DR 280. Comparison of reverse_iterator to const reverse_iterator. |
396 | template<typename _IteratorL, typename _IteratorR> |
397 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
398 | operator==(const reverse_iterator<_IteratorL>& __x, |
399 | const reverse_iterator<_IteratorR>& __y) |
400 | { return __x.base() == __y.base(); } |
401 | |
402 | template<typename _IteratorL, typename _IteratorR> |
403 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
404 | operator<(const reverse_iterator<_IteratorL>& __x, |
405 | const reverse_iterator<_IteratorR>& __y) |
406 | { return __y.base() < __x.base(); } |
407 | |
408 | template<typename _IteratorL, typename _IteratorR> |
409 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
410 | operator!=(const reverse_iterator<_IteratorL>& __x, |
411 | const reverse_iterator<_IteratorR>& __y) |
412 | { return !(__x == __y); } |
413 | |
414 | template<typename _IteratorL, typename _IteratorR> |
415 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
416 | operator>(const reverse_iterator<_IteratorL>& __x, |
417 | const reverse_iterator<_IteratorR>& __y) |
418 | { return __y < __x; } |
419 | |
420 | template<typename _IteratorL, typename _IteratorR> |
421 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
422 | operator<=(const reverse_iterator<_IteratorL>& __x, |
423 | const reverse_iterator<_IteratorR>& __y) |
424 | { return !(__y < __x); } |
425 | |
426 | template<typename _IteratorL, typename _IteratorR> |
427 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
428 | operator>=(const reverse_iterator<_IteratorL>& __x, |
429 | const reverse_iterator<_IteratorR>& __y) |
430 | { return !(__x < __y); } |
431 | #else // C++20 |
432 | template<typename _IteratorL, typename _IteratorR> |
433 | constexpr bool |
434 | operator==(const reverse_iterator<_IteratorL>& __x, |
435 | const reverse_iterator<_IteratorR>& __y) |
436 | requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; } |
437 | { return __x.base() == __y.base(); } |
438 | |
439 | template<typename _IteratorL, typename _IteratorR> |
440 | constexpr bool |
441 | operator!=(const reverse_iterator<_IteratorL>& __x, |
442 | const reverse_iterator<_IteratorR>& __y) |
443 | requires requires { { __x.base() != __y.base() } -> convertible_to<bool>; } |
444 | { return __x.base() != __y.base(); } |
445 | |
446 | template<typename _IteratorL, typename _IteratorR> |
447 | constexpr bool |
448 | operator<(const reverse_iterator<_IteratorL>& __x, |
449 | const reverse_iterator<_IteratorR>& __y) |
450 | requires requires { { __x.base() > __y.base() } -> convertible_to<bool>; } |
451 | { return __x.base() > __y.base(); } |
452 | |
453 | template<typename _IteratorL, typename _IteratorR> |
454 | constexpr bool |
455 | operator>(const reverse_iterator<_IteratorL>& __x, |
456 | const reverse_iterator<_IteratorR>& __y) |
457 | requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; } |
458 | { return __x.base() < __y.base(); } |
459 | |
460 | template<typename _IteratorL, typename _IteratorR> |
461 | constexpr bool |
462 | operator<=(const reverse_iterator<_IteratorL>& __x, |
463 | const reverse_iterator<_IteratorR>& __y) |
464 | requires requires { { __x.base() >= __y.base() } -> convertible_to<bool>; } |
465 | { return __x.base() >= __y.base(); } |
466 | |
467 | template<typename _IteratorL, typename _IteratorR> |
468 | constexpr bool |
469 | operator>=(const reverse_iterator<_IteratorL>& __x, |
470 | const reverse_iterator<_IteratorR>& __y) |
471 | requires requires { { __x.base() <= __y.base() } -> convertible_to<bool>; } |
472 | { return __x.base() <= __y.base(); } |
473 | |
474 | template<typename _IteratorL, |
475 | three_way_comparable_with<_IteratorL> _IteratorR> |
476 | constexpr compare_three_way_result_t<_IteratorL, _IteratorR> |
477 | operator<=>(const reverse_iterator<_IteratorL>& __x, |
478 | const reverse_iterator<_IteratorR>& __y) |
479 | { return __y.base() <=> __x.base(); } |
480 | #endif // C++20 |
481 | //@} |
482 | |
483 | #if __cplusplus201703L < 201103L |
484 | template<typename _Iterator> |
485 | inline typename reverse_iterator<_Iterator>::difference_type |
486 | operator-(const reverse_iterator<_Iterator>& __x, |
487 | const reverse_iterator<_Iterator>& __y) |
488 | { return __y.base() - __x.base(); } |
489 | |
490 | template<typename _IteratorL, typename _IteratorR> |
491 | inline typename reverse_iterator<_IteratorL>::difference_type |
492 | operator-(const reverse_iterator<_IteratorL>& __x, |
493 | const reverse_iterator<_IteratorR>& __y) |
494 | { return __y.base() - __x.base(); } |
495 | #else |
496 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
497 | // DR 685. reverse_iterator/move_iterator difference has invalid signatures |
498 | template<typename _IteratorL, typename _IteratorR> |
499 | inline _GLIBCXX17_CONSTEXPRconstexpr auto |
500 | operator-(const reverse_iterator<_IteratorL>& __x, |
501 | const reverse_iterator<_IteratorR>& __y) |
502 | -> decltype(__y.base() - __x.base()) |
503 | { return __y.base() - __x.base(); } |
504 | #endif |
505 | |
506 | template<typename _Iterator> |
507 | inline _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator<_Iterator> |
508 | operator+(typename reverse_iterator<_Iterator>::difference_type __n, |
509 | const reverse_iterator<_Iterator>& __x) |
510 | { return reverse_iterator<_Iterator>(__x.base() - __n); } |
511 | |
512 | #if __cplusplus201703L >= 201103L |
513 | // Same as C++14 make_reverse_iterator but used in C++11 mode too. |
514 | template<typename _Iterator> |
515 | inline _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator<_Iterator> |
516 | __make_reverse_iterator(_Iterator __i) |
517 | { return reverse_iterator<_Iterator>(__i); } |
518 | |
519 | # if __cplusplus201703L >= 201402L |
520 | # define __cpp_lib_make_reverse_iterator201402 201402 |
521 | |
522 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
523 | // DR 2285. make_reverse_iterator |
524 | /// Generator function for reverse_iterator. |
525 | template<typename _Iterator> |
526 | inline _GLIBCXX17_CONSTEXPRconstexpr reverse_iterator<_Iterator> |
527 | make_reverse_iterator(_Iterator __i) |
528 | { return reverse_iterator<_Iterator>(__i); } |
529 | |
530 | # if __cplusplus201703L > 201703L && defined __cpp_lib_concepts |
531 | template<typename _Iterator1, typename _Iterator2> |
532 | requires (!sized_sentinel_for<_Iterator1, _Iterator2>) |
533 | inline constexpr bool |
534 | disable_sized_sentinel_for<reverse_iterator<_Iterator1>, |
535 | reverse_iterator<_Iterator2>> = true; |
536 | # endif // C++20 |
537 | # endif // C++14 |
538 | |
539 | template<typename _Iterator> |
540 | _GLIBCXX20_CONSTEXPR |
541 | auto |
542 | __niter_base(reverse_iterator<_Iterator> __it) |
543 | -> decltype(__make_reverse_iterator(__niter_base(__it.base()))) |
544 | { return __make_reverse_iterator(__niter_base(__it.base())); } |
545 | |
546 | template<typename _Iterator> |
547 | struct __is_move_iterator<reverse_iterator<_Iterator> > |
548 | : __is_move_iterator<_Iterator> |
549 | { }; |
550 | |
551 | template<typename _Iterator> |
552 | _GLIBCXX20_CONSTEXPR |
553 | auto |
554 | __miter_base(reverse_iterator<_Iterator> __it) |
555 | -> decltype(__make_reverse_iterator(__miter_base(__it.base()))) |
556 | { return __make_reverse_iterator(__miter_base(__it.base())); } |
557 | #endif // C++11 |
558 | |
559 | // 24.4.2.2.1 back_insert_iterator |
560 | /** |
561 | * @brief Turns assignment into insertion. |
562 | * |
563 | * These are output iterators, constructed from a container-of-T. |
564 | * Assigning a T to the iterator appends it to the container using |
565 | * push_back. |
566 | * |
567 | * Tip: Using the back_inserter function to create these iterators can |
568 | * save typing. |
569 | */ |
570 | template<typename _Container> |
571 | class back_insert_iterator |
572 | : public iterator<output_iterator_tag, void, void, void, void> |
573 | { |
574 | protected: |
575 | _Container* container; |
576 | |
577 | public: |
578 | /// A nested typedef for the type of whatever container you used. |
579 | typedef _Container container_type; |
580 | #if __cplusplus201703L > 201703L |
581 | using difference_type = ptrdiff_t; |
582 | |
583 | constexpr back_insert_iterator() noexcept : container(nullptr) { } |
584 | #endif |
585 | |
586 | /// The only way to create this %iterator is with a container. |
587 | explicit _GLIBCXX20_CONSTEXPR |
588 | back_insert_iterator(_Container& __x) |
589 | : container(std::__addressof(__x)) { } |
590 | |
591 | /** |
592 | * @param __value An instance of whatever type |
593 | * container_type::const_reference is; presumably a |
594 | * reference-to-const T for container<T>. |
595 | * @return This %iterator, for chained operations. |
596 | * |
597 | * This kind of %iterator doesn't really have a @a position in the |
598 | * container (you can think of the position as being permanently at |
599 | * the end, if you like). Assigning a value to the %iterator will |
600 | * always append the value to the end of the container. |
601 | */ |
602 | #if __cplusplus201703L < 201103L |
603 | back_insert_iterator& |
604 | operator=(typename _Container::const_reference __value) |
605 | { |
606 | container->push_back(__value); |
607 | return *this; |
608 | } |
609 | #else |
610 | _GLIBCXX20_CONSTEXPR |
611 | back_insert_iterator& |
612 | operator=(const typename _Container::value_type& __value) |
613 | { |
614 | container->push_back(__value); |
615 | return *this; |
616 | } |
617 | |
618 | _GLIBCXX20_CONSTEXPR |
619 | back_insert_iterator& |
620 | operator=(typename _Container::value_type&& __value) |
621 | { |
622 | container->push_back(std::move(__value)); |
623 | return *this; |
624 | } |
625 | #endif |
626 | |
627 | /// Simply returns *this. |
628 | _GLIBCXX20_CONSTEXPR |
629 | back_insert_iterator& |
630 | operator*() |
631 | { return *this; } |
632 | |
633 | /// Simply returns *this. (This %iterator does not @a move.) |
634 | _GLIBCXX20_CONSTEXPR |
635 | back_insert_iterator& |
636 | operator++() |
637 | { return *this; } |
638 | |
639 | /// Simply returns *this. (This %iterator does not @a move.) |
640 | _GLIBCXX20_CONSTEXPR |
641 | back_insert_iterator |
642 | operator++(int) |
643 | { return *this; } |
644 | }; |
645 | |
646 | /** |
647 | * @param __x A container of arbitrary type. |
648 | * @return An instance of back_insert_iterator working on @p __x. |
649 | * |
650 | * This wrapper function helps in creating back_insert_iterator instances. |
651 | * Typing the name of the %iterator requires knowing the precise full |
652 | * type of the container, which can be tedious and impedes generic |
653 | * programming. Using this function lets you take advantage of automatic |
654 | * template parameter deduction, making the compiler match the correct |
655 | * types for you. |
656 | */ |
657 | template<typename _Container> |
658 | _GLIBCXX20_CONSTEXPR |
659 | inline back_insert_iterator<_Container> |
660 | back_inserter(_Container& __x) |
661 | { return back_insert_iterator<_Container>(__x); } |
662 | |
663 | /** |
664 | * @brief Turns assignment into insertion. |
665 | * |
666 | * These are output iterators, constructed from a container-of-T. |
667 | * Assigning a T to the iterator prepends it to the container using |
668 | * push_front. |
669 | * |
670 | * Tip: Using the front_inserter function to create these iterators can |
671 | * save typing. |
672 | */ |
673 | template<typename _Container> |
674 | class front_insert_iterator |
675 | : public iterator<output_iterator_tag, void, void, void, void> |
676 | { |
677 | protected: |
678 | _Container* container; |
679 | |
680 | public: |
681 | /// A nested typedef for the type of whatever container you used. |
682 | typedef _Container container_type; |
683 | #if __cplusplus201703L > 201703L |
684 | using difference_type = ptrdiff_t; |
685 | |
686 | constexpr front_insert_iterator() noexcept : container(nullptr) { } |
687 | #endif |
688 | |
689 | /// The only way to create this %iterator is with a container. |
690 | explicit _GLIBCXX20_CONSTEXPR |
691 | front_insert_iterator(_Container& __x) |
692 | : container(std::__addressof(__x)) { } |
693 | |
694 | /** |
695 | * @param __value An instance of whatever type |
696 | * container_type::const_reference is; presumably a |
697 | * reference-to-const T for container<T>. |
698 | * @return This %iterator, for chained operations. |
699 | * |
700 | * This kind of %iterator doesn't really have a @a position in the |
701 | * container (you can think of the position as being permanently at |
702 | * the front, if you like). Assigning a value to the %iterator will |
703 | * always prepend the value to the front of the container. |
704 | */ |
705 | #if __cplusplus201703L < 201103L |
706 | front_insert_iterator& |
707 | operator=(typename _Container::const_reference __value) |
708 | { |
709 | container->push_front(__value); |
710 | return *this; |
711 | } |
712 | #else |
713 | _GLIBCXX20_CONSTEXPR |
714 | front_insert_iterator& |
715 | operator=(const typename _Container::value_type& __value) |
716 | { |
717 | container->push_front(__value); |
718 | return *this; |
719 | } |
720 | |
721 | _GLIBCXX20_CONSTEXPR |
722 | front_insert_iterator& |
723 | operator=(typename _Container::value_type&& __value) |
724 | { |
725 | container->push_front(std::move(__value)); |
726 | return *this; |
727 | } |
728 | #endif |
729 | |
730 | /// Simply returns *this. |
731 | _GLIBCXX20_CONSTEXPR |
732 | front_insert_iterator& |
733 | operator*() |
734 | { return *this; } |
735 | |
736 | /// Simply returns *this. (This %iterator does not @a move.) |
737 | _GLIBCXX20_CONSTEXPR |
738 | front_insert_iterator& |
739 | operator++() |
740 | { return *this; } |
741 | |
742 | /// Simply returns *this. (This %iterator does not @a move.) |
743 | _GLIBCXX20_CONSTEXPR |
744 | front_insert_iterator |
745 | operator++(int) |
746 | { return *this; } |
747 | }; |
748 | |
749 | /** |
750 | * @param __x A container of arbitrary type. |
751 | * @return An instance of front_insert_iterator working on @p x. |
752 | * |
753 | * This wrapper function helps in creating front_insert_iterator instances. |
754 | * Typing the name of the %iterator requires knowing the precise full |
755 | * type of the container, which can be tedious and impedes generic |
756 | * programming. Using this function lets you take advantage of automatic |
757 | * template parameter deduction, making the compiler match the correct |
758 | * types for you. |
759 | */ |
760 | template<typename _Container> |
761 | _GLIBCXX20_CONSTEXPR |
762 | inline front_insert_iterator<_Container> |
763 | front_inserter(_Container& __x) |
764 | { return front_insert_iterator<_Container>(__x); } |
765 | |
766 | /** |
767 | * @brief Turns assignment into insertion. |
768 | * |
769 | * These are output iterators, constructed from a container-of-T. |
770 | * Assigning a T to the iterator inserts it in the container at the |
771 | * %iterator's position, rather than overwriting the value at that |
772 | * position. |
773 | * |
774 | * (Sequences will actually insert a @e copy of the value before the |
775 | * %iterator's position.) |
776 | * |
777 | * Tip: Using the inserter function to create these iterators can |
778 | * save typing. |
779 | */ |
780 | template<typename _Container> |
781 | class insert_iterator |
782 | : public iterator<output_iterator_tag, void, void, void, void> |
783 | { |
784 | #if __cplusplus201703L > 201703L && defined __cpp_lib_concepts |
785 | using _Iter = std::__detail::__range_iter_t<_Container>; |
786 | |
787 | protected: |
788 | _Container* container = nullptr; |
789 | _Iter iter = _Iter(); |
790 | #else |
791 | typedef typename _Container::iterator _Iter; |
792 | |
793 | protected: |
794 | _Container* container; |
795 | _Iter iter; |
796 | #endif |
797 | |
798 | public: |
799 | /// A nested typedef for the type of whatever container you used. |
800 | typedef _Container container_type; |
801 | |
802 | #if __cplusplus201703L > 201703L && defined __cpp_lib_concepts |
803 | using difference_type = ptrdiff_t; |
804 | |
805 | insert_iterator() = default; |
806 | #endif |
807 | |
808 | /** |
809 | * The only way to create this %iterator is with a container and an |
810 | * initial position (a normal %iterator into the container). |
811 | */ |
812 | _GLIBCXX20_CONSTEXPR |
813 | insert_iterator(_Container& __x, _Iter __i) |
814 | : container(std::__addressof(__x)), iter(__i) {} |
815 | |
816 | /** |
817 | * @param __value An instance of whatever type |
818 | * container_type::const_reference is; presumably a |
819 | * reference-to-const T for container<T>. |
820 | * @return This %iterator, for chained operations. |
821 | * |
822 | * This kind of %iterator maintains its own position in the |
823 | * container. Assigning a value to the %iterator will insert the |
824 | * value into the container at the place before the %iterator. |
825 | * |
826 | * The position is maintained such that subsequent assignments will |
827 | * insert values immediately after one another. For example, |
828 | * @code |
829 | * // vector v contains A and Z |
830 | * |
831 | * insert_iterator i (v, ++v.begin()); |
832 | * i = 1; |
833 | * i = 2; |
834 | * i = 3; |
835 | * |
836 | * // vector v contains A, 1, 2, 3, and Z |
837 | * @endcode |
838 | */ |
839 | #if __cplusplus201703L < 201103L |
840 | insert_iterator& |
841 | operator=(typename _Container::const_reference __value) |
842 | { |
843 | iter = container->insert(iter, __value); |
844 | ++iter; |
845 | return *this; |
846 | } |
847 | #else |
848 | _GLIBCXX20_CONSTEXPR |
849 | insert_iterator& |
850 | operator=(const typename _Container::value_type& __value) |
851 | { |
852 | iter = container->insert(iter, __value); |
853 | ++iter; |
854 | return *this; |
855 | } |
856 | |
857 | _GLIBCXX20_CONSTEXPR |
858 | insert_iterator& |
859 | operator=(typename _Container::value_type&& __value) |
860 | { |
861 | iter = container->insert(iter, std::move(__value)); |
862 | ++iter; |
863 | return *this; |
864 | } |
865 | #endif |
866 | |
867 | /// Simply returns *this. |
868 | _GLIBCXX20_CONSTEXPR |
869 | insert_iterator& |
870 | operator*() |
871 | { return *this; } |
872 | |
873 | /// Simply returns *this. (This %iterator does not @a move.) |
874 | _GLIBCXX20_CONSTEXPR |
875 | insert_iterator& |
876 | operator++() |
877 | { return *this; } |
878 | |
879 | /// Simply returns *this. (This %iterator does not @a move.) |
880 | _GLIBCXX20_CONSTEXPR |
881 | insert_iterator& |
882 | operator++(int) |
883 | { return *this; } |
884 | }; |
885 | |
886 | /** |
887 | * @param __x A container of arbitrary type. |
888 | * @param __i An iterator into the container. |
889 | * @return An instance of insert_iterator working on @p __x. |
890 | * |
891 | * This wrapper function helps in creating insert_iterator instances. |
892 | * Typing the name of the %iterator requires knowing the precise full |
893 | * type of the container, which can be tedious and impedes generic |
894 | * programming. Using this function lets you take advantage of automatic |
895 | * template parameter deduction, making the compiler match the correct |
896 | * types for you. |
897 | */ |
898 | #if __cplusplus201703L > 201703L && defined __cpp_lib_concepts |
899 | template<typename _Container> |
900 | constexpr insert_iterator<_Container> |
901 | inserter(_Container& __x, std::__detail::__range_iter_t<_Container> __i) |
902 | { return insert_iterator<_Container>(__x, __i); } |
903 | #else |
904 | template<typename _Container, typename _Iterator> |
905 | inline insert_iterator<_Container> |
906 | inserter(_Container& __x, _Iterator __i) |
907 | { |
908 | return insert_iterator<_Container>(__x, |
909 | typename _Container::iterator(__i)); |
910 | } |
911 | #endif |
912 | |
913 | // @} group iterators |
914 | |
915 | _GLIBCXX_END_NAMESPACE_VERSION |
916 | } // namespace |
917 | |
918 | namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
919 | { |
920 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
921 | |
922 | // This iterator adapter is @a normal in the sense that it does not |
923 | // change the semantics of any of the operators of its iterator |
924 | // parameter. Its primary purpose is to convert an iterator that is |
925 | // not a class, e.g. a pointer, into an iterator that is a class. |
926 | // The _Container parameter exists solely so that different containers |
927 | // using this template can instantiate different types, even if the |
928 | // _Iterator parameter is the same. |
929 | template<typename _Iterator, typename _Container> |
930 | class __normal_iterator |
931 | { |
932 | protected: |
933 | _Iterator _M_current; |
934 | |
935 | typedef std::iterator_traits<_Iterator> __traits_type; |
936 | |
937 | public: |
938 | typedef _Iterator iterator_type; |
939 | typedef typename __traits_type::iterator_category iterator_category; |
940 | typedef typename __traits_type::value_type value_type; |
941 | typedef typename __traits_type::difference_type difference_type; |
942 | typedef typename __traits_type::reference reference; |
943 | typedef typename __traits_type::pointer pointer; |
944 | |
945 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
946 | using iterator_concept = std::__detail::__iter_concept<_Iterator>; |
947 | #endif |
948 | |
949 | _GLIBCXX_CONSTEXPRconstexpr __normal_iterator() _GLIBCXX_NOEXCEPTnoexcept |
950 | : _M_current(_Iterator()) { } |
951 | |
952 | explicit _GLIBCXX20_CONSTEXPR |
953 | __normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPTnoexcept |
954 | : _M_current(__i) { } |
955 | |
956 | // Allow iterator to const_iterator conversion |
957 | template<typename _Iter> |
958 | _GLIBCXX20_CONSTEXPR |
959 | __normal_iterator(const __normal_iterator<_Iter, |
960 | typename __enable_if< |
961 | (std::__are_same<_Iter, typename _Container::pointer>::__value), |
962 | _Container>::__type>& __i) _GLIBCXX_NOEXCEPTnoexcept |
963 | : _M_current(__i.base()) { } |
964 | |
965 | // Forward iterator requirements |
966 | _GLIBCXX20_CONSTEXPR |
967 | reference |
968 | operator*() const _GLIBCXX_NOEXCEPTnoexcept |
969 | { return *_M_current; } |
970 | |
971 | _GLIBCXX20_CONSTEXPR |
972 | pointer |
973 | operator->() const _GLIBCXX_NOEXCEPTnoexcept |
974 | { return _M_current; } |
975 | |
976 | _GLIBCXX20_CONSTEXPR |
977 | __normal_iterator& |
978 | operator++() _GLIBCXX_NOEXCEPTnoexcept |
979 | { |
980 | ++_M_current; |
981 | return *this; |
982 | } |
983 | |
984 | _GLIBCXX20_CONSTEXPR |
985 | __normal_iterator |
986 | operator++(int) _GLIBCXX_NOEXCEPTnoexcept |
987 | { return __normal_iterator(_M_current++); } |
988 | |
989 | // Bidirectional iterator requirements |
990 | _GLIBCXX20_CONSTEXPR |
991 | __normal_iterator& |
992 | operator--() _GLIBCXX_NOEXCEPTnoexcept |
993 | { |
994 | --_M_current; |
995 | return *this; |
996 | } |
997 | |
998 | _GLIBCXX20_CONSTEXPR |
999 | __normal_iterator |
1000 | operator--(int) _GLIBCXX_NOEXCEPTnoexcept |
1001 | { return __normal_iterator(_M_current--); } |
1002 | |
1003 | // Random access iterator requirements |
1004 | _GLIBCXX20_CONSTEXPR |
1005 | reference |
1006 | operator[](difference_type __n) const _GLIBCXX_NOEXCEPTnoexcept |
1007 | { return _M_current[__n]; } |
1008 | |
1009 | _GLIBCXX20_CONSTEXPR |
1010 | __normal_iterator& |
1011 | operator+=(difference_type __n) _GLIBCXX_NOEXCEPTnoexcept |
1012 | { _M_current += __n; return *this; } |
1013 | |
1014 | _GLIBCXX20_CONSTEXPR |
1015 | __normal_iterator |
1016 | operator+(difference_type __n) const _GLIBCXX_NOEXCEPTnoexcept |
1017 | { return __normal_iterator(_M_current + __n); } |
1018 | |
1019 | _GLIBCXX20_CONSTEXPR |
1020 | __normal_iterator& |
1021 | operator-=(difference_type __n) _GLIBCXX_NOEXCEPTnoexcept |
1022 | { _M_current -= __n; return *this; } |
1023 | |
1024 | _GLIBCXX20_CONSTEXPR |
1025 | __normal_iterator |
1026 | operator-(difference_type __n) const _GLIBCXX_NOEXCEPTnoexcept |
1027 | { return __normal_iterator(_M_current - __n); } |
1028 | |
1029 | _GLIBCXX20_CONSTEXPR |
1030 | const _Iterator& |
1031 | base() const _GLIBCXX_NOEXCEPTnoexcept |
1032 | { return _M_current; } |
1033 | }; |
1034 | |
1035 | // Note: In what follows, the left- and right-hand-side iterators are |
1036 | // allowed to vary in types (conceptually in cv-qualification) so that |
1037 | // comparison between cv-qualified and non-cv-qualified iterators be |
1038 | // valid. However, the greedy and unfriendly operators in std::rel_ops |
1039 | // will make overload resolution ambiguous (when in scope) if we don't |
1040 | // provide overloads whose operands are of the same type. Can someone |
1041 | // remind me what generic programming is about? -- Gaby |
1042 | |
1043 | #if __cpp_lib_three_way_comparison |
1044 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1045 | requires requires (_IteratorL __lhs, _IteratorR __rhs) |
1046 | { { __lhs == __rhs } -> std::convertible_to<bool>; } |
1047 | constexpr bool |
1048 | operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1049 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1050 | noexcept(noexcept(__lhs.base() == __rhs.base())) |
1051 | { return __lhs.base() == __rhs.base(); } |
1052 | |
1053 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1054 | constexpr std::__detail::__synth3way_t<_IteratorR, _IteratorL> |
1055 | operator<=>(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1056 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1057 | noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base()))) |
1058 | { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); } |
1059 | #else |
1060 | // Forward iterator requirements |
1061 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1062 | _GLIBCXX20_CONSTEXPR |
1063 | inline bool |
1064 | operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1065 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1066 | _GLIBCXX_NOEXCEPTnoexcept |
1067 | { return __lhs.base() == __rhs.base(); } |
1068 | |
1069 | template<typename _Iterator, typename _Container> |
1070 | _GLIBCXX20_CONSTEXPR |
1071 | inline bool |
1072 | operator==(const __normal_iterator<_Iterator, _Container>& __lhs, |
1073 | const __normal_iterator<_Iterator, _Container>& __rhs) |
1074 | _GLIBCXX_NOEXCEPTnoexcept |
1075 | { return __lhs.base() == __rhs.base(); } |
1076 | |
1077 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1078 | _GLIBCXX20_CONSTEXPR |
1079 | inline bool |
1080 | operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1081 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1082 | _GLIBCXX_NOEXCEPTnoexcept |
1083 | { return __lhs.base() != __rhs.base(); } |
1084 | |
1085 | template<typename _Iterator, typename _Container> |
1086 | _GLIBCXX20_CONSTEXPR |
1087 | inline bool |
1088 | operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, |
1089 | const __normal_iterator<_Iterator, _Container>& __rhs) |
1090 | _GLIBCXX_NOEXCEPTnoexcept |
1091 | { return __lhs.base() != __rhs.base(); } |
1092 | |
1093 | // Random access iterator requirements |
1094 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1095 | inline bool |
1096 | operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1097 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1098 | _GLIBCXX_NOEXCEPTnoexcept |
1099 | { return __lhs.base() < __rhs.base(); } |
1100 | |
1101 | template<typename _Iterator, typename _Container> |
1102 | _GLIBCXX20_CONSTEXPR |
1103 | inline bool |
1104 | operator<(const __normal_iterator<_Iterator, _Container>& __lhs, |
1105 | const __normal_iterator<_Iterator, _Container>& __rhs) |
1106 | _GLIBCXX_NOEXCEPTnoexcept |
1107 | { return __lhs.base() < __rhs.base(); } |
1108 | |
1109 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1110 | inline bool |
1111 | operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1112 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1113 | _GLIBCXX_NOEXCEPTnoexcept |
1114 | { return __lhs.base() > __rhs.base(); } |
1115 | |
1116 | template<typename _Iterator, typename _Container> |
1117 | _GLIBCXX20_CONSTEXPR |
1118 | inline bool |
1119 | operator>(const __normal_iterator<_Iterator, _Container>& __lhs, |
1120 | const __normal_iterator<_Iterator, _Container>& __rhs) |
1121 | _GLIBCXX_NOEXCEPTnoexcept |
1122 | { return __lhs.base() > __rhs.base(); } |
1123 | |
1124 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1125 | inline bool |
1126 | operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1127 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1128 | _GLIBCXX_NOEXCEPTnoexcept |
1129 | { return __lhs.base() <= __rhs.base(); } |
1130 | |
1131 | template<typename _Iterator, typename _Container> |
1132 | _GLIBCXX20_CONSTEXPR |
1133 | inline bool |
1134 | operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, |
1135 | const __normal_iterator<_Iterator, _Container>& __rhs) |
1136 | _GLIBCXX_NOEXCEPTnoexcept |
1137 | { return __lhs.base() <= __rhs.base(); } |
1138 | |
1139 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1140 | inline bool |
1141 | operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1142 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1143 | _GLIBCXX_NOEXCEPTnoexcept |
1144 | { return __lhs.base() >= __rhs.base(); } |
1145 | |
1146 | template<typename _Iterator, typename _Container> |
1147 | _GLIBCXX20_CONSTEXPR |
1148 | inline bool |
1149 | operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, |
1150 | const __normal_iterator<_Iterator, _Container>& __rhs) |
1151 | _GLIBCXX_NOEXCEPTnoexcept |
1152 | { return __lhs.base() >= __rhs.base(); } |
1153 | #endif // three-way comparison |
1154 | |
1155 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1156 | // According to the resolution of DR179 not only the various comparison |
1157 | // operators but also operator- must accept mixed iterator/const_iterator |
1158 | // parameters. |
1159 | template<typename _IteratorL, typename _IteratorR, typename _Container> |
1160 | #if __cplusplus201703L >= 201103L |
1161 | // DR 685. |
1162 | _GLIBCXX20_CONSTEXPR |
1163 | inline auto |
1164 | operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1165 | const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept |
1166 | -> decltype(__lhs.base() - __rhs.base()) |
1167 | #else |
1168 | inline typename __normal_iterator<_IteratorL, _Container>::difference_type |
1169 | operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, |
1170 | const __normal_iterator<_IteratorR, _Container>& __rhs) |
1171 | #endif |
1172 | { return __lhs.base() - __rhs.base(); } |
1173 | |
1174 | template<typename _Iterator, typename _Container> |
1175 | _GLIBCXX20_CONSTEXPR |
1176 | inline typename __normal_iterator<_Iterator, _Container>::difference_type |
1177 | operator-(const __normal_iterator<_Iterator, _Container>& __lhs, |
1178 | const __normal_iterator<_Iterator, _Container>& __rhs) |
1179 | _GLIBCXX_NOEXCEPTnoexcept |
1180 | { return __lhs.base() - __rhs.base(); } |
1181 | |
1182 | template<typename _Iterator, typename _Container> |
1183 | _GLIBCXX20_CONSTEXPR |
1184 | inline __normal_iterator<_Iterator, _Container> |
1185 | operator+(typename __normal_iterator<_Iterator, _Container>::difference_type |
1186 | __n, const __normal_iterator<_Iterator, _Container>& __i) |
1187 | _GLIBCXX_NOEXCEPTnoexcept |
1188 | { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } |
1189 | |
1190 | _GLIBCXX_END_NAMESPACE_VERSION |
1191 | } // namespace |
1192 | |
1193 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
1194 | { |
1195 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
1196 | |
1197 | template<typename _Iterator, typename _Container> |
1198 | _GLIBCXX20_CONSTEXPR |
1199 | _Iterator |
1200 | __niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it) |
1201 | _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)noexcept(std::is_nothrow_copy_constructible<_Iterator>:: value) |
1202 | { return __it.base(); } |
1203 | |
1204 | #if __cplusplus201703L >= 201103L |
1205 | /** |
1206 | * @addtogroup iterators |
1207 | * @{ |
1208 | */ |
1209 | |
1210 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1211 | template<semiregular _Sent> |
1212 | class move_sentinel |
1213 | { |
1214 | public: |
1215 | constexpr |
1216 | move_sentinel() |
1217 | noexcept(is_nothrow_default_constructible_v<_Sent>) |
1218 | : _M_last() { } |
1219 | |
1220 | constexpr explicit |
1221 | move_sentinel(_Sent __s) |
1222 | noexcept(is_nothrow_move_constructible_v<_Sent>) |
1223 | : _M_last(std::move(__s)) { } |
1224 | |
1225 | template<typename _S2> requires convertible_to<const _S2&, _Sent> |
1226 | constexpr |
1227 | move_sentinel(const move_sentinel<_S2>& __s) |
1228 | noexcept(is_nothrow_constructible_v<_Sent, const _S2&>) |
1229 | : _M_last(__s.base()) |
1230 | { } |
1231 | |
1232 | template<typename _S2> requires assignable_from<_Sent&, const _S2&> |
1233 | constexpr move_sentinel& |
1234 | operator=(const move_sentinel<_S2>& __s) |
1235 | noexcept(is_nothrow_assignable_v<_Sent, const _S2&>) |
1236 | { |
1237 | _M_last = __s.base(); |
1238 | return *this; |
1239 | } |
1240 | |
1241 | constexpr _Sent |
1242 | base() const |
1243 | noexcept(is_nothrow_copy_constructible_v<_Sent>) |
1244 | { return _M_last; } |
1245 | |
1246 | private: |
1247 | _Sent _M_last; |
1248 | }; |
1249 | #endif // C++20 |
1250 | |
1251 | // 24.4.3 Move iterators |
1252 | /** |
1253 | * Class template move_iterator is an iterator adapter with the same |
1254 | * behavior as the underlying iterator except that its dereference |
1255 | * operator implicitly converts the value returned by the underlying |
1256 | * iterator's dereference operator to an rvalue reference. Some |
1257 | * generic algorithms can be called with move iterators to replace |
1258 | * copying with moving. |
1259 | */ |
1260 | template<typename _Iterator> |
1261 | class move_iterator |
1262 | { |
1263 | _Iterator _M_current; |
1264 | |
1265 | using __traits_type = iterator_traits<_Iterator>; |
1266 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1267 | using __base_cat = typename __traits_type::iterator_category; |
1268 | #else |
1269 | using __base_ref = typename __traits_type::reference; |
1270 | #endif |
1271 | |
1272 | public: |
1273 | using iterator_type = _Iterator; |
1274 | |
1275 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1276 | using iterator_concept = input_iterator_tag; |
1277 | using iterator_category |
1278 | = __detail::__clamp_iter_cat<__base_cat, random_access_iterator_tag>; |
1279 | using value_type = iter_value_t<_Iterator>; |
1280 | using difference_type = iter_difference_t<_Iterator>; |
1281 | using pointer = _Iterator; |
1282 | using reference = iter_rvalue_reference_t<_Iterator>; |
1283 | #else |
1284 | typedef typename __traits_type::iterator_category iterator_category; |
1285 | typedef typename __traits_type::value_type value_type; |
1286 | typedef typename __traits_type::difference_type difference_type; |
1287 | // NB: DR 680. |
1288 | typedef _Iterator pointer; |
1289 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1290 | // 2106. move_iterator wrapping iterators returning prvalues |
1291 | typedef typename conditional<is_reference<__base_ref>::value, |
1292 | typename remove_reference<__base_ref>::type&&, |
1293 | __base_ref>::type reference; |
1294 | #endif |
1295 | |
1296 | _GLIBCXX17_CONSTEXPRconstexpr |
1297 | move_iterator() |
1298 | : _M_current() { } |
1299 | |
1300 | explicit _GLIBCXX17_CONSTEXPRconstexpr |
1301 | move_iterator(iterator_type __i) |
1302 | : _M_current(std::move(__i)) { } |
1303 | |
1304 | template<typename _Iter> |
1305 | _GLIBCXX17_CONSTEXPRconstexpr |
1306 | move_iterator(const move_iterator<_Iter>& __i) |
1307 | : _M_current(__i.base()) { } |
1308 | |
1309 | #if __cplusplus201703L <= 201703L |
1310 | _GLIBCXX17_CONSTEXPRconstexpr iterator_type |
1311 | base() const |
1312 | { return _M_current; } |
1313 | #else |
1314 | constexpr iterator_type |
1315 | base() const & |
1316 | #if __cpp_lib_concepts |
1317 | requires copy_constructible<iterator_type> |
1318 | #endif |
1319 | { return _M_current; } |
1320 | |
1321 | constexpr iterator_type |
1322 | base() && |
1323 | { return std::move(_M_current); } |
1324 | #endif |
1325 | |
1326 | _GLIBCXX17_CONSTEXPRconstexpr reference |
1327 | operator*() const |
1328 | { return static_cast<reference>(*_M_current); } |
1329 | |
1330 | _GLIBCXX17_CONSTEXPRconstexpr pointer |
1331 | operator->() const |
1332 | { return _M_current; } |
1333 | |
1334 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator& |
1335 | operator++() |
1336 | { |
1337 | ++_M_current; |
1338 | return *this; |
1339 | } |
1340 | |
1341 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator |
1342 | operator++(int) |
1343 | { |
1344 | move_iterator __tmp = *this; |
1345 | ++_M_current; |
1346 | return __tmp; |
1347 | } |
1348 | |
1349 | #if __cpp_lib_concepts |
1350 | constexpr void |
1351 | operator++(int) requires (!forward_iterator<_Iterator>) |
1352 | { ++_M_current; } |
1353 | #endif |
1354 | |
1355 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator& |
1356 | operator--() |
1357 | { |
1358 | --_M_current; |
1359 | return *this; |
1360 | } |
1361 | |
1362 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator |
1363 | operator--(int) |
1364 | { |
1365 | move_iterator __tmp = *this; |
1366 | --_M_current; |
1367 | return __tmp; |
1368 | } |
1369 | |
1370 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator |
1371 | operator+(difference_type __n) const |
1372 | { return move_iterator(_M_current + __n); } |
1373 | |
1374 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator& |
1375 | operator+=(difference_type __n) |
1376 | { |
1377 | _M_current += __n; |
1378 | return *this; |
1379 | } |
1380 | |
1381 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator |
1382 | operator-(difference_type __n) const |
1383 | { return move_iterator(_M_current - __n); } |
1384 | |
1385 | _GLIBCXX17_CONSTEXPRconstexpr move_iterator& |
1386 | operator-=(difference_type __n) |
1387 | { |
1388 | _M_current -= __n; |
1389 | return *this; |
1390 | } |
1391 | |
1392 | _GLIBCXX17_CONSTEXPRconstexpr reference |
1393 | operator[](difference_type __n) const |
1394 | { return std::move(_M_current[__n]); } |
1395 | |
1396 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1397 | template<sentinel_for<_Iterator> _Sent> |
1398 | friend constexpr bool |
1399 | operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) |
1400 | { return __x.base() == __y.base(); } |
1401 | |
1402 | template<sized_sentinel_for<_Iterator> _Sent> |
1403 | friend constexpr iter_difference_t<_Iterator> |
1404 | operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) |
1405 | { return __x.base() - __y.base(); } |
1406 | |
1407 | template<sized_sentinel_for<_Iterator> _Sent> |
1408 | friend constexpr iter_difference_t<_Iterator> |
1409 | operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) |
1410 | { return __x.base() - __y.base(); } |
1411 | |
1412 | friend constexpr iter_rvalue_reference_t<_Iterator> |
1413 | iter_move(const move_iterator& __i) |
1414 | noexcept(noexcept(ranges::iter_move(__i._M_current))) |
1415 | { return ranges::iter_move(__i._M_current); } |
1416 | |
1417 | template<indirectly_swappable<_Iterator> _Iter2> |
1418 | friend constexpr void |
1419 | iter_swap(const move_iterator& __x, const move_iterator<_Iter2>& __y) |
1420 | noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current))) |
1421 | { return ranges::iter_swap(__x._M_current, __y._M_current); } |
1422 | #endif // C++20 |
1423 | }; |
1424 | |
1425 | template<typename _IteratorL, typename _IteratorR> |
1426 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1427 | operator==(const move_iterator<_IteratorL>& __x, |
1428 | const move_iterator<_IteratorR>& __y) |
1429 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1430 | requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; } |
1431 | #endif |
1432 | { return __x.base() == __y.base(); } |
1433 | |
1434 | #if __cpp_lib_three_way_comparison |
1435 | template<typename _IteratorL, |
1436 | three_way_comparable_with<_IteratorL> _IteratorR> |
1437 | constexpr compare_three_way_result_t<_IteratorL, _IteratorR> |
1438 | operator<=>(const move_iterator<_IteratorL>& __x, |
1439 | const move_iterator<_IteratorR>& __y) |
1440 | { return __x.base() <=> __y.base(); } |
1441 | #else |
1442 | template<typename _IteratorL, typename _IteratorR> |
1443 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1444 | operator!=(const move_iterator<_IteratorL>& __x, |
1445 | const move_iterator<_IteratorR>& __y) |
1446 | { return !(__x == __y); } |
1447 | #endif |
1448 | |
1449 | template<typename _IteratorL, typename _IteratorR> |
1450 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1451 | operator<(const move_iterator<_IteratorL>& __x, |
1452 | const move_iterator<_IteratorR>& __y) |
1453 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1454 | requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; } |
1455 | #endif |
1456 | { return __x.base() < __y.base(); } |
1457 | |
1458 | template<typename _IteratorL, typename _IteratorR> |
1459 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1460 | operator<=(const move_iterator<_IteratorL>& __x, |
1461 | const move_iterator<_IteratorR>& __y) |
1462 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1463 | requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; } |
1464 | #endif |
1465 | { return !(__y < __x); } |
1466 | |
1467 | template<typename _IteratorL, typename _IteratorR> |
1468 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1469 | operator>(const move_iterator<_IteratorL>& __x, |
1470 | const move_iterator<_IteratorR>& __y) |
1471 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1472 | requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; } |
1473 | #endif |
1474 | { return __y < __x; } |
1475 | |
1476 | template<typename _IteratorL, typename _IteratorR> |
1477 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1478 | operator>=(const move_iterator<_IteratorL>& __x, |
1479 | const move_iterator<_IteratorR>& __y) |
1480 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1481 | requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; } |
1482 | #endif |
1483 | { return !(__x < __y); } |
1484 | |
1485 | #if ! (__cplusplus201703L > 201703L && __cpp_lib_concepts) |
1486 | // Note: See __normal_iterator operators note from Gaby to understand |
1487 | // why we have these extra overloads for some move_iterator operators. |
1488 | |
1489 | // These extra overloads are not needed in C++20, because the ones above |
1490 | // are constrained with a requires-clause and so overload resolution will |
1491 | // prefer them to greedy unconstrained function templates. |
1492 | |
1493 | template<typename _Iterator> |
1494 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1495 | operator==(const move_iterator<_Iterator>& __x, |
1496 | const move_iterator<_Iterator>& __y) |
1497 | { return __x.base() == __y.base(); } |
1498 | |
1499 | template<typename _Iterator> |
1500 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1501 | operator!=(const move_iterator<_Iterator>& __x, |
1502 | const move_iterator<_Iterator>& __y) |
1503 | { return !(__x == __y); } |
1504 | |
1505 | template<typename _Iterator> |
1506 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1507 | operator<(const move_iterator<_Iterator>& __x, |
1508 | const move_iterator<_Iterator>& __y) |
1509 | { return __x.base() < __y.base(); } |
1510 | |
1511 | template<typename _Iterator> |
1512 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1513 | operator<=(const move_iterator<_Iterator>& __x, |
1514 | const move_iterator<_Iterator>& __y) |
1515 | { return !(__y < __x); } |
1516 | |
1517 | template<typename _Iterator> |
1518 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1519 | operator>(const move_iterator<_Iterator>& __x, |
1520 | const move_iterator<_Iterator>& __y) |
1521 | { return __y < __x; } |
1522 | |
1523 | template<typename _Iterator> |
1524 | inline _GLIBCXX17_CONSTEXPRconstexpr bool |
1525 | operator>=(const move_iterator<_Iterator>& __x, |
1526 | const move_iterator<_Iterator>& __y) |
1527 | { return !(__x < __y); } |
1528 | #endif // ! C++20 |
1529 | |
1530 | // DR 685. |
1531 | template<typename _IteratorL, typename _IteratorR> |
1532 | inline _GLIBCXX17_CONSTEXPRconstexpr auto |
1533 | operator-(const move_iterator<_IteratorL>& __x, |
1534 | const move_iterator<_IteratorR>& __y) |
1535 | -> decltype(__x.base() - __y.base()) |
1536 | { return __x.base() - __y.base(); } |
1537 | |
1538 | template<typename _Iterator> |
1539 | inline _GLIBCXX17_CONSTEXPRconstexpr move_iterator<_Iterator> |
1540 | operator+(typename move_iterator<_Iterator>::difference_type __n, |
1541 | const move_iterator<_Iterator>& __x) |
1542 | { return __x + __n; } |
1543 | |
1544 | template<typename _Iterator> |
1545 | inline _GLIBCXX17_CONSTEXPRconstexpr move_iterator<_Iterator> |
1546 | make_move_iterator(_Iterator __i) |
1547 | { return move_iterator<_Iterator>(std::move(__i)); } |
1548 | |
1549 | template<typename _Iterator, typename _ReturnType |
1550 | = typename conditional<__move_if_noexcept_cond |
1551 | <typename iterator_traits<_Iterator>::value_type>::value, |
1552 | _Iterator, move_iterator<_Iterator>>::type> |
1553 | inline _GLIBCXX17_CONSTEXPRconstexpr _ReturnType |
1554 | __make_move_if_noexcept_iterator(_Iterator __i) |
1555 | { return _ReturnType(__i); } |
1556 | |
1557 | // Overload for pointers that matches std::move_if_noexcept more closely, |
1558 | // returning a constant iterator when we don't want to move. |
1559 | template<typename _Tp, typename _ReturnType |
1560 | = typename conditional<__move_if_noexcept_cond<_Tp>::value, |
1561 | const _Tp*, move_iterator<_Tp*>>::type> |
1562 | inline _GLIBCXX17_CONSTEXPRconstexpr _ReturnType |
1563 | __make_move_if_noexcept_iterator(_Tp* __i) |
1564 | { return _ReturnType(__i); } |
1565 | |
1566 | #if __cplusplus201703L > 201703L && __cpp_lib_concepts |
1567 | // [iterators.common] Common iterators |
1568 | |
1569 | namespace __detail |
1570 | { |
1571 | template<typename _It> |
1572 | concept __common_iter_has_arrow = indirectly_readable<const _It> |
1573 | && (requires(const _It& __it) { __it.operator->(); } |
1574 | || is_reference_v<iter_reference_t<_It>> |
1575 | || constructible_from<iter_value_t<_It>, iter_reference_t<_It>>); |
1576 | |
1577 | } // namespace __detail |
1578 | |
1579 | /// An iterator/sentinel adaptor for representing a non-common range. |
1580 | template<input_or_output_iterator _It, sentinel_for<_It> _Sent> |
1581 | requires (!same_as<_It, _Sent>) && copyable<_It> |
1582 | class common_iterator |
1583 | { |
1584 | template<typename _Tp, typename _Up> |
1585 | static constexpr bool |
1586 | _S_noexcept1() |
1587 | { |
1588 | if constexpr (is_trivially_default_constructible_v<_Tp>) |
1589 | return is_nothrow_assignable_v<_Tp, _Up>; |
1590 | else |
1591 | return is_nothrow_constructible_v<_Tp, _Up>; |
1592 | } |
1593 | |
1594 | template<typename _It2, typename _Sent2> |
1595 | static constexpr bool |
1596 | _S_noexcept() |
1597 | { return _S_noexcept1<_It, _It2>() && _S_noexcept1<_Sent, _Sent2>(); } |
1598 | |
1599 | class _Proxy |
1600 | { |
1601 | iter_value_t<_It> _M_keep; |
1602 | |
1603 | _Proxy(iter_reference_t<_It>&& __x) |
1604 | : _M_keep(std::move(__x)) { } |
1605 | |
1606 | friend class common_iterator; |
1607 | |
1608 | public: |
1609 | const iter_value_t<_It>* |
1610 | operator->() const |
1611 | { return std::__addressof(_M_keep); } |
1612 | }; |
1613 | |
1614 | public: |
1615 | constexpr |
1616 | common_iterator() |
1617 | noexcept(is_nothrow_default_constructible_v<_It>) |
1618 | : _M_it(), _M_index(0) |
1619 | { } |
1620 | |
1621 | constexpr |
1622 | common_iterator(_It __i) |
1623 | noexcept(is_nothrow_move_constructible_v<_It>) |
1624 | : _M_it(std::move(__i)), _M_index(0) |
1625 | { } |
1626 | |
1627 | constexpr |
1628 | common_iterator(_Sent __s) |
1629 | noexcept(is_nothrow_move_constructible_v<_Sent>) |
1630 | : _M_sent(std::move(__s)), _M_index(1) |
1631 | { } |
1632 | |
1633 | template<typename _It2, typename _Sent2> |
1634 | requires convertible_to<const _It2&, _It> |
1635 | && convertible_to<const _Sent2&, _Sent> |
1636 | constexpr |
1637 | common_iterator(const common_iterator<_It2, _Sent2>& __x) |
1638 | noexcept(_S_noexcept<const _It2&, const _Sent2&>()) |
1639 | : _M_valueless(), _M_index(__x._M_index) |
1640 | { |
1641 | if (_M_index == 0) |
1642 | { |
1643 | if constexpr (is_trivially_default_constructible_v<_It>) |
1644 | _M_it = std::move(__x._M_it); |
1645 | else |
1646 | ::new((void*)std::__addressof(_M_it)) _It(__x._M_it); |
1647 | } |
1648 | else if (_M_index == 1) |
1649 | { |
1650 | if constexpr (is_trivially_default_constructible_v<_Sent>) |
1651 | _M_sent = std::move(__x._M_sent); |
1652 | else |
1653 | ::new((void*)std::__addressof(_M_sent)) _Sent(__x._M_sent); |
1654 | } |
1655 | } |
1656 | |
1657 | constexpr |
1658 | common_iterator(const common_iterator& __x) |
1659 | noexcept(_S_noexcept<const _It&, const _Sent&>()) |
1660 | : _M_valueless(), _M_index(__x._M_index) |
1661 | { |
1662 | if (_M_index == 0) |
1663 | { |
1664 | if constexpr (is_trivially_default_constructible_v<_It>) |
1665 | _M_it = std::move(__x._M_it); |
1666 | else |
1667 | ::new((void*)std::__addressof(_M_it)) _It(__x._M_it); |
1668 | } |
1669 | else if (_M_index == 1) |
1670 | { |
1671 | if constexpr (is_trivially_default_constructible_v<_Sent>) |
1672 | _M_sent = std::move(__x._M_sent); |
1673 | else |
1674 | ::new((void*)std::__addressof(_M_sent)) _Sent(__x._M_sent); |
1675 | } |
1676 | } |
1677 | |
1678 | common_iterator& |
1679 | operator=(const common_iterator& __x) |
1680 | noexcept(is_nothrow_copy_assignable_v<_It> |
1681 | && is_nothrow_copy_assignable_v<_Sent> |
1682 | && is_nothrow_copy_constructible_v<_It> |
1683 | && is_nothrow_copy_constructible_v<_Sent>) |
1684 | { |
1685 | return this->operator=<_It, _Sent>(__x); |
1686 | } |
1687 | |
1688 | template<typename _It2, typename _Sent2> |
1689 | requires convertible_to<const _It2&, _It> |
1690 | && convertible_to<const _Sent2&, _Sent> |
1691 | && assignable_from<_It&, const _It2&> |
1692 | && assignable_from<_Sent&, const _Sent2&> |
1693 | common_iterator& |
1694 | operator=(const common_iterator<_It2, _Sent2>& __x) |
1695 | noexcept(is_nothrow_constructible_v<_It, const _It2&> |
1696 | && is_nothrow_constructible_v<_Sent, const _Sent2&> |
1697 | && is_nothrow_assignable_v<_It, const _It2&> |
1698 | && is_nothrow_assignable_v<_Sent, const _Sent2&>) |
1699 | { |
1700 | switch(_M_index << 2 | __x._M_index) |
1701 | { |
1702 | case 0b0000: |
1703 | _M_it = __x._M_it; |
1704 | break; |
1705 | case 0b0101: |
1706 | _M_sent = __x._M_sent; |
1707 | break; |
1708 | case 0b0001: |
1709 | _M_it.~_It(); |
1710 | _M_index = -1; |
1711 | [[fallthrough]]; |
1712 | case 0b1001: |
1713 | ::new((void*)std::__addressof(_M_sent)) _Sent(__x._M_sent); |
1714 | _M_index = 1; |
1715 | break; |
1716 | case 0b0100: |
1717 | _M_sent.~_Sent(); |
1718 | _M_index = -1; |
1719 | [[fallthrough]]; |
1720 | case 0b1000: |
1721 | ::new((void*)std::__addressof(_M_it)) _It(__x._M_it); |
1722 | _M_index = 0; |
1723 | break; |
1724 | default: |
1725 | __glibcxx_assert(__x._M_has_value()); |
1726 | __builtin_unreachable(); |
1727 | } |
1728 | return *this; |
1729 | } |
1730 | |
1731 | ~common_iterator() |
1732 | { |
1733 | switch (_M_index) |
1734 | { |
1735 | case 0: |
1736 | _M_it.~_It(); |
1737 | break; |
1738 | case 1: |
1739 | _M_sent.~_Sent(); |
1740 | break; |
1741 | } |
1742 | } |
1743 | |
1744 | decltype(auto) |
1745 | operator*() |
1746 | { |
1747 | __glibcxx_assert(_M_index == 0); |
1748 | return *_M_it; |
1749 | } |
1750 | |
1751 | decltype(auto) |
1752 | operator*() const requires __detail::__dereferenceable<const _It> |
1753 | { |
1754 | __glibcxx_assert(_M_index == 0); |
1755 | return *_M_it; |
1756 | } |
1757 | |
1758 | decltype(auto) |
1759 | operator->() const requires __detail::__common_iter_has_arrow<_It> |
1760 | { |
1761 | __glibcxx_assert(_M_index == 0); |
1762 | if constexpr (is_pointer_v<_It> || requires { _M_it.operator->(); }) |
1763 | return _M_it; |
1764 | else if constexpr (is_reference_v<iter_reference_t<_It>>) |
1765 | { |
1766 | auto&& __tmp = *_M_it; |
1767 | return std::__addressof(__tmp); |
1768 | } |
1769 | else |
1770 | return _Proxy{*_M_it}; |
1771 | } |
1772 | |
1773 | common_iterator& |
1774 | operator++() |
1775 | { |
1776 | __glibcxx_assert(_M_index == 0); |
1777 | ++_M_it; |
1778 | return *this; |
1779 | } |
1780 | |
1781 | decltype(auto) |
1782 | operator++(int) |
1783 | { |
1784 | __glibcxx_assert(_M_index == 0); |
1785 | if constexpr (forward_iterator<_It>) |
1786 | { |
1787 | common_iterator __tmp = *this; |
1788 | ++*this; |
1789 | return __tmp; |
1790 | } |
1791 | else |
1792 | return _M_it++; |
1793 | } |
1794 | |
1795 | template<typename _It2, sentinel_for<_It> _Sent2> |
1796 | requires sentinel_for<_Sent, _It2> |
1797 | friend bool |
1798 | operator==(const common_iterator& __x, |
1799 | const common_iterator<_It2, _Sent2>& __y) |
1800 | { |
1801 | switch(__x._M_index << 2 | __y._M_index) |
1802 | { |
1803 | case 0b0000: |
1804 | case 0b0101: |
1805 | return true; |
1806 | case 0b0001: |
1807 | return __x._M_it == __y._M_sent; |
1808 | case 0b0100: |
1809 | return __x._M_sent == __y._M_it; |
1810 | default: |
1811 | __glibcxx_assert(__x._M_has_value()); |
1812 | __glibcxx_assert(__y._M_has_value()); |
1813 | __builtin_unreachable(); |
1814 | } |
1815 | } |
1816 | |
1817 | template<typename _It2, sentinel_for<_It> _Sent2> |
1818 | requires sentinel_for<_Sent, _It2> && equality_comparable_with<_It, _It2> |
1819 | friend bool |
1820 | operator==(const common_iterator& __x, |
1821 | const common_iterator<_It2, _Sent2>& __y) |
1822 | { |
1823 | switch(__x._M_index << 2 | __y._M_index) |
1824 | { |
1825 | case 0b0101: |
1826 | return true; |
1827 | case 0b0000: |
1828 | return __x._M_it == __y._M_it; |
1829 | case 0b0001: |
1830 | return __x._M_it == __y._M_sent; |
1831 | case 0b0100: |
1832 | return __x._M_sent == __y._M_it; |
1833 | default: |
1834 | __glibcxx_assert(__x._M_has_value()); |
1835 | __glibcxx_assert(__y._M_has_value()); |
1836 | __builtin_unreachable(); |
1837 | } |
1838 | } |
1839 | |
1840 | template<sized_sentinel_for<_It> _It2, sized_sentinel_for<_It> _Sent2> |
1841 | requires sized_sentinel_for<_Sent, _It2> |
1842 | friend iter_difference_t<_It2> |
1843 | operator-(const common_iterator& __x, |
1844 | const common_iterator<_It2, _Sent2>& __y) |
1845 | { |
1846 | switch(__x._M_index << 2 | __y._M_index) |
1847 | { |
1848 | case 0b0101: |
1849 | return 0; |
1850 | case 0b0000: |
1851 | return __x._M_it - __y._M_it; |
1852 | case 0b0001: |
1853 | return __x._M_it - __y._M_sent; |
1854 | case 0b0100: |
1855 | return __x._M_sent - __y._M_it; |
1856 | default: |
1857 | __glibcxx_assert(__x._M_has_value()); |
1858 | __glibcxx_assert(__y._M_has_value()); |
1859 | __builtin_unreachable(); |
1860 | } |
1861 | } |
1862 | |
1863 | friend iter_rvalue_reference_t<_It> |
1864 | iter_move(const common_iterator& __i) |
1865 | noexcept(noexcept(ranges::iter_move(std::declval<const _It&>()))) |
1866 | requires input_iterator<_It> |
1867 | { |
1868 | __glibcxx_assert(__i._M_index == 0); |
1869 | return ranges::iter_move(__i._M_it); |
1870 | } |
1871 | |
1872 | template<indirectly_swappable<_It> _It2, typename _Sent2> |
1873 | friend void |
1874 | iter_swap(const common_iterator& __x, |
1875 | const common_iterator<_It2, _Sent2>& __y) |
1876 | noexcept(noexcept(ranges::iter_swap(std::declval<const _It&>(), |
1877 | std::declval<const _It2&>()))) |
1878 | { |
1879 | __glibcxx_assert(__x._M_index == 0); |
1880 | __glibcxx_assert(__y._M_index == 0); |
1881 | return ranges::iter_swap(__x._M_it, __y._M_it); |
1882 | } |
1883 | |
1884 | private: |
1885 | template<input_or_output_iterator _It2, sentinel_for<_It2> _Sent2> |
1886 | friend class common_iterator; |
1887 | |
1888 | bool _M_has_value() const noexcept { return _M_index < 2; } |
1889 | |
1890 | union |
1891 | { |
1892 | _It _M_it; |
1893 | _Sent _M_sent; |
1894 | unsigned char _M_valueless; |
1895 | }; |
1896 | unsigned char _M_index; // 0==_M_it, 1==_M_sent, 2==valueless |
1897 | }; |
1898 | |
1899 | template<typename _It, typename _Sent> |
1900 | struct incrementable_traits<common_iterator<_It, _Sent>> |
1901 | { |
1902 | using difference_type = iter_difference_t<_It>; |
1903 | }; |
1904 | |
1905 | namespace __detail |
1906 | { |
1907 | // FIXME: This has to be at namespace-scope because of PR 92103. |
1908 | template<typename _It, typename _Sent> |
1909 | struct __common_iter_ptr |
1910 | { |
1911 | using type = void; |
1912 | }; |
1913 | |
1914 | template<typename _It, typename _Sent> |
1915 | requires __detail::__common_iter_has_arrow<_It> |
1916 | struct __common_iter_ptr<_It, _Sent> |
1917 | { |
1918 | using common_iterator = std::common_iterator<_It, _Sent>; |
1919 | |
1920 | using type |
1921 | = decltype(std::declval<const common_iterator&>().operator->()); |
1922 | }; |
1923 | } // namespace __detail |
1924 | |
1925 | template<input_iterator _It, typename _Sent> |
1926 | struct iterator_traits<common_iterator<_It, _Sent>> |
1927 | { |
1928 | using iterator_concept = conditional_t<forward_iterator<_It>, |
1929 | forward_iterator_tag, input_iterator_tag>; |
1930 | using iterator_category = __detail::__clamp_iter_cat< |
1931 | typename iterator_traits<_It>::iterator_category, |
1932 | forward_iterator_tag, input_iterator_tag>; |
1933 | using value_type = iter_value_t<_It>; |
1934 | using difference_type = iter_difference_t<_It>; |
1935 | using pointer = typename __detail::__common_iter_ptr<_It, _Sent>::type; |
1936 | using reference = iter_reference_t<_It>; |
1937 | }; |
1938 | |
1939 | // [iterators.counted] Counted iterators |
1940 | |
1941 | /// An iterator adaptor that keeps track of the distance to the end. |
1942 | template<input_or_output_iterator _It> |
1943 | class counted_iterator |
1944 | { |
1945 | public: |
1946 | using iterator_type = _It; |
1947 | |
1948 | constexpr counted_iterator() = default; |
1949 | |
1950 | constexpr |
1951 | counted_iterator(_It __i, iter_difference_t<_It> __n) |
1952 | : _M_current(std::move(__i)), _M_length(__n) |
1953 | { __glibcxx_assert(__n >= 0); } |
1954 | |
1955 | template<typename _It2> |
1956 | requires convertible_to<const _It2&, _It> |
1957 | constexpr |
1958 | counted_iterator(const counted_iterator<_It2>& __x) |
1959 | : _M_current(__x._M_current), _M_length(__x._M_length) |
1960 | { } |
1961 | |
1962 | template<typename _It2> |
1963 | requires assignable_from<_It&, const _It2&> |
1964 | constexpr counted_iterator& |
1965 | operator=(const counted_iterator<_It2>& __x) |
1966 | { |
1967 | _M_current = __x._M_current; |
1968 | _M_length = __x._M_length; |
1969 | return *this; |
1970 | } |
1971 | |
1972 | constexpr _It |
1973 | base() const & |
1974 | noexcept(is_nothrow_copy_constructible_v<_It>) |
1975 | requires copy_constructible<_It> |
1976 | { return _M_current; } |
1977 | |
1978 | constexpr _It |
1979 | base() && |
1980 | noexcept(is_nothrow_move_constructible_v<_It>) |
1981 | { return std::move(_M_current); } |
1982 | |
1983 | constexpr iter_difference_t<_It> |
1984 | count() const noexcept { return _M_length; } |
1985 | |
1986 | constexpr decltype(auto) |
1987 | operator*() |
1988 | noexcept(noexcept(*_M_current)) |
1989 | { return *_M_current; } |
1990 | |
1991 | constexpr decltype(auto) |
1992 | operator*() const |
1993 | noexcept(noexcept(*_M_current)) |
1994 | requires __detail::__dereferenceable<const _It> |
1995 | { return *_M_current; } |
1996 | |
1997 | constexpr counted_iterator& |
1998 | operator++() |
1999 | { |
2000 | __glibcxx_assert(_M_length > 0); |
2001 | ++_M_current; |
2002 | --_M_length; |
2003 | return *this; |
2004 | } |
2005 | |
2006 | decltype(auto) |
2007 | operator++(int) |
2008 | { |
2009 | __glibcxx_assert(_M_length > 0); |
2010 | --_M_length; |
2011 | __trytry |
2012 | { |
2013 | return _M_current++; |
2014 | } __catch(...)catch(...) { |
2015 | ++_M_length; |
2016 | throw; |
2017 | } |
2018 | |
2019 | } |
2020 | |
2021 | constexpr counted_iterator |
2022 | operator++(int) requires forward_iterator<_It> |
2023 | { |
2024 | auto __tmp = *this; |
2025 | ++*this; |
2026 | return __tmp; |
2027 | } |
2028 | |
2029 | constexpr counted_iterator& |
2030 | operator--() requires bidirectional_iterator<_It> |
2031 | { |
2032 | --_M_current; |
2033 | ++_M_length; |
2034 | return *this; |
2035 | } |
2036 | |
2037 | constexpr counted_iterator |
2038 | operator--(int) requires bidirectional_iterator<_It> |
2039 | { |
2040 | auto __tmp = *this; |
2041 | --*this; |
2042 | return __tmp; |
2043 | } |
2044 | |
2045 | constexpr counted_iterator |
2046 | operator+(iter_difference_t<_It> __n) const |
2047 | requires random_access_iterator<_It> |
2048 | { return counted_iterator(_M_current + __n, _M_length - __n); } |
2049 | |
2050 | friend constexpr counted_iterator |
2051 | operator+(iter_difference_t<_It> __n, const counted_iterator& __x) |
2052 | requires random_access_iterator<_It> |
2053 | { return __x + __n; } |
2054 | |
2055 | constexpr counted_iterator& |
2056 | operator+=(iter_difference_t<_It> __n) |
2057 | requires random_access_iterator<_It> |
2058 | { |
2059 | __glibcxx_assert(__n <= _M_length); |
2060 | _M_current += __n; |
2061 | _M_length -= __n; |
2062 | return *this; |
2063 | } |
2064 | |
2065 | constexpr counted_iterator |
2066 | operator-(iter_difference_t<_It> __n) const |
2067 | requires random_access_iterator<_It> |
2068 | { return counted_iterator(_M_current - __n, _M_length + __n); } |
2069 | |
2070 | template<common_with<_It> _It2> |
2071 | friend constexpr iter_difference_t<_It2> |
2072 | operator-(const counted_iterator& __x, |
2073 | const counted_iterator<_It2>& __y) |
2074 | { return __y._M_length - __x._M_length; } |
2075 | |
2076 | friend constexpr iter_difference_t<_It> |
2077 | operator-(const counted_iterator& __x, default_sentinel_t) |
2078 | { return -__x._M_length; } |
2079 | |
2080 | friend constexpr iter_difference_t<_It> |
2081 | operator-(default_sentinel_t, const counted_iterator& __y) |
2082 | { return __y._M_length; } |
2083 | |
2084 | constexpr counted_iterator& |
2085 | operator-=(iter_difference_t<_It> __n) |
2086 | requires random_access_iterator<_It> |
2087 | { |
2088 | __glibcxx_assert(-__n <= _M_length); |
2089 | _M_current -= __n; |
2090 | _M_length += __n; |
2091 | return *this; |
2092 | } |
2093 | |
2094 | constexpr decltype(auto) |
2095 | operator[](iter_difference_t<_It> __n) const |
2096 | noexcept(noexcept(_M_current[__n])) |
2097 | requires random_access_iterator<_It> |
2098 | { |
2099 | __glibcxx_assert(__n < _M_length); |
2100 | return _M_current[__n]; |
2101 | } |
2102 | |
2103 | template<common_with<_It> _It2> |
2104 | friend constexpr bool |
2105 | operator==(const counted_iterator& __x, |
2106 | const counted_iterator<_It2>& __y) |
2107 | { return __x._M_length == __y._M_length; } |
2108 | |
2109 | friend constexpr bool |
2110 | operator==(const counted_iterator& __x, default_sentinel_t) |
2111 | { return __x._M_length == 0; } |
2112 | |
2113 | template<common_with<_It> _It2> |
2114 | friend constexpr strong_ordering |
2115 | operator<=>(const counted_iterator& __x, |
2116 | const counted_iterator<_It2>& __y) |
2117 | { return __y._M_length <=> __x._M_length; } |
2118 | |
2119 | friend constexpr iter_rvalue_reference_t<_It> |
2120 | iter_move(const counted_iterator& __i) |
2121 | noexcept(noexcept(ranges::iter_move(__i._M_current))) |
2122 | requires input_iterator<_It> |
2123 | { return ranges::iter_move(__i._M_current); } |
2124 | |
2125 | template<indirectly_swappable<_It> _It2> |
2126 | friend constexpr void |
2127 | iter_swap(const counted_iterator& __x, |
2128 | const counted_iterator<_It2>& __y) |
2129 | noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current))) |
2130 | { ranges::iter_swap(__x._M_current, __y._M_current); } |
2131 | |
2132 | private: |
2133 | template<input_or_output_iterator _It2> friend class counted_iterator; |
2134 | |
2135 | _It _M_current = _It(); |
2136 | iter_difference_t<_It> _M_length = 0; |
2137 | }; |
2138 | |
2139 | template<typename _It> |
2140 | struct incrementable_traits<counted_iterator<_It>> |
2141 | { |
2142 | using difference_type = iter_difference_t<_It>; |
2143 | }; |
2144 | |
2145 | template<input_iterator _It> |
2146 | struct iterator_traits<counted_iterator<_It>> : iterator_traits<_It> |
2147 | { |
2148 | using pointer = void; |
2149 | }; |
2150 | #endif // C++20 |
2151 | |
2152 | // @} group iterators |
2153 | |
2154 | template<typename _Iterator> |
2155 | auto |
2156 | __niter_base(move_iterator<_Iterator> __it) |
2157 | -> decltype(make_move_iterator(__niter_base(__it.base()))) |
2158 | { return make_move_iterator(__niter_base(__it.base())); } |
2159 | |
2160 | template<typename _Iterator> |
2161 | struct __is_move_iterator<move_iterator<_Iterator> > |
2162 | { |
2163 | enum { __value = 1 }; |
2164 | typedef __true_type __type; |
2165 | }; |
2166 | |
2167 | template<typename _Iterator> |
2168 | auto |
2169 | __miter_base(move_iterator<_Iterator> __it) |
2170 | -> decltype(__miter_base(__it.base())) |
2171 | { return __miter_base(__it.base()); } |
2172 | |
2173 | #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter)std::make_move_iterator(_Iter) std::make_move_iterator(_Iter) |
2174 | #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter)std::__make_move_if_noexcept_iterator(_Iter) \ |
2175 | std::__make_move_if_noexcept_iterator(_Iter) |
2176 | #else |
2177 | #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter)std::make_move_iterator(_Iter) (_Iter) |
2178 | #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter)std::__make_move_if_noexcept_iterator(_Iter) (_Iter) |
2179 | #endif // C++11 |
2180 | |
2181 | #if __cpp_deduction_guides201703L >= 201606 |
2182 | // These helper traits are used for deduction guides |
2183 | // of associative containers. |
2184 | template<typename _InputIterator> |
2185 | using __iter_key_t = remove_const_t< |
2186 | typename iterator_traits<_InputIterator>::value_type::first_type>; |
2187 | |
2188 | template<typename _InputIterator> |
2189 | using __iter_val_t = |
2190 | typename iterator_traits<_InputIterator>::value_type::second_type; |
2191 | |
2192 | template<typename _T1, typename _T2> |
2193 | struct pair; |
2194 | |
2195 | template<typename _InputIterator> |
2196 | using __iter_to_alloc_t = |
2197 | pair<add_const_t<__iter_key_t<_InputIterator>>, |
2198 | __iter_val_t<_InputIterator>>; |
2199 | #endif // __cpp_deduction_guides |
2200 | |
2201 | _GLIBCXX_END_NAMESPACE_VERSION |
2202 | } // namespace |
2203 | |
2204 | #ifdef _GLIBCXX_DEBUG |
2205 | # include <debug/stl_iterator.h> |
2206 | #endif |
2207 | |
2208 | #endif |