File: | home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx |
Warning: | line 3101, column 18 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 && rPropertyName == UNO_NAME_PARA_STYLE_CONDITIONS"ParaStyleConditions")) | |||
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 |