Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx
Warning:line 3101, column 18
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name unostyle.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx

/home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx

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
121using namespace css;
122using namespace css::io;
123using namespace css::lang;
124using namespace css::uno;
125
126namespace {
127
128class SwXStyle;
129class 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}
190static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries();
191
192using namespace ::com::sun::star;
193
194namespace 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
298namespace {
299
300class SwStyleBase_Impl;
301class 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
321protected:
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
337public:
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
427class SwXFrameStyle
428 : public SwXStyle
429 , public css::document::XEventsSupplier
430 , public sw::ICoreFrameStyle
431{
432public:
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
453class SwXPageStyle
454 : public SwXStyle
455{
456protected:
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
460public:
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
473using sw::XStyleFamily;
474
475OUString SwXStyleFamilies::getImplementationName()
476 { return {"SwXStyleFamilies"}; }
477
478sal_Bool SwXStyleFamilies::supportsService(const OUString& rServiceName)
479{
480 return cppu::supportsService(this, rServiceName);
481}
482
483uno::Sequence< OUString > SwXStyleFamilies::getSupportedServiceNames()
484 { return { "com.sun.star.style.StyleFamilies" }; }
485
486SwXStyleFamilies::SwXStyleFamilies(SwDocShell& rDocShell) :
487 SwUnoCollection(rDocShell.GetDoc()),
488 m_pDocShell(&rDocShell)
489 { }
490
491SwXStyleFamilies::~SwXStyleFamilies()
492 { }
493
494uno::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
507uno::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
516sal_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
523sal_Int32 SwXStyleFamilies::getCount()
524{
525 return lcl_GetStyleFamilyEntries()->size();
526}
527
528uno::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
544uno::Type SwXStyleFamilies::getElementType()
545{
546 return cppu::UnoType<container::XNameContainer>::get();
547}
548
549sal_Bool SwXStyleFamilies::hasElements()
550 { return true; }
551
552void 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
597uno::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
611static 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
628template<enum SfxStyleFamily>
629static sal_Int32 lcl_GetCountOrName(const SwDoc&, OUString*, sal_Int32);
630
631template<>
632sal_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
657template<>
658sal_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
679template<>
680sal_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
700template<>
701sal_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
722template<>
723sal_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
743template<>
744sal_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
757template<>
758sal_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
780template<SfxStyleFamily eFamily>
781static 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
784template<>
785uno::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); };
787template<>
788uno::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
791template<>
792uno::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
795template<>
796uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Table>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
797 { return SwXTextTableStyle::CreateXTextTableStyle(pDocShell, sStyleName); };
798
799template<>
800uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Cell>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
801 { return SwXTextCellStyle::CreateXTextCellStyle(pDocShell, sStyleName); };
802
803uno::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.
812uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyleCondParagraph(SwDoc& rDoc)
813 { return new SwXStyle(&rDoc, SfxStyleFamily::Para, true); };
814
815template<enum SfxStyleFamily>
816static sal_uInt16 lcl_TranslateIndex(const sal_uInt16 nIndex);
817
818template<>
819sal_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
829template<>
830sal_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
848template<>
849sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Table>(const sal_uInt16 nIndex)
850{
851 return nIndex;
852}
853
854template<>
855sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Cell>(const sal_uInt16 nIndex)
856{
857 return nIndex;
858}
859
860template<sal_uInt16 nRangeBegin, sal_uInt16 nRangeSize>
861static sal_uInt16 lcl_TranslateIndexRange(const sal_uInt16 nIndex)
862{
863 if(nIndex < nRangeSize)
864 return nIndex + nRangeBegin;
865 throw lang::IndexOutOfBoundsException();
866}
867
868uno::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
887uno::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
903uno::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
919sal_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
930void 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
999void 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
1060void 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
1084uno::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
1093SwXStyle* 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
1106static 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
1123static 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
1139namespace {
1140
1141class SwStyleProperties_Impl
1142{
1143 const PropertyEntryVector_t aPropertyEntries;
1144 std::map<OUString, uno::Any> m_vPropertyValues;
1145public:
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(),
11
Calling 'any_of<__gnu_cxx::__normal_iterator<const SfxItemPropertyNamedEntry *, std::vector<SfxItemPropertyNamedEntry, std::allocator<SfxItemPropertyNamedEntry>>>, (lambda at /home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx:1153:13)>'
20
Returning from 'any_of<__gnu_cxx::__normal_iterator<const SfxItemPropertyNamedEntry *, std::vector<SfxItemPropertyNamedEntry, std::allocator<SfxItemPropertyNamedEntry>>>, (lambda at /home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx:1153:13)>'
21
Returning zero, which participates in a condition later
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))
10
Calling 'SwStyleProperties_Impl::AllowsKey'
22
Returning from 'SwStyleProperties_Impl::AllowsKey'
23
Taking true branch
1165 {
1166 pAny = nullptr;
24
Null pointer value stored to 'pAny'
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
1197static 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
1208namespace
1209{
1210 class theSwXStyleUnoTunnelId : public rtl::Static<UnoTunnelIdInit, theSwXStyleUnoTunnelId> {};
1211}
1212
1213const uno::Sequence<sal_Int8>& SwXStyle::getUnoTunnelId()
1214{
1215 return theSwXStyleUnoTunnelId::get().getSeq();
1216}
1217
1218sal_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
1228uno::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
1271static 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
1282static 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
1298static 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
1312static 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
1321SwXStyle::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
1337SwXStyle::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
1346SwXStyle::~SwXStyle()
1347{
1348 SolarMutexGuard aGuard;
1349 if(m_pBasePool)
1350 SfxListener::EndListening(*m_pBasePool);
1351 m_pPropertiesImpl.reset();
1352 SvtListener::EndListeningAll();
1353}
1354
1355void 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
1365OUString 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
1379void 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
1397sal_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
1407sal_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
1416OUString 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
1433void 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
1465uno::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
1477void SwXStyle::ApplyDescriptorProperties()
1478{
1479 m_bIsDescriptor = false;
1480 m_xStyleData.clear();
1481 m_xStyleFamily.clear();
1482 m_pPropertiesImpl->Apply(*this);
1483}
1484
1485namespace {
1486
1487class SwStyleBase_Impl
1488{
1489private:
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;
1497public:
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
1568const 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
1593static 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}
1613template<>
1614void 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}
1623template<>
1624void 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}
1635template<>
1636void 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}
1642template<>
1643void 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}
1669template<>
1670void 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}
1688template<>
1689void 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}
1702template<>
1703void 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}
1732template<>
1733void 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}
1783template<>
1784void 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}
1792template<>
1793void 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}
1802template<>
1803void 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}
1839template<>
1840void 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}
1853template<>
1854void 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}
1864template<>
1865void 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}
1900template<>
1901void 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}
1918template<>
1919void 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}
1930template<>
1931void 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}
1957template<>
1958void 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}
1986template<>
1987void 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
2005void 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
2050void 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
2091void 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
2109SfxStyleSheetBase* 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}
2116void 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
2125template<>
2126uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
2127template<>
2128uno::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}
2141template<>
2142uno::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}
2150template<>
2151uno::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}
2161template<>
2162uno::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}
2176template<>
2177uno::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}
2185template<>
2186uno::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}
2192template<>
2193uno::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}
2200template<>
2201uno::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}
2217template<>
2218uno::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}
2228template<>
2229uno::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}
2234template<>
2235uno::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}
2264template<>
2265uno::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}
2282template<>
2283uno::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}
2296template<>
2297uno::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}
2307template<>
2308uno::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}
2318template<>
2319uno::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
2345uno::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
2377uno::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
2420uno::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
2433uno::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
2465void 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
2473beans::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)
2483static 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}
2495uno::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
2590void SwXStyle::setPropertyToDefault(const OUString& rPropertyName)
2591{
2592 const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
2593 setPropertiesToDefault(aSequence);
2594}
2595
2596static 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
2617void 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
2663void 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
2744uno::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
2784uno::Any SwXStyle::getPropertyDefault(const OUString& rPropertyName)
2785{
2786 const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
2787 return getPropertyDefaults(aSequence)[0];
2788}
2789
2790void 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
2809void 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
2818SwXPageStyle::SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName)
2819 : SwXStyle(&rPool, SfxStyleFamily::Page, pDocSh->GetDoc(), rStyleName)
2820{ }
2821
2822SwXPageStyle::SwXPageStyle(SwDocShell* pDocSh)
2823 : SwXStyle(pDocSh->GetDoc(), SfxStyleFamily::Page)
2824{ }
2825
2826void 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
2849void 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
3051void 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
3070static 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
3086uno::Sequence<uno::Any> SwXPageStyle::GetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames)
3087{
3088 if(!GetDoc())
1
Assuming the condition is false
2
Taking false branch
3089 throw uno::RuntimeException();
3090
3091 sal_Int32 nLength = rPropertyNames.getLength();
3092 uno::Sequence<uno::Any> aRet (nLength);
3093 if(!m_pBasePool)
3
Assuming field 'm_pBasePool' is null
4
Taking true branch
3094 {
3095 if(!IsDescriptor())
5
Assuming the condition is false
6
Taking false branch
3096 throw uno::RuntimeException();
3097 for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
3098 {
3099 const uno::Any* pAny = nullptr;
3100 m_pPropertiesImpl->GetProperty(rPropertyNames[nProp], pAny);
9
Calling 'SwStyleProperties_Impl::GetProperty'
25
Returning from 'SwStyleProperties_Impl::GetProperty'
3101 if (!pAny->hasValue())
26
Called C++ object pointer is null
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
3275uno::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
3301uno::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
3308void 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
3316SwXFrameStyle::SwXFrameStyle(SwDoc *pDoc)
3317 : SwXStyle(pDoc, SfxStyleFamily::Frame, false)
3318{ }
3319
3320void 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
3333const 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
3343uno::Sequence<uno::Type> SwXFrameStyle::getTypes()
3344{
3345 return cppu::OTypeCollection(
3346 cppu::UnoType<XEventsSupplier>::get(),
3347 SwXStyle::getTypes()
3348 ).getTypes();
3349}
3350
3351uno::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
3358uno::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
3365const IStyleAccess::SwAutoStyleFamily aAutoStyleByIndex[] =
3366{
3367 IStyleAccess::AUTO_STYLE_CHAR,
3368 IStyleAccess::AUTO_STYLE_RUBY,
3369 IStyleAccess::AUTO_STYLE_PARA
3370};
3371
3372class 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;
3378public:
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
3386SwXAutoStyles::SwXAutoStyles(SwDocShell& rDocShell) :
3387 SwUnoCollection(rDocShell.GetDoc()), m_pDocShell( &rDocShell )
3388{
3389}
3390
3391SwXAutoStyles::~SwXAutoStyles()
3392{
3393}
3394
3395sal_Int32 SwXAutoStyles::getCount()
3396{
3397 return AUTOSTYLE_FAMILY_COUNT3;
3398}
3399
3400uno::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
3443uno::Type SwXAutoStyles::getElementType( )
3444{
3445 return cppu::UnoType<style::XAutoStyleFamily>::get();
3446}
3447
3448sal_Bool SwXAutoStyles::hasElements( )
3449{
3450 return true;
3451}
3452
3453uno::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
3467uno::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
3477sal_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
3487SwXAutoStyleFamily::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
3494SwXAutoStyleFamily::~SwXAutoStyleFamily()
3495{
3496}
3497
3498void SwXAutoStyleFamily::Notify(const SfxHint& rHint)
3499{
3500 if(rHint.GetId() == SfxHintId::Dying)
3501 m_pDocShell = nullptr;
3502}
3503
3504uno::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
3730uno::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
3738uno::Type SwXAutoStyleFamily::getElementType( )
3739{
3740 return cppu::UnoType<style::XAutoStyle>::get();
3741}
3742
3743sal_Bool SwXAutoStyleFamily::hasElements( )
3744{
3745 return false;
3746}
3747
3748SwAutoStylesEnumImpl::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
3784SwXAutoStylesEnumerator::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
3791SwXAutoStylesEnumerator::~SwXAutoStylesEnumerator()
3792{
3793}
3794
3795void SwXAutoStylesEnumerator::Notify( const SfxHint& rHint)
3796{
3797 if(rHint.GetId() == SfxHintId::Dying)
3798 m_pImpl.reset();
3799}
3800
3801sal_Bool SwXAutoStylesEnumerator::hasMoreElements( )
3802{
3803 if( !m_pImpl )
3804 throw uno::RuntimeException();
3805 return m_pImpl->hasMoreElements();
3806}
3807
3808uno::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
3830SwXAutoStyle::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
3842SwXAutoStyle::~SwXAutoStyle()
3843{
3844}
3845
3846void SwXAutoStyle::Notify(const SfxHint& rHint)
3847{
3848 if(rHint.GetId() == SfxHintId::Dying)
3849 mpSet.reset();
3850}
3851
3852uno::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
3897void SwXAutoStyle::setPropertyValue( const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
3898{
3899}
3900
3901uno::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
3908void SwXAutoStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/,
3909 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
3910{
3911}
3912
3913void SwXAutoStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/,
3914 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
3915{
3916}
3917
3918void SwXAutoStyle::addVetoableChangeListener( const OUString& /*PropertyName*/,
3919 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
3920{
3921}
3922
3923void SwXAutoStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/,
3924 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
3925{
3926}
3927
3928void SwXAutoStyle::setPropertyValues(
3929 const uno::Sequence< OUString >& /*aPropertyNames*/,
3930 const uno::Sequence< uno::Any >& /*aValues*/ )
3931{
3932}
3933
3934uno::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
4071uno::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
4096void SwXAutoStyle::addPropertiesChangeListener(
4097 const uno::Sequence< OUString >& /*aPropertyNames*/,
4098 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
4099{
4100}
4101
4102void SwXAutoStyle::removePropertiesChangeListener(
4103 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
4104{
4105}
4106
4107void SwXAutoStyle::firePropertiesChangeEvent(
4108 const uno::Sequence< OUString >& /*aPropertyNames*/,
4109 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
4110{
4111}
4112
4113beans::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
4122void SwXAutoStyle::setPropertyToDefault( const OUString& /*PropertyName*/ )
4123{
4124}
4125
4126uno::Any SwXAutoStyle::getPropertyDefault( const OUString& rPropertyName )
4127{
4128 const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
4129 return getPropertyDefaults ( aSequence ).getConstArray()[0];
4130}
4131
4132uno::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
4216void SwXAutoStyle::setAllPropertiesToDefault( )
4217{
4218}
4219
4220void SwXAutoStyle::setPropertiesToDefault(
4221 const uno::Sequence< OUString >& /*rPropertyNames*/ )
4222{
4223}
4224
4225uno::Sequence< uno::Any > SwXAutoStyle::getPropertyDefaults(
4226 const uno::Sequence< OUString >& /*aPropertyNames*/ )
4227{
4228 uno::Sequence< uno::Any > aRet(0);
4229 return aRet;
4230}
4231
4232uno::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
4285SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, SwTableAutoFormat* pTableAutoFormat) :
4286 m_pDocShell(pDocShell), m_pTableAutoFormat(pTableAutoFormat), m_bPhysical(true)
4287{
4288 UpdateCellStylesMapping();
4289}
4290
4291SwXTextTableStyle::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
4298uno::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
4323void 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
4340const 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
4365SwTableAutoFormat* SwXTextTableStyle::GetTableFormat()
4366{
4367 return m_pTableAutoFormat;
4368}
4369
4370SwTableAutoFormat* 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
4385void 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
4419sal_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
4429sal_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
4450OUString SAL_CALL SwXTextTableStyle::getParentStyle()
4451{
4452 return OUString();
4453}
4454
4455void SAL_CALL SwXTextTableStyle::setParentStyle(const OUString& /*aParentStyle*/)
4456{ }
4457
4458//XNamed
4459OUString 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
4467void SAL_CALL SwXTextTableStyle::setName(const OUString& rName)
4468{
4469 SolarMutexGuard aGuard;
4470 m_pTableAutoFormat->SetName(rName);
4471}
4472
4473//XPropertySet
4474css::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
4480void 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
4485css::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
4506void 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
4511void 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
4516void 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
4521void 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
4527uno::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
4538css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getElementNames()
4539{
4540 SolarMutexGuard aGuard;
4541 return comphelper::mapKeysToSequence(GetCellStyleNameMap());
4542}
4543
4544sal_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
4553void 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
4558void 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
4593void 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
4599uno::Type SAL_CALL SAL_CALL SwXTextTableStyle::getElementType()
4600{
4601 return cppu::UnoType<style::XStyle>::get();
4602}
4603
4604sal_Bool SAL_CALL SAL_CALL SwXTextTableStyle::hasElements()
4605{
4606 return true;
4607}
4608
4609//XServiceInfo
4610OUString SAL_CALL SwXTextTableStyle::getImplementationName()
4611{
4612 return {"SwXTextTableStyle"};
4613}
4614
4615sal_Bool SAL_CALL SwXTextTableStyle::supportsService(const OUString& rServiceName)
4616{
4617 return cppu::supportsService(this, rServiceName);
4618}
4619
4620css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getSupportedServiceNames()
4621{
4622 return {"com.sun.star.style.Style"};
4623}
4624
4625// SwXTextCellStyle
4626SwXTextCellStyle::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
4633SwXTextCellStyle::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
4642SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat()
4643{
4644 return m_pBoxAutoFormat;
4645}
4646
4647void 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
4655void 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
4674bool SwXTextCellStyle::IsPhysical() const
4675{
4676 return m_bPhysical;
4677}
4678
4679SwBoxAutoFormat* 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
4718css::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
4749sal_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
4759sal_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
4783OUString 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
4789void 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
4797OUString 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
4824void 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
4835css::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
4841void 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
5030css::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
5194void 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
5199void 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
5204void 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
5209void 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
5215css::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
5223css::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
5373void 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
5574css::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
5582OUString SAL_CALL SwXTextCellStyle::getImplementationName()
5583{
5584 return {"SwXTextCellStyle"};
5585}
5586
5587sal_Bool SAL_CALL SwXTextCellStyle::supportsService(const OUString& rServiceName)
5588{
5589 return cppu::supportsService(this, rServiceName);
5590}
5591
5592css::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: */

/usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_algo.h

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
71namespace 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); }
13
Calling 'operator==<const SfxItemPropertyNamedEntry *, std::vector<SfxItemPropertyNamedEntry, std::allocator<SfxItemPropertyNamedEntry>>>'
16
Returning from 'operator==<const SfxItemPropertyNamedEntry *, std::vector<SfxItemPropertyNamedEntry, std::allocator<SfxItemPropertyNamedEntry>>>'
17
Returning the value 1, which participates in a condition later
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); }
12
Calling 'none_of<__gnu_cxx::__normal_iterator<const SfxItemPropertyNamedEntry *, std::vector<SfxItemPropertyNamedEntry, std::allocator<SfxItemPropertyNamedEntry>>>, (lambda at /home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx:1153:13)>'
18
Returning from 'none_of<__gnu_cxx::__normal_iterator<const SfxItemPropertyNamedEntry *, std::vector<SfxItemPropertyNamedEntry, std::allocator<SfxItemPropertyNamedEntry>>>, (lambda at /home/maarten/src/libreoffice/core/sw/source/core/unocore/unostyle.cxx:1153:13)>'
19
Returning zero, which participates in a condition later
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 */

/usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/stl_iterator.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
85namespace 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
918namespace __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(); }
14
Assuming the condition is true
15
Returning the value 1, which participates in a condition later
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
1193namespace 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