Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx
Warning:line 358, column 34
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 ssfrm.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/layout/ssfrm.cxx

/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.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 <pagefrm.hxx>
21#include <rootfrm.hxx>
22#include <dcontact.hxx>
23#include <flyfrm.hxx>
24#include <txtfrm.hxx>
25#include <cellfrm.hxx>
26#include <swtable.hxx>
27#include <fmtfsize.hxx>
28#include <editeng/boxitem.hxx>
29#include <editeng/shaditem.hxx>
30#include <IDocumentRedlineAccess.hxx>
31#include <fmtclds.hxx>
32#include <viewimp.hxx>
33#include <sortedobjs.hxx>
34#include <hints.hxx>
35#include <frmtool.hxx>
36#include <ndtxt.hxx>
37
38 // No inline cause we need the function pointers
39long SwFrame::GetTopMargin() const
40 { return getFramePrintArea().Top(); }
41long SwFrame::GetBottomMargin() const
42 { return getFrameArea().Height() -getFramePrintArea().Height() -getFramePrintArea().Top(); }
43long SwFrame::GetLeftMargin() const
44 { return getFramePrintArea().Left(); }
45long SwFrame::GetRightMargin() const
46 { return getFrameArea().Width() - getFramePrintArea().Width() - getFramePrintArea().Left(); }
47long SwFrame::GetPrtLeft() const
48 { return getFrameArea().Left() + getFramePrintArea().Left(); }
49long SwFrame::GetPrtBottom() const
50 { return getFrameArea().Top() + getFramePrintArea().Height() + getFramePrintArea().Top(); }
51long SwFrame::GetPrtRight() const
52 { return getFrameArea().Left() + getFramePrintArea().Width() + getFramePrintArea().Left(); }
53long SwFrame::GetPrtTop() const
54 { return getFrameArea().Top() + getFramePrintArea().Top(); }
55
56bool SwFrame::SetMinLeft( long nDeadline )
57{
58 SwTwips nDiff = nDeadline - getFrameArea().Left();
59 if( nDiff > 0 )
60 {
61 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
62 aFrm.Left( nDeadline );
63
64 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
65 aPrt.Width( aPrt.Width() - nDiff );
66
67 return true;
68 }
69 return false;
70}
71
72bool SwFrame::SetMaxBottom( long nDeadline )
73{
74 SwTwips nDiff = getFrameArea().Top() + getFrameArea().Height() - nDeadline;
75 if( nDiff > 0 )
76 {
77 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
78 aFrm.Height( aFrm.Height() - nDiff );
79
80 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
81 aPrt.Height( aPrt.Height() - nDiff );
82
83 return true;
84 }
85 return false;
86}
87
88bool SwFrame::SetMaxRight( long nDeadline )
89{
90 SwTwips nDiff = getFrameArea().Left() + getFrameArea().Width() - nDeadline;
91 if( nDiff > 0 )
92 {
93 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
94 aFrm.Width( aFrm.Width() - nDiff );
95
96 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
97 aPrt.Width( aPrt.Width() - nDiff );
98
99 return true;
100 }
101 return false;
102}
103
104void SwFrame::MakeBelowPos( const SwFrame* pUp, const SwFrame* pPrv, bool bNotify )
105{
106 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
107
108 if( pPrv )
109 {
110 aFrm.Pos( pPrv->getFrameArea().Pos() );
111 aFrm.Pos().AdjustY(pPrv->getFrameArea().Height() );
112 }
113 else
114 {
115 aFrm.Pos( pUp->getFrameArea().Pos() );
116 aFrm.Pos() += pUp->getFramePrintArea().Pos();
117 }
118
119 if( bNotify )
120 {
121 aFrm.Pos().AdjustY(1 );
122 }
123}
124
125void SwFrame::MakeLeftPos( const SwFrame* pUp, const SwFrame* pPrv, bool bNotify )
126{
127 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
128
129 if( pPrv )
130 {
131 aFrm.Pos( pPrv->getFrameArea().Pos() );
132 aFrm.Pos().AdjustX( -(aFrm.Width()) );
133 }
134 else
135 {
136 aFrm.Pos( pUp->getFrameArea().Pos() );
137 aFrm.Pos() += pUp->getFramePrintArea().Pos();
138 aFrm.Pos().AdjustX(pUp->getFramePrintArea().Width() - aFrm.Width() );
139 }
140
141 if( bNotify )
142 {
143 aFrm.Pos().AdjustX( -1 );
144 }
145}
146
147void SwFrame::MakeRightPos( const SwFrame* pUp, const SwFrame* pPrv, bool bNotify )
148{
149 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
150
151 if( pPrv )
152 {
153 aFrm.Pos( pPrv->getFrameArea().Pos() );
154 aFrm.Pos().AdjustX(pPrv->getFrameArea().Width() );
155 }
156 else
157 {
158 aFrm.Pos( pUp->getFrameArea().Pos() );
159 aFrm.Pos() += pUp->getFramePrintArea().Pos();
160 }
161
162 if( bNotify )
163 {
164 aFrm.Pos().AdjustX(1 );
165 }
166}
167
168void SwFrame::SetTopBottomMargins( long nTop, long nBot )
169{
170 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
171 aPrt.Top( nTop );
172 aPrt.Height( getFrameArea().Height() - nTop - nBot );
173}
174
175void SwFrame::SetLeftRightMargins( long nLeft, long nRight)
176{
177 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
178 aPrt.Left( nLeft );
179 aPrt.Width( getFrameArea().Width() - nLeft - nRight );
180}
181
182void SwFrame::SetRightLeftMargins( long nRight, long nLeft)
183{
184 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
185 aPrt.Left( nLeft );
186 aPrt.Width( getFrameArea().Width() - nLeft - nRight );
187}
188
189/// checks the layout direction and invalidates the lower frames recursively, if necessary.
190void SwFrame::CheckDirChange()
191{
192 bool bOldVert = mbVertical;
193 bool bOldR2L = mbRightToLeft;
194 SetInvalidVert( true );
195 mbInvalidR2L = true;
196 bool bChg = bOldR2L != IsRightToLeft();
197 bool bOldVertL2R = IsVertLR();
198 if( !(( IsVertical() != bOldVert ) || bChg || bOldVertL2R != IsVertLR()) )
199 return;
200
201 InvalidateAll();
202 if( IsLayoutFrame() )
203 {
204 // set minimum row height for vertical cells in horizontal table:
205 if ( IsCellFrame() && GetUpper() )
206 {
207 if ( IsVertical() != GetUpper()->IsVertical() &&
208 static_cast<SwCellFrame*>(this)->GetTabBox()->getRowSpan() == 1 )
209 {
210 enum {
211 MIN_VERT_CELL_HEIGHT = 1135
212 };
213
214 SwTableLine* pLine = const_cast<SwTableLine*>(static_cast<SwCellFrame*>(this)->GetTabBox()->GetUpper());
215 SwFrameFormat* pFrameFormat = pLine->GetFrameFormat();
216 SwFormatFrameSize aNew( pFrameFormat->GetFrameSize() );
217 if ( SwFrameSize::Fixed != aNew.GetHeightSizeType() )
218 aNew.SetHeightSizeType( SwFrameSize::Minimum );
219 if ( aNew.GetHeight() < MIN_VERT_CELL_HEIGHT )
220 aNew.SetHeight( MIN_VERT_CELL_HEIGHT );
221 SwDoc* pDoc = pFrameFormat->GetDoc();
222 pDoc->SetAttr( aNew, *pLine->ClaimFrameFormat() );
223 }
224 }
225
226 SwFrame* pFrame = static_cast<SwLayoutFrame*>(this)->Lower();
227 const SwFormatCol* pCol = nullptr;
228 SwLayoutFrame* pBody = nullptr;
229 if( pFrame )
230 {
231 if( IsPageFrame() )
232 {
233 // If we're a page frame and we change our layout direction,
234 // we have to look for columns and rearrange them.
235 pBody = static_cast<SwPageFrame*>(this)->FindBodyCont();
236 if(pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame())
237 pCol = &static_cast<SwPageFrame*>(this)->GetFormat()->GetCol();
238 }
239 else if( pFrame->IsColumnFrame() )
240 {
241 pBody = static_cast<SwLayoutFrame*>(this);
242 const SwFrameFormat *pFormat = pBody->GetFormat();
243 if( pFormat )
244 pCol = &pFormat->GetCol();
245 }
246 }
247 while( pFrame )
248 {
249 pFrame->CheckDirChange();
250 pFrame = pFrame->GetNext();
251 }
252 if( pCol )
253 pBody->AdjustColumns( pCol, true );
254 }
255 else if( IsTextFrame() )
256 static_cast<SwTextFrame*>(this)->Prepare();
257
258 // #i31698# - notify anchored objects also for page frames.
259 // Remove code above for special handling of page frames
260 if ( !GetDrawObjs() )
261 return;
262
263 const SwSortedObjs *pObjs = GetDrawObjs();
264 const size_t nCnt = pObjs->size();
265 for ( size_t i = 0; i < nCnt; ++i )
266 {
267 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
268 if( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
269 static_cast<SwFlyFrame*>(pAnchoredObj)->CheckDirChange();
270 else
271 {
272 // OD 2004-04-06 #i26791# - direct object
273 // positioning no longer needed. Instead
274 // invalidate
275 pAnchoredObj->InvalidateObjPos();
276 }
277 // #i31698# - update layout direction of
278 // anchored object
279 {
280 ::setContextWritingMode( pAnchoredObj->DrawObj(), pAnchoredObj->GetAnchorFrameContainingAnchPos() );
281 pAnchoredObj->UpdateLayoutDir();
282 }
283 }
284}
285
286/// returns the position for anchors based on frame direction
287// OD 2004-03-10 #i11860# - consider lower space and line spacing of
288// previous frame according to new option 'Use former object positioning'
289Point SwFrame::GetFrameAnchorPos( bool bIgnoreFlysAnchoredAtThisFrame ) const
290{
291 Point aAnchor = getFrameArea().Pos();
292
293 if ( ( IsVertical() && !IsVertLR() ) || IsRightToLeft() )
294 aAnchor.AdjustX(getFrameArea().Width() );
295
296 if ( IsTextFrame() )
297 {
298 SwTwips nBaseOfstForFly =
299 static_cast<const SwTextFrame*>(this)->GetBaseOffsetForFly( bIgnoreFlysAnchoredAtThisFrame );
300 if ( IsVertical() )
301 aAnchor.AdjustY(nBaseOfstForFly );
302 else
303 aAnchor.AdjustX(nBaseOfstForFly );
304
305 // OD 2004-03-10 #i11860# - if option 'Use former object positioning'
306 // is OFF, consider the lower space and the line spacing of the
307 // previous frame and the spacing considered for the page grid
308 const SwTextFrame* pThisTextFrame = static_cast<const SwTextFrame*>(this);
309 const SwTwips nUpperSpaceAmountConsideredForPrevFrameAndPageGrid =
310 pThisTextFrame->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
311 if ( IsVertical() )
312 {
313 aAnchor.AdjustX( -nUpperSpaceAmountConsideredForPrevFrameAndPageGrid );
314 }
315 else
316 {
317 aAnchor.AdjustY(nUpperSpaceAmountConsideredForPrevFrameAndPageGrid );
318 }
319 }
320
321 return aAnchor;
322}
323
324void SwFrame::DestroyImpl()
325{
326 mbInDtor = true;
327
328 // accessible objects for fly and cell frames have been already disposed
329 // by the destructors of the derived classes.
330 if (IsAccessibleFrame() && !(IsFlyFrame() || IsCellFrame())
8
Calling 'SwFrame::IsAccessibleFrame'
14
Returning from 'SwFrame::IsAccessibleFrame'
331 && (GetDep() || IsTextFrame())) // sw_redlinehide: text frame may not have Dep!
332 {
333 assert(!IsTextFrame() || GetDep() || static_cast<SwTextFrame*>(this)->GetMergedPara())(static_cast <bool> (!IsTextFrame() || GetDep() || static_cast
<SwTextFrame*>(this)->GetMergedPara()) ? void (0) : __assert_fail
("!IsTextFrame() || GetDep() || static_cast<SwTextFrame*>(this)->GetMergedPara()"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 333, __extension__ __PRETTY_FUNCTION__))
;
334 SwRootFrame *pRootFrame = getRootFrame();
335 if( pRootFrame && pRootFrame->IsAnyShellAccessible() )
336 {
337 SwViewShell *pVSh = pRootFrame->GetCurrShell();
338 if( pVSh && pVSh->Imp() )
339 {
340 OSL_ENSURE( !GetLower(), "Lowers should be dispose already!" )do { if (true && (!(!GetLower()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "340" ": "), "%s", "Lowers should be dispose already!");
} } while (false)
;
341 pVSh->Imp()->DisposeAccessibleFrame( this );
342 }
343 }
344 }
345
346 if (!m_pDrawObjs)
15
Calling 'unique_ptr::operator bool'
19
Returning from 'unique_ptr::operator bool'
20
Taking false branch
347 return;
348
349 for (size_t i = m_pDrawObjs->size(); i; )
21
Loop condition is true. Entering loop body
350 {
351 SwAnchoredObject* pAnchoredObj = (*m_pDrawObjs)[--i];
22
'pAnchoredObj' initialized here
352 if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
23
Assuming pointer value is null
24
Taking false branch
353 {
354 SwFrame::DestroyFrame(static_cast<SwFlyFrame*>(pAnchoredObj));
355 }
356 else
357 {
358 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
25
Called C++ object pointer is null
359 SwDrawContact* pContact =
360 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
361 OSL_ENSURE( pContact,do { if (true && (!(pContact))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "362" ": "), "%s", "<SwFrame::~SwFrame> - missing contact for drawing object"
); } } while (false)
362 "<SwFrame::~SwFrame> - missing contact for drawing object" )do { if (true && (!(pContact))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "362" ": "), "%s", "<SwFrame::~SwFrame> - missing contact for drawing object"
); } } while (false)
;
363 if ( pContact )
364 {
365 pContact->DisconnectObjFromLayout( pSdrObj );
366 }
367 }
368 }
369 m_pDrawObjs.reset();
370}
371
372SwFrame::~SwFrame()
373{
374 assert(m_isInDestroy)(static_cast <bool> (m_isInDestroy) ? void (0) : __assert_fail
("m_isInDestroy", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 374, __extension__ __PRETTY_FUNCTION__))
; // check that only DestroySwFrame does "delete"
375 assert(!IsDeleteForbidden())(static_cast <bool> (!IsDeleteForbidden()) ? void (0) :
__assert_fail ("!IsDeleteForbidden()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // check that it's not deleted while deletes are forbidden
376#if OSL_DEBUG_LEVEL1 > 0
377 // JP 15.10.2001: for detection of access to deleted frames
378 mpRoot = reinterpret_cast<SwRootFrame*>(0x33333333);
379#endif
380}
381
382void SwFrame::DestroyFrame(SwFrame *const pFrame)
383{
384 if (pFrame)
385 {
386 pFrame->m_isInDestroy = true;
387 pFrame->DestroyImpl();
388 assert(pFrame->mbInDtor)(static_cast <bool> (pFrame->mbInDtor) ? void (0) : __assert_fail
("pFrame->mbInDtor", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 388, __extension__ __PRETTY_FUNCTION__))
; // check that nobody forgot to call base class
389 delete pFrame;
390 }
391}
392
393const SwFrameFormat * SwLayoutFrame::GetFormat() const
394{
395 return static_cast< const SwFrameFormat * >( GetDep() );
396}
397
398SwFrameFormat * SwLayoutFrame::GetFormat()
399{
400 return static_cast< SwFrameFormat * >( GetDep() );
401}
402
403void SwLayoutFrame::SetFrameFormat( SwFrameFormat *pNew )
404{
405 if ( pNew != GetFormat() )
406 {
407 SwFormatChg aOldFormat( GetFormat() );
408 pNew->Add( this );
409 SwFormatChg aNewFormat( pNew );
410 ModifyNotification( &aOldFormat, &aNewFormat );
411 }
412}
413
414SwContentFrame::SwContentFrame( SwContentNode * const pContent, SwFrame* pSib ) :
415 SwFrame( pContent, pSib ),
416 SwFlowFrame( static_cast<SwFrame&>(*this) )
417{
418 assert(!getRootFrame()->IsHideRedlines() || pContent->IsCreateFrameWhenHidingRedlines())(static_cast <bool> (!getRootFrame()->IsHideRedlines
() || pContent->IsCreateFrameWhenHidingRedlines()) ? void (
0) : __assert_fail ("!getRootFrame()->IsHideRedlines() || pContent->IsCreateFrameWhenHidingRedlines()"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 418, __extension__ __PRETTY_FUNCTION__))
;
419}
420
421void SwContentFrame::DestroyImpl()
422{
423 const SwContentNode* pCNd(dynamic_cast<SwContentNode*>(GetDep()));
424 if (nullptr == pCNd && IsTextFrame())
425 {
426 pCNd = static_cast<SwTextFrame*>(this)->GetTextNodeFirst();
427 }
428 // IsInDtor shouldn't be happening with ViewShell owning layout
429 assert(nullptr == pCNd || !pCNd->GetDoc().IsInDtor())(static_cast <bool> (nullptr == pCNd || !pCNd->GetDoc
().IsInDtor()) ? void (0) : __assert_fail ("nullptr == pCNd || !pCNd->GetDoc().IsInDtor()"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 429, __extension__ __PRETTY_FUNCTION__))
;
430 if (nullptr != pCNd && !pCNd->GetDoc().IsInDtor())
431 {
432 //Unregister from root if I'm still in turbo there.
433 SwRootFrame *pRoot = getRootFrame();
434 if( pRoot && pRoot->GetTurbo() == this )
435 {
436 pRoot->DisallowTurbo();
437 pRoot->ResetTurbo();
438 }
439 }
440
441 SwFrame::DestroyImpl();
442}
443
444SwContentFrame::~SwContentFrame()
445{
446}
447
448void SwTextFrame::RegisterToNode(SwTextNode & rNode, bool const isForceNodeAsFirst)
449{
450 if (isForceNodeAsFirst && m_pMergedPara)
451 { // nothing registered here, in particular no delete redlines (insert
452 // redline might end on empty node where delete rl starts, should be ok)
453 assert(m_pMergedPara->pFirstNode->GetIndex() + 1 == rNode.GetIndex())(static_cast <bool> (m_pMergedPara->pFirstNode->GetIndex
() + 1 == rNode.GetIndex()) ? void (0) : __assert_fail ("m_pMergedPara->pFirstNode->GetIndex() + 1 == rNode.GetIndex()"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 453, __extension__ __PRETTY_FUNCTION__))
;
454 assert(rNode.GetDoc().getIDocumentRedlineAccess().GetRedlinePos((static_cast <bool> (rNode.GetDoc().getIDocumentRedlineAccess
().GetRedlinePos( *m_pMergedPara->pFirstNode, RedlineType::
Delete) == SwRedlineTable::npos) ? void (0) : __assert_fail (
"rNode.GetDoc().getIDocumentRedlineAccess().GetRedlinePos( *m_pMergedPara->pFirstNode, RedlineType::Delete) == SwRedlineTable::npos"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 455, __extension__ __PRETTY_FUNCTION__))
455 *m_pMergedPara->pFirstNode, RedlineType::Delete) == SwRedlineTable::npos)(static_cast <bool> (rNode.GetDoc().getIDocumentRedlineAccess
().GetRedlinePos( *m_pMergedPara->pFirstNode, RedlineType::
Delete) == SwRedlineTable::npos) ? void (0) : __assert_fail (
"rNode.GetDoc().getIDocumentRedlineAccess().GetRedlinePos( *m_pMergedPara->pFirstNode, RedlineType::Delete) == SwRedlineTable::npos"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 455, __extension__ __PRETTY_FUNCTION__))
;
456 }
457 assert(&rNode != GetDep())(static_cast <bool> (&rNode != GetDep()) ? void (0)
: __assert_fail ("&rNode != GetDep()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 457, __extension__ __PRETTY_FUNCTION__))
;
458 assert(!m_pMergedPara(static_cast <bool> (!m_pMergedPara || (m_pMergedPara->
pFirstNode->GetIndex() < rNode.GetIndex()) || (rNode.GetIndex
() + 1 == m_pMergedPara->pFirstNode->GetIndex())) ? void
(0) : __assert_fail ("!m_pMergedPara || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex()) || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex())"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 460, __extension__ __PRETTY_FUNCTION__))
459 || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())(static_cast <bool> (!m_pMergedPara || (m_pMergedPara->
pFirstNode->GetIndex() < rNode.GetIndex()) || (rNode.GetIndex
() + 1 == m_pMergedPara->pFirstNode->GetIndex())) ? void
(0) : __assert_fail ("!m_pMergedPara || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex()) || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex())"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 460, __extension__ __PRETTY_FUNCTION__))
460 || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex()))(static_cast <bool> (!m_pMergedPara || (m_pMergedPara->
pFirstNode->GetIndex() < rNode.GetIndex()) || (rNode.GetIndex
() + 1 == m_pMergedPara->pFirstNode->GetIndex())) ? void
(0) : __assert_fail ("!m_pMergedPara || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex()) || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex())"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 460, __extension__ __PRETTY_FUNCTION__))
;
461 SwTextNode & rFirstNode(
462 (!isForceNodeAsFirst && m_pMergedPara && m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
463 ? *m_pMergedPara->pFirstNode
464 : rNode);
465 // sw_redlinehide: use New here, because the only caller also calls lcl_ChangeFootnoteRef
466 m_pMergedPara = sw::CheckParaRedlineMerge(*this, rFirstNode, sw::FrameMode::New);
467 if (!m_pMergedPara)
468 {
469 rNode.Add(this);
470 }
471}
472
473void SwLayoutFrame::DestroyImpl()
474{
475 while (!m_VertPosOrientFramesFor.empty())
1
Assuming the condition is false
2
Loop condition is false. Execution continues on line 481
476 {
477 SwAnchoredObject *pObj = *m_VertPosOrientFramesFor.begin();
478 pObj->ClearVertPosOrientFrame();
479 }
480
481 assert(m_VertPosOrientFramesFor.empty())(static_cast <bool> (m_VertPosOrientFramesFor.empty()) ?
void (0) : __assert_fail ("m_VertPosOrientFramesFor.empty()"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 481, __extension__ __PRETTY_FUNCTION__))
;
3
Assuming the condition is true
4
'?' condition is true
482
483 SwFrame *pFrame = m_pLower;
484
485 if( GetFormat() && !GetFormat()->GetDoc()->IsInDtor() )
5
Assuming the condition is false
486 {
487 while ( pFrame )
488 {
489 //First delete the Objs of the Frame because they can't unregister
490 //from the page after remove.
491 //We don't want to create an endless loop only because one couldn't
492 //unregister.
493
494 while ( pFrame->GetDrawObjs() && pFrame->GetDrawObjs()->size() )
495 {
496 const size_t nCnt = pFrame->GetDrawObjs()->size();
497 // #i28701#
498 SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[0];
499 if (SwFlyFrame* pFlyFrame = dynamic_cast<SwFlyFrame*>(pAnchoredObj))
500 {
501 SwFrame::DestroyFrame(pFlyFrame);
502 assert(!pFrame->GetDrawObjs() || nCnt > pFrame->GetDrawObjs()->size())(static_cast <bool> (!pFrame->GetDrawObjs() || nCnt >
pFrame->GetDrawObjs()->size()) ? void (0) : __assert_fail
("!pFrame->GetDrawObjs() || nCnt > pFrame->GetDrawObjs()->size()"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 502, __extension__ __PRETTY_FUNCTION__))
;
503 }
504 else
505 {
506 pAnchoredObj->ClearTmpConsiderWrapInfluence();
507 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
508 SwDrawContact* pContact =
509 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
510 OSL_ENSURE( pContact,do { if (true && (!(pContact))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "511" ": "), "%s", "<SwFrame::~SwFrame> - missing contact for drawing object"
); } } while (false)
511 "<SwFrame::~SwFrame> - missing contact for drawing object" )do { if (true && (!(pContact))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "511" ": "), "%s", "<SwFrame::~SwFrame> - missing contact for drawing object"
); } } while (false)
;
512 if ( pContact )
513 {
514 pContact->DisconnectObjFromLayout( pSdrObj );
515 }
516
517 if ( pFrame->GetDrawObjs() &&
518 nCnt == pFrame->GetDrawObjs()->size() )
519 {
520 pFrame->GetDrawObjs()->Remove( *pAnchoredObj );
521 }
522 }
523 }
524 pFrame->RemoveFromLayout();
525 SwFrame::DestroyFrame(pFrame);
526 pFrame = m_pLower;
527 }
528 //Delete the Flys, the last one also deletes the array.
529 while ( GetDrawObjs() && GetDrawObjs()->size() )
530 {
531 const size_t nCnt = GetDrawObjs()->size();
532
533 // #i28701#
534 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[0];
535 if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
536 {
537 SwFrame::DestroyFrame(static_cast<SwFlyFrame*>(pAnchoredObj));
538 assert(!GetDrawObjs() || nCnt > GetDrawObjs()->size())(static_cast <bool> (!GetDrawObjs() || nCnt > GetDrawObjs
()->size()) ? void (0) : __assert_fail ("!GetDrawObjs() || nCnt > GetDrawObjs()->size()"
, "/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
, 538, __extension__ __PRETTY_FUNCTION__))
;
539 }
540 else
541 {
542 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
543 SwDrawContact* pContact =
544 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
545 OSL_ENSURE( pContact,do { if (true && (!(pContact))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "546" ": "), "%s", "<SwFrame::~SwFrame> - missing contact for drawing object"
); } } while (false)
546 "<SwFrame::~SwFrame> - missing contact for drawing object" )do { if (true && (!(pContact))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "546" ": "), "%s", "<SwFrame::~SwFrame> - missing contact for drawing object"
); } } while (false)
;
547 if ( pContact )
548 {
549 pContact->DisconnectObjFromLayout( pSdrObj );
550 }
551
552 if ( GetDrawObjs() && nCnt == GetDrawObjs()->size() )
553 {
554 GetDrawObjs()->Remove( *pAnchoredObj );
555 }
556 }
557 }
558 }
559 else
560 {
561 while( pFrame )
6
Loop condition is false. Execution continues on line 569
562 {
563 SwFrame *pNxt = pFrame->GetNext();
564 SwFrame::DestroyFrame(pFrame);
565 pFrame = pNxt;
566 }
567 }
568
569 SwFrame::DestroyImpl();
7
Calling 'SwFrame::DestroyImpl'
570}
571
572SwLayoutFrame::~SwLayoutFrame()
573{
574}
575
576/**
577|* The paintarea is the area, in which the content of a frame is allowed
578|* to be displayed. This region could be larger than the printarea (getFramePrintArea())
579|* of the upper, it includes e.g. often the margin of the page.
580|*/
581SwRect SwFrame::GetPaintArea() const
582{
583 // NEW TABLES
584 // Cell frames may not leave their upper:
585 SwRect aRect = IsRowFrame() ? GetUpper()->getFrameArea() : getFrameArea();
586 const bool bVert = IsVertical();
587 SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
588 SwRectFnSet aRectFnSet(this);
589 long nRight = (aRect.*fnRect->fnGetRight)();
590 long nLeft = (aRect.*fnRect->fnGetLeft)();
591 const SwFrame* pTmp = this;
592 bool bLeft = true;
593 bool bRight = true;
594 long nRowSpan = 0;
595 while( pTmp )
596 {
597 if( pTmp->IsCellFrame() && pTmp->GetUpper() &&
598 pTmp->GetUpper()->IsVertical() != pTmp->IsVertical() )
599 nRowSpan = static_cast<const SwCellFrame*>(pTmp)->GetTabBox()->getRowSpan();
600 long nTmpRight = (pTmp->getFrameArea().*fnRect->fnGetRight)();
601 long nTmpLeft = (pTmp->getFrameArea().*fnRect->fnGetLeft)();
602 if( pTmp->IsRowFrame() && nRowSpan > 1 )
603 {
604 const SwFrame* pNxt = pTmp;
605 while( --nRowSpan > 0 && pNxt->GetNext() )
606 pNxt = pNxt->GetNext();
607 if( pTmp->IsVertical() )
608 nTmpLeft = (pNxt->getFrameArea().*fnRect->fnGetLeft)();
609 else
610 {
611 // pTmp is a row frame, but it's not vertical.
612 if (IsVertLRBT())
613 {
614 // This frame cell is OK to expand towards the physical down direction.
615 // Physical down is left.
616 nTmpLeft = (pNxt->getFrameArea().*fnRect->fnGetLeft)();
617 }
618 else
619 {
620 nTmpRight = (pNxt->getFrameArea().*fnRect->fnGetRight)();
621 }
622 }
623 }
624 OSL_ENSURE( pTmp, "GetPaintArea lost in time and space" )do { if (true && (!(pTmp))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ssfrm.cxx"
":" "624" ": "), "%s", "GetPaintArea lost in time and space"
); } } while (false)
;
625 if( pTmp->IsPageFrame() || pTmp->IsFlyFrame() ||
626 pTmp->IsCellFrame() || pTmp->IsRowFrame() || //nobody leaves a table!
627 pTmp->IsRootFrame() )
628 {
629 if( bLeft || aRectFnSet.XDiff(nTmpLeft, nLeft) > 0 )
630 nLeft = nTmpLeft;
631 if( bRight || aRectFnSet.XDiff(nRight, nTmpRight) > 0 )
632 nRight = nTmpRight;
633 if( pTmp->IsPageFrame() || pTmp->IsFlyFrame() || pTmp->IsRootFrame() )
634 break;
635 bLeft = false;
636 bRight = false;
637 }
638 else if( pTmp->IsColumnFrame() ) // nobody enters neighbour columns
639 {
640 bool bR2L = pTmp->IsRightToLeft();
641 // the first column has _no_ influence to the left range
642 if( bR2L ? pTmp->GetNext() : pTmp->GetPrev() )
643 {
644 if( bLeft || aRectFnSet.XDiff(nTmpLeft, nLeft) > 0 )
645 nLeft = nTmpLeft;
646 bLeft = false;
647 }
648 // the last column has _no_ influence to the right range
649 if( bR2L ? pTmp->GetPrev() : pTmp->GetNext() )
650 {
651 if( bRight || aRectFnSet.XDiff(nRight, nTmpRight) > 0 )
652 nRight = nTmpRight;
653 bRight = false;
654 }
655 }
656 else if( bVert && pTmp->IsBodyFrame() )
657 {
658 // Header and footer frames have always horizontal direction and
659 // limit the body frame.
660 // A previous frame of a body frame must be a header,
661 // the next frame of a body frame may be a footnotecontainer or
662 // a footer. The footnotecontainer has the same direction like
663 // the body frame.
664 if( pTmp->GetPrev() && ( bLeft || aRectFnSet.XDiff(nTmpLeft, nLeft) > 0 ) )
665 {
666 nLeft = nTmpLeft;
667 bLeft = false;
668 }
669 if( pTmp->GetNext() &&
670 ( pTmp->GetNext()->IsFooterFrame() || pTmp->GetNext()->GetNext() )
671 && ( bRight || aRectFnSet.XDiff(nRight, nTmpRight) > 0 ) )
672 {
673 nRight = nTmpRight;
674 bRight = false;
675 }
676 }
677 pTmp = pTmp->GetUpper();
678 }
679 (aRect.*fnRect->fnSetLeft)( nLeft );
680 (aRect.*fnRect->fnSetRight)( nRight );
681 return aRect;
682}
683
684/**
685|* The unionframe is the framearea (getFrameArea()) of a frame expanded by the
686|* printarea, if there's a negative margin at the left or right side.
687|*/
688SwRect SwFrame::UnionFrame( bool bBorder ) const
689{
690 bool bVert = IsVertical();
691 SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
692 long nLeft = (getFrameArea().*fnRect->fnGetLeft)();
693 long nWidth = (getFrameArea().*fnRect->fnGetWidth)();
694 long nPrtLeft = (getFramePrintArea().*fnRect->fnGetLeft)();
695 long nPrtWidth = (getFramePrintArea().*fnRect->fnGetWidth)();
696 SwRectFnSet aRectFnSet(this);
697 if (aRectFnSet.XInc(nPrtLeft, nPrtWidth) > nWidth)
698 nWidth = nPrtLeft + nPrtWidth;
699 if( nPrtLeft < 0 )
700 {
701 nLeft += nPrtLeft;
702 nWidth -= nPrtLeft;
703 }
704 SwTwips nRight = aRectFnSet.XInc(nLeft, nWidth);
705 long nAdd = 0;
706 if( bBorder )
707 {
708 SwBorderAttrAccess aAccess( SwFrame::GetCache(), this );
709 const SwBorderAttrs &rAttrs = *aAccess.Get();
710 const SvxBoxItem &rBox = rAttrs.GetBox();
711 if ( rBox.GetLeft() )
712 nLeft -= rBox.CalcLineSpace( SvxBoxItemLine::LEFT );
713 else
714 nLeft -= rBox.GetDistance( SvxBoxItemLine::LEFT ) + 1;
715 if ( rBox.GetRight() )
716 nAdd += rBox.CalcLineSpace( SvxBoxItemLine::RIGHT );
717 else
718 nAdd += rBox.GetDistance( SvxBoxItemLine::RIGHT ) + 1;
719 if( rAttrs.GetShadow().GetLocation() != SvxShadowLocation::NONE )
720 {
721 const SvxShadowItem &rShadow = rAttrs.GetShadow();
722 nLeft -= rShadow.CalcShadowSpace( SvxShadowItemSide::LEFT );
723 nAdd += rShadow.CalcShadowSpace( SvxShadowItemSide::RIGHT );
724 }
725 }
726 if( IsTextFrame() && static_cast<const SwTextFrame*>(this)->HasPara() )
727 {
728 long nTmp = static_cast<const SwTextFrame*>(this)->HangingMargin();
729 if( nTmp > nAdd )
730 nAdd = nTmp;
731 }
732 nWidth = aRectFnSet.XDiff(aRectFnSet.XInc(nRight, nAdd), nLeft);
733 SwRect aRet( getFrameArea() );
734 (aRet.*fnRect->fnSetLeft)(nLeft);
735 (aRet.*fnRect->fnSetWidth)( nWidth );
736 return aRet;
737}
738
739/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/sw/source/core/inc/frame.hxx

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#ifndef INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX
21#define INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX
22
23#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
24#include <editeng/borderline.hxx>
25#include <svl/poolitem.hxx>
26#include <swtypes.hxx>
27#include <swrect.hxx>
28#include <calbck.hxx>
29#include <svl/SfxBroadcaster.hxx>
30#include <o3tl/typed_flags_set.hxx>
31#include <com/sun/star/style/TabStop.hpp>
32#include <basegfx/matrix/b2dhommatrix.hxx>
33#include <vcl/outdev.hxx>
34
35#include <memory>
36
37namespace drawinglayer::processor2d { class BaseProcessor2D; }
38
39class SwLayoutFrame;
40class SwRootFrame;
41class SwPageFrame;
42class SwBodyFrame;
43class SwFlyFrame;
44class SwSectionFrame;
45class SwFootnoteFrame;
46class SwFootnoteBossFrame;
47class SwTabFrame;
48class SwRowFrame;
49class SwContentFrame;
50class SwAttrSet;
51class Color;
52class SwBorderAttrs;
53class SwCache;
54class SvxBrushItem;
55class SvxFormatBreakItem;
56class SwFormatPageDesc;
57class SwSelectionList;
58struct SwPosition;
59struct SwCursorMoveState;
60class SwFormat;
61class SwPrintData;
62class SwSortedObjs;
63class SwAnchoredObject;
64enum class SvxFrameDirection;
65class IDocumentDrawModelAccess;
66
67// Each FrameType is represented here as a bit.
68// The bits must be set in a way that it can be determined with masking of
69// which kind of FrameType an instance is _and_ from what classes it was derived.
70// Each frame has in its base class a member that must be set by the
71// constructors accordingly.
72enum class SwFrameType
73{
74 None = 0x0000,
75 Root = 0x0001,
76 Page = 0x0002,
77 Column = 0x0004,
78 Header = 0x0008,
79 Footer = 0x0010,
80 FtnCont = 0x0020,
81 Ftn = 0x0040,
82 Body = 0x0080,
83 Fly = 0x0100,
84 Section = 0x0200,
85// UNUSED 0x0400
86 Tab = 0x0800,
87 Row = 0x1000,
88 Cell = 0x2000,
89 Txt = 0x4000,
90 NoTxt = 0x8000,
91};
92
93namespace o3tl
94{
95 template<> struct typed_flags<SwFrameType> : is_typed_flags<SwFrameType, 0xfbff> {};
96};
97
98// for internal use some common combinations
99#define FRM_LAYOUTSwFrameType(0x3bFF) SwFrameType(0x3bFF)
100#define FRM_ALLSwFrameType(0xfbff) SwFrameType(0xfbff)
101#define FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt) (SwFrameType::Txt | SwFrameType::NoTxt)
102#define FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column) (SwFrameType::Page | SwFrameType::Column)
103#define FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header |
SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType
::Tab | SwFrameType::Cell | SwFrameType::Txt)
(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType::Tab | SwFrameType::Cell | SwFrameType::Txt)
104#define FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) (SwFrameType::Column | SwFrameType::Cell)
105#define FRM_NOTE_VERT(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section
| SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType
::Txt)
(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType::Txt)
106#define FRM_HEADFOOT(SwFrameType::Header | SwFrameType::Footer) (SwFrameType::Header | SwFrameType::Footer)
107#define FRM_BODYFTNC(SwFrameType::FtnCont | SwFrameType::Body) (SwFrameType::FtnCont | SwFrameType::Body)
108
109// for GetNextLeaf/GetPrevLeaf.
110enum MakePageType
111{
112 MAKEPAGE_NONE, // do not create page/footnote
113 MAKEPAGE_APPEND, // only append page if needed
114 MAKEPAGE_INSERT, // add or append page if needed
115 MAKEPAGE_FTN, // add footnote if needed
116 MAKEPAGE_NOSECTION // Don't create section frames
117};
118
119namespace drawinglayer::attribute {
120 class SdrAllFillAttributesHelper;
121 typedef std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr;
122}
123
124/// Helper class to isolate geometry-defining members of SwFrame
125/// and to control their accesses. Moved to own class to have no
126/// hidden accesses to 'private' members anymore.
127///
128/// Added most important flags about the state of this geometric
129/// information and if it is valid or not
130class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SwFrameAreaDefinition
131{
132private:
133 friend void FriendHackInvalidateRowFrame(SwFrameAreaDefinition &);
134
135 // The absolute position and size of the SwFrame in the document.
136 // This values are set by the layouter implementations
137 SwRect maFrameArea;
138
139 // The 'inner' Frame Area defined by a SwRect relative to FrameArea:
140 // When identical to FrameArea, Pos() will be (0, 0) and Size identical.
141 SwRect maFramePrintArea;
142
143 // bitfield
144 bool mbFrameAreaPositionValid : 1;
145 bool mbFrameAreaSizeValid : 1;
146 bool mbFramePrintAreaValid : 1;
147
148 // #i65250#
149 // frame ID is now in general available - used for layout loop control
150 static sal_uInt32 mnLastFrameId;
151 const sal_uInt32 mnFrameId;
152
153protected:
154 // write access to mb*Valid flags
155 void setFrameAreaPositionValid(bool bNew);
156 void setFrameAreaSizeValid(bool bNew);
157 void setFramePrintAreaValid(bool bNew);
158
159public:
160 SwFrameAreaDefinition();
161 virtual ~SwFrameAreaDefinition();
162
163 // read access to mb*Valid flags
164 bool isFrameAreaPositionValid() const { return mbFrameAreaPositionValid; }
165 bool isFrameAreaSizeValid() const { return mbFrameAreaSizeValid; }
166 bool isFramePrintAreaValid() const { return mbFramePrintAreaValid; }
167
168 // syntactic sugar: test whole FrameAreaDefinition
169 bool isFrameAreaDefinitionValid() const { return isFrameAreaPositionValid() && isFrameAreaSizeValid() && isFramePrintAreaValid(); }
170
171 // #i65250#
172 sal_uInt32 GetFrameId() const { return mnFrameId; }
173
174 // read accesses to FrameArea definitions - only const access allowed.
175 // Do *not* const_cast results, it is necessary to track changes. use
176 // the below offered WriteAccess helper classes instead
177 const SwRect& getFrameArea() const { return maFrameArea; }
178 const SwRect& getFramePrintArea() const { return maFramePrintArea; }
179
180 // helper class(es) for FrameArea manipulation. These
181 // have to be used to apply changes to FrameAreas. They hold a copy of the
182 // SwRect for manipulation. It gets written back at destruction. Thus, this
183 // mechanism depends on scope usage, take care. It prevents errors using
184 // different instances of SwFrame in get/set methods which is more safe
185 class FrameAreaWriteAccess : public SwRect
186 {
187 private:
188 SwFrameAreaDefinition& mrTarget;
189
190 FrameAreaWriteAccess(const FrameAreaWriteAccess&) = delete;
191 FrameAreaWriteAccess& operator=(const FrameAreaWriteAccess&) = delete;
192
193 public:
194 FrameAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFrameArea()), mrTarget(rTarget) {}
195 ~FrameAreaWriteAccess();
196 void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; }
197 };
198
199 // same helper for FramePrintArea
200 class FramePrintAreaWriteAccess : public SwRect
201 {
202 private:
203 SwFrameAreaDefinition& mrTarget;
204
205 FramePrintAreaWriteAccess(const FramePrintAreaWriteAccess&) = delete;
206 FramePrintAreaWriteAccess& operator=(const FramePrintAreaWriteAccess&) = delete;
207
208 public:
209 FramePrintAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFramePrintArea()), mrTarget(rTarget) {}
210 ~FramePrintAreaWriteAccess();
211 void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; }
212 };
213
214 // RotateFlyFrame3 - Support for Transformations
215 // Hand out the Transformations for the current FrameAreaDefinition
216 // for the FrameArea and FramePrintArea.
217 // FramePrintArea is not relative to FrameArea in this
218 // transformation representation (to make it easier to use and understand).
219 // There is no 'set' method since SwFrame is a layout object. For
220 // some cases rotation will be included (used for SwGrfNode in inner
221 // SwFrame of a SwFlyFrame)
222 virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const;
223 virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const;
224
225 // RotateFlyFrame3 - Support for Transformations
226 // Modify current transformations by applying given translation
227 virtual void transform_translate(const Point& rOffset);
228};
229
230/// RotateFlyFrame3: Helper class when you want to make your SwFrame derivate
231/// transformable. It provides some tooling to do so. To use, add as member
232/// (see e.g. SwFlyFreeFrame which uses 'std::unique_ptr< TransformableSwFrame >')
233class TransformableSwFrame
234{
235private:
236 // The SwFrameAreaDefinition to work on
237 SwFrameAreaDefinition& mrSwFrameAreaDefinition;
238
239 // FrameAreaTransformation and FramePrintAreaTransformation
240 // !identity when needed (translate/scale is used (e.g. rotation))
241 basegfx::B2DHomMatrix maFrameAreaTransformation;
242 basegfx::B2DHomMatrix maFramePrintAreaTransformation;
243
244public:
245 TransformableSwFrame(SwFrameAreaDefinition& rSwFrameAreaDefinition)
246 : mrSwFrameAreaDefinition(rSwFrameAreaDefinition),
247 maFrameAreaTransformation(),
248 maFramePrintAreaTransformation()
249 {
250 }
251
252 // get SwFrameArea in transformation form
253 const basegfx::B2DHomMatrix& getLocalFrameAreaTransformation() const
254 {
255 return maFrameAreaTransformation;
256 }
257
258 // get SwFramePrintArea in transformation form
259 const basegfx::B2DHomMatrix& getLocalFramePrintAreaTransformation() const
260 {
261 return maFramePrintAreaTransformation;
262 }
263
264 // Helpers to re-create the untransformed SwRect(s) originally
265 // in the SwFrameAreaDefinition, based on the current Transformations.
266 SwRect getUntransformedFrameArea() const;
267 SwRect getUntransformedFramePrintArea() const;
268
269 // Helper method to re-create FrameAreaTransformations based on the
270 // current FrameAreaDefinition transformed by given rotation and Center
271 void createFrameAreaTransformations(
272 double fRotation,
273 const basegfx::B2DPoint& rCenter);
274
275 // Tooling method to reset the SwRect(s) in the current
276 // SwFrameAreaDefinition which are already adapted to
277 // Transformation back to the untransformed state, using
278 // the getUntransformedFrame*Area calls above when needed.
279 // Only the SwRect(s) are changed back, not the transformations.
280 void restoreFrameAreas();
281
282 // Re-Creates the SwRect(s) as BoundAreas based on the current
283 // set Transformations.
284 void adaptFrameAreasToTransformations();
285
286 // Modify current definitions by applying the given transformation
287 void transform(const basegfx::B2DHomMatrix& aTransform);
288};
289
290/**
291 * Base class of the Writer layout elements.
292 *
293 * This includes not only fly frames, but everything down to the paragraph
294 * level: pages, headers, footers, etc. (Inside a paragraph SwLinePortion
295 * instances are used.)
296 */
297class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwFrame : public SwFrameAreaDefinition, public SwClient, public SfxBroadcaster
298{
299 // the hidden Frame
300 friend class SwFlowFrame;
301 friend class SwLayoutFrame;
302 friend class SwLooping;
303 friend class SwDeletionChecker; // for GetDep()
304
305 // voids lower during creation of a column
306 friend SwFrame *SaveContent( SwLayoutFrame *, SwFrame* pStart );
307 friend void RestoreContent( SwFrame *, SwLayoutFrame *, SwFrame *pSibling );
308
309 // for validating a mistakenly invalidated one in SwContentFrame::MakeAll
310 friend void ValidateSz( SwFrame *pFrame );
311 // implemented in text/txtftn.cxx, prevents Footnote oscillation
312 friend void ValidateText( SwFrame *pFrame );
313
314 friend void MakeNxt( SwFrame *pFrame, SwFrame *pNxt );
315
316 // cache for (border) attributes
317 static SwCache *mpCache;
318
319 SwRootFrame *mpRoot;
320 SwLayoutFrame *mpUpper;
321 SwFrame *mpNext;
322 SwFrame *mpPrev;
323
324 // sw_redlinehide: hide these dangerous SwClient functions
325 using SwClient::GetRegisteredInNonConst;
326 using SwClient::GetRegisteredIn;
327
328 SwFrame *FindNext_();
329 SwFrame *FindPrev_();
330
331 /** method to determine next content frame in the same environment
332 for a flow frame (content frame, table frame, section frame)
333
334 #i27138# - adding documentation:
335 Travelling downwards through the layout to determine the next content
336 frame in the same environment. There are several environments in a
337 document, which form a closed context regarding this function. These
338 environments are:
339 - Each page header
340 - Each page footer
341 - Each unlinked fly frame
342 - Each group of linked fly frames
343 - All footnotes
344 - All document body frames
345 #i27138# - adding parameter <_bInSameFootnote>
346 Its default value is <false>. If its value is <true>, the environment
347 'All footnotes' is no longer treated. Instead each footnote is treated
348 as an own environment.
349
350 @param _bInSameFootnote
351 input parameter - boolean indicating, that the found next content
352 frame has to be in the same footnote frame. This parameter is only
353 relevant for flow frames in footnotes.
354
355 @return SwContentFrame*
356 pointer to the found next content frame. It's NULL, if none exists.
357 */
358 SwContentFrame* FindNextCnt_( const bool _bInSameFootnote );
359
360 /** method to determine previous content frame in the same environment
361 for a flow frame (content frame, table frame, section frame)
362
363 #i27138#
364 Travelling upwards through the layout to determine the previous content
365 frame in the same environment. There are several environments in a
366 document, which form a closed context regarding this function. These
367 environments are:
368 - Each page header
369 - Each page footer
370 - Each unlinked fly frame
371 - Each group of linked fly frames
372 - All footnotes
373 - All document body frames
374 #i27138# - adding parameter <_bInSameFootnote>
375 Its default value is <false>. If its value is <true>, the environment
376 'All footnotes' is no longer treated. Instead each footnote is treated
377 as an own environment.
378
379 The found previous content frame has to be in the same footnote frame. This is only
380 relevant for flow frames in footnotes.
381
382 @return SwContentFrame*
383 pointer to the found previous content frame. It's NULL, if none exists.
384 */
385 SwContentFrame* FindPrevCnt_();
386
387 void UpdateAttrFrame( const SfxPoolItem*, const SfxPoolItem*, sal_uInt8 & );
388 SwFrame* GetIndNext_();
389 void SetDirFlags( bool bVert );
390
391 const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const;
392
393 SwPageFrame* ImplFindPageFrame();
394
395protected:
396 std::unique_ptr<SwSortedObjs> m_pDrawObjs; // draw objects, can be null
397 SwFrameType mnFrameType; //Who am I?
398
399 bool mbInDtor : 1;
400 bool mbInvalidR2L : 1;
401 bool mbDerivedR2L : 1;
402 bool mbRightToLeft : 1;
403 bool mbInvalidVert : 1;
404 bool mbDerivedVert : 1;
405 bool mbVertical : 1;
406
407 bool mbVertLR : 1;
408 bool mbVertLRBT : 1;
409
410 bool mbValidLineNum : 1;
411 bool mbFixSize : 1;
412
413 // if true, frame will be painted completely even content was changed
414 // only partially. For ContentFrames a border (from Action) will exclusively
415 // painted if <mbCompletePaint> is true.
416 bool mbCompletePaint : 1;
417
418 bool mbRetouche : 1; // frame is responsible for retouching
419
420 bool mbInfInvalid : 1; // InfoFlags are invalid
421 bool mbInfBody : 1; // Frame is in document body
422 bool mbInfTab : 1; // Frame is in a table
423 bool mbInfFly : 1; // Frame is in a Fly
424 bool mbInfFootnote : 1; // Frame is in a footnote
425 bool mbInfSct : 1; // Frame is in a section
426 bool mbColLocked : 1; // lock Grow/Shrink for column-wise section
427 // or fly frames, will be set in Format
428 bool m_isInDestroy : 1;
429 bool mbForbidDelete : 1;
430
431 void ColLock() { mbColLocked = true; }
432 void ColUnlock() { mbColLocked = false; }
433
434 virtual void DestroyImpl();
435 virtual ~SwFrame() override;
436
437 // Only used by SwRootFrame Ctor to get 'this' into mpRoot...
438 void setRootFrame( SwRootFrame* pRoot ) { mpRoot = pRoot; }
439
440 SwPageFrame *InsertPage( SwPageFrame *pSibling, bool bFootnote );
441 void PrepareMake(vcl::RenderContext* pRenderContext);
442 void OptPrepareMake();
443 virtual void MakePos();
444 // Format next frame of table frame to assure keeping attributes.
445 // In case of nested tables method <SwFrame::MakeAll()> is called to
446 // avoid formatting of superior table frame.
447 friend SwFrame* sw_FormatNextContentForKeep( SwTabFrame* pTabFrame );
448
449 virtual void MakeAll(vcl::RenderContext* pRenderContext) = 0;
450 // adjust frames of a page
451 SwTwips AdjustNeighbourhood( SwTwips nDiff, bool bTst = false );
452
453 // change only frame size not the size of PrtArea
454 virtual SwTwips ShrinkFrame( SwTwips, bool bTst = false, bool bInfo = false ) = 0;
455 virtual SwTwips GrowFrame ( SwTwips, bool bTst = false, bool bInfo = false ) = 0;
456
457 /// use these so we can grep for SwFrame's GetRegisteredIn accesses
458 /// beware that SwTextFrame may return sw::WriterMultiListener
459 SwModify *GetDep() { return GetRegisteredInNonConst(); }
460 const SwModify *GetDep() const { return GetRegisteredIn(); }
461
462 SwFrame( SwModify*, SwFrame* );
463
464 void CheckDir( SvxFrameDirection nDir, bool bVert, bool bOnlyBiDi, bool bBrowse );
465
466 /** enumeration for the different invalidations
467 #i28701#
468 */
469 enum InvalidationType
470 {
471 INVALID_SIZE, INVALID_PRTAREA, INVALID_POS, INVALID_LINENUM, INVALID_ALL
472 };
473
474 /** method to determine, if an invalidation is allowed.
475 #i28701
476 */
477 virtual bool InvalidationAllowed( const InvalidationType _nInvalid ) const;
478
479 /** method to perform additional actions on an invalidation
480
481 #i28701#
482 Method has *only* to contain actions, which has to be performed on
483 *every* assignment of the corresponding flag to <false>.
484 */
485 virtual void ActionOnInvalidation( const InvalidationType _nInvalid );
486
487 // draw shadow and borders
488 void PaintShadow( const SwRect&, SwRect&, const SwBorderAttrs& ) const;
489 virtual void Modify( const SfxPoolItem*, const SfxPoolItem* ) override;
490
491 virtual const IDocumentDrawModelAccess& getIDocumentDrawModelAccess( );
492
493public:
494 virtual css::uno::Sequence< css::style::TabStop > GetTabStopInfo( SwTwips )
495 {
496 return css::uno::Sequence< css::style::TabStop >();
497 }
498
499
500 SwFrameType GetType() const { return mnFrameType; }
501
502 static SwCache &GetCache() { return *mpCache; }
503 static SwCache *GetCachePtr() { return mpCache; }
504 static void SetCache( SwCache *pNew ) { mpCache = pNew; }
505
506 // change PrtArea size and FrameSize
507 SwTwips Shrink( SwTwips, bool bTst = false, bool bInfo = false );
508 SwTwips Grow ( SwTwips, bool bTst = false, bool bInfo = false );
509
510 // different methods for inserting in layout tree (for performance reasons)
511
512 // insert before pBehind or at the end of the chain below mpUpper
513 void InsertBefore( SwLayoutFrame* pParent, SwFrame* pBehind );
514 // insert after pBefore or at the beginning of the chain below mpUpper
515 void InsertBehind( SwLayoutFrame *pParent, SwFrame *pBefore );
516 // insert before pBehind or at the end of the chain while considering
517 // the siblings of pSct
518 bool InsertGroupBefore( SwFrame* pParent, SwFrame* pWhere, SwFrame* pSct );
519 void RemoveFromLayout();
520
521 // For internal use only - who ignores this will be put in a sack and has
522 // to stay there for two days
523 // Does special treatment for Get_[Next|Prev]Leaf() (for tables).
524 SwLayoutFrame *GetLeaf( MakePageType eMakePage, bool bFwd );
525 SwLayoutFrame *GetNextLeaf ( MakePageType eMakePage );
526 SwLayoutFrame *GetNextFootnoteLeaf( MakePageType eMakePage );
527 SwLayoutFrame *GetNextSctLeaf( MakePageType eMakePage );
528 SwLayoutFrame *GetNextCellLeaf();
529 SwLayoutFrame *GetPrevLeaf ();
530 SwLayoutFrame *GetPrevFootnoteLeaf( MakePageType eMakeFootnote );
531 SwLayoutFrame *GetPrevSctLeaf();
532 SwLayoutFrame *GetPrevCellLeaf();
533 const SwLayoutFrame *GetLeaf ( MakePageType eMakePage, bool bFwd,
534 const SwFrame *pAnch ) const;
535
536 bool WrongPageDesc( SwPageFrame* pNew );
537
538 //#i28701# - new methods to append/remove drawing objects
539 void AppendDrawObj( SwAnchoredObject& _rNewObj );
540 void RemoveDrawObj( SwAnchoredObject& _rToRemoveObj );
541
542 // work with chain of FlyFrames
543 void AppendFly( SwFlyFrame *pNew );
544 void RemoveFly( SwFlyFrame *pToRemove );
545 const SwSortedObjs *GetDrawObjs() const { return m_pDrawObjs.get(); }
546 SwSortedObjs *GetDrawObjs() { return m_pDrawObjs.get(); }
547 // #i28701# - change purpose of method and adjust its name
548 void InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs = true );
549
550 virtual void PaintSwFrameShadowAndBorder(
551 const SwRect&,
552 const SwPageFrame* pPage,
553 const SwBorderAttrs&) const;
554 void PaintBaBo( const SwRect&, const SwPageFrame *pPage,
555 const bool bOnlyTextBackground = false) const;
556 void PaintSwFrameBackground( const SwRect&, const SwPageFrame *pPage,
557 const SwBorderAttrs &,
558 const bool bLowerMode = false,
559 const bool bLowerBorder = false,
560 const bool bOnlyTextBackground = false ) const;
561 void PaintBorderLine( const SwRect&, const SwRect&, const SwPageFrame*,
562 const Color *pColor,
563 const SvxBorderLineStyle = SvxBorderLineStyle::SOLID ) const;
564
565 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> CreateProcessor2D( ) const;
566 void ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DContainer& rSequence ) const;
567
568 // retouch, not in the area of the given Rect!
569 void Retouch( const SwPageFrame *pPage, const SwRect &rRect ) const;
570
571 bool GetBackgroundBrush(
572 drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
573 const SvxBrushItem*& rpBrush,
574 const Color*& rpColor,
575 SwRect &rOrigRect,
576 bool bLowerMode,
577 bool bConsiderTextBox ) const;
578
579 inline void SetCompletePaint() const;
580 inline void ResetCompletePaint() const;
581 bool IsCompletePaint() const { return mbCompletePaint; }
582
583 inline void SetRetouche() const;
584 inline void ResetRetouche() const;
585 bool IsRetouche() const { return mbRetouche; }
586
587 void SetInfFlags();
588 void InvalidateInfFlags() { mbInfInvalid = true; }
589 inline bool IsInDocBody() const; // use InfoFlags, determine flags
590 inline bool IsInFootnote() const; // if necessary
591 inline bool IsInTab() const;
592 inline bool IsInFly() const;
593 inline bool IsInSct() const;
594
595 // If frame is inside a split table row, this function returns
596 // the corresponding row frame in the follow table.
597 const SwRowFrame* IsInSplitTableRow() const;
598
599 // If frame is inside a follow flow row, this function returns
600 // the corresponding row frame master table
601 const SwRowFrame* IsInFollowFlowRow() const;
602
603 bool IsInBalancedSection() const;
604
605 inline bool IsVertical() const;
606 inline bool IsVertLR() const;
607 inline bool IsVertLRBT() const;
608
609 void SetDerivedVert( bool bNew ){ mbDerivedVert = bNew; }
610 void SetInvalidVert( bool bNew) { mbInvalidVert = bNew; }
611 inline bool IsRightToLeft() const;
612 void SetDerivedR2L( bool bNew ) { mbDerivedR2L = bNew; }
613
614 void CheckDirChange();
615 // returns upper left frame position for LTR and
616 // upper right frame position for Asian / RTL frames
617 Point GetFrameAnchorPos( bool bIgnoreFlysAnchoredAtThisFrame ) const;
618
619 /** determine, if frame is moveable in given environment
620
621 method replaced 'old' method <bool IsMoveable() const>.
622 Determines, if frame is moveable in given environment. if no environment
623 is given (parameter _pLayoutFrame == 0), the movability in the actual
624 environment (<GetUpper()) is checked.
625
626 @param _pLayoutFrame
627 input parameter - given environment (layout frame), in which the movability
628 will be checked. If not set ( == 0 ), actual environment is taken.
629
630 @return boolean, indicating, if frame is moveable in given environment
631 */
632 bool IsMoveable( const SwLayoutFrame* _pLayoutFrame = nullptr ) const;
633
634 // Is it permitted for the (Text)Frame to add a footnote in the current
635 // environment (not e.g. for repeating table headlines)
636 bool IsFootnoteAllowed() const;
637
638 virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr );
639
640 virtual void CheckDirection( bool bVert );
641
642 void ReinitializeFrameSizeAttrFlags();
643
644 /// WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for
645 /// SwTextFrame, use GetBreakItem()/GetPageDescItem() instead
646 const SwAttrSet *GetAttrSet() const;
647 virtual const SvxFormatBreakItem& GetBreakItem() const;
648 virtual const SwFormatPageDesc& GetPageDescItem() const;
649
650 bool HasFixSize() const { return mbFixSize; }
651
652 // check all pages (starting from the given) and correct them if needed
653 static void CheckPageDescs( SwPageFrame *pStart, bool bNotifyFields = true, SwPageFrame** ppPrev = nullptr);
654
655 // might return 0, with and without const
656 SwFrame *GetNext() { return mpNext; }
657 SwFrame *GetPrev() { return mpPrev; }
658 SwLayoutFrame *GetUpper() { return mpUpper; }
659 SwRootFrame *getRootFrame(){ return mpRoot; }
660 SwPageFrame *FindPageFrame() { return IsPageFrame() ? reinterpret_cast<SwPageFrame*>(this) : ImplFindPageFrame(); }
661 SwFrame *FindColFrame();
662 SwRowFrame *FindRowFrame();
663 SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnotes = false );
664 SwTabFrame *ImplFindTabFrame();
665 SwFootnoteFrame *ImplFindFootnoteFrame();
666 SwFlyFrame *ImplFindFlyFrame();
667 SwSectionFrame *ImplFindSctFrame();
668 const SwBodyFrame *ImplFindBodyFrame() const;
669 SwFrame *FindFooterOrHeader();
670 SwFrame *GetLower();
671 const SwFrame *GetNext() const { return mpNext; }
672 const SwFrame *GetPrev() const { return mpPrev; }
673 const SwLayoutFrame *GetUpper() const { return mpUpper; }
674 const SwRootFrame *getRootFrame() const { return mpRoot; }
675 inline SwTabFrame *FindTabFrame();
676 inline SwFootnoteFrame *FindFootnoteFrame();
677 inline SwFlyFrame *FindFlyFrame();
678 inline SwSectionFrame *FindSctFrame();
679 inline SwFrame *FindNext();
680 // #i27138# - add parameter <_bInSameFootnote>
681 SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false );
682 inline SwFrame *FindPrev();
683 inline const SwPageFrame *FindPageFrame() const;
684 inline const SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnote = false ) const;
685 inline const SwFrame *FindColFrame() const;
686 inline const SwFrame *FindFooterOrHeader() const;
687 inline const SwTabFrame *FindTabFrame() const;
688 inline const SwFootnoteFrame *FindFootnoteFrame() const;
689 inline const SwFlyFrame *FindFlyFrame() const;
690 inline const SwSectionFrame *FindSctFrame() const;
691 inline const SwBodyFrame *FindBodyFrame() const;
692 inline const SwFrame *FindNext() const;
693 // #i27138# - add parameter <_bInSameFootnote>
694 const SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false ) const;
695 inline const SwFrame *FindPrev() const;
696 const SwFrame *GetLower() const;
697
698 SwContentFrame* FindPrevCnt();
699
700 const SwContentFrame* FindPrevCnt() const;
701
702 // #i79774#
703 SwFrame* GetIndPrev_() const;
704 SwFrame* GetIndPrev() const
705 { return ( mpPrev || !IsInSct() ) ? mpPrev : GetIndPrev_(); }
706
707 SwFrame* GetIndNext()
708 { return ( mpNext || !IsInSct() ) ? mpNext : GetIndNext_(); }
709 const SwFrame* GetIndNext() const { return const_cast<SwFrame*>(this)->GetIndNext(); }
710
711 sal_uInt16 GetPhyPageNum() const; // page number without offset
712 sal_uInt16 GetVirtPageNum() const; // page number with offset
713 bool OnRightPage() const { return 0 != GetPhyPageNum() % 2; };
714 bool WannaRightPage() const;
715 bool OnFirstPage() const;
716
717 inline const SwLayoutFrame *GetPrevLayoutLeaf() const;
718 inline const SwLayoutFrame *GetNextLayoutLeaf() const;
719 inline SwLayoutFrame *GetPrevLayoutLeaf();
720 inline SwLayoutFrame *GetNextLayoutLeaf();
721
722 virtual void Calc(vcl::RenderContext* pRenderContext) const; // here might be "formatted"
723 inline void OptCalc() const; // here we assume (for optimization) that
724 // the predecessors are already formatted
725 Point GetRelPos() const;
726
727 // PaintArea is the area where content might be displayed.
728 // The margin of a page or the space between columns belongs to it.
729 SwRect GetPaintArea() const;
730
731 // UnionFrame is the union of Frame- and PrtArea, normally identical
732 // to the FrameArea except in case of negative Prt margins.
733 SwRect UnionFrame( bool bBorder = false ) const;
734
735 virtual Size ChgSize( const Size& aNewSize );
736
737 virtual void Cut() = 0;
738 virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) = 0;
739
740 void ValidateLineNum() { mbValidLineNum = true; }
741
742 bool GetValidLineNumFlag()const { return mbValidLineNum; }
743
744 // Only invalidate Frame
745 // #i28701# - add call to method <ActionOnInvalidation(..)>
746 // for all invalidation methods.
747 // #i28701# - use method <InvalidationAllowed(..)> to
748 // decide, if invalidation will to be performed or not.
749 // #i26945# - no additional invalidation, if it's already
750 // invalidate.
751 void InvalidateSize_()
752 {
753 if ( isFrameAreaSizeValid() && InvalidationAllowed( INVALID_SIZE ) )
754 {
755 setFrameAreaSizeValid(false);
756 ActionOnInvalidation( INVALID_SIZE );
757 }
758 }
759 void InvalidatePrt_()
760 {
761 if ( isFramePrintAreaValid() && InvalidationAllowed( INVALID_PRTAREA ) )
762 {
763 setFramePrintAreaValid(false);
764 ActionOnInvalidation( INVALID_PRTAREA );
765 }
766 }
767 void InvalidatePos_()
768 {
769 if ( isFrameAreaPositionValid() && InvalidationAllowed( INVALID_POS ) )
770 {
771 setFrameAreaPositionValid(false);
772 ActionOnInvalidation( INVALID_POS );
773 }
774 }
775 void InvalidateLineNum_()
776 {
777 if ( mbValidLineNum && InvalidationAllowed( INVALID_LINENUM ) )
778 {
779 mbValidLineNum = false;
780 ActionOnInvalidation( INVALID_LINENUM );
781 }
782 }
783 void InvalidateAll_()
784 {
785 if ( ( isFrameAreaSizeValid() || isFramePrintAreaValid() || isFrameAreaPositionValid() ) && InvalidationAllowed( INVALID_ALL ) )
786 {
787 setFrameAreaSizeValid(false);
788 setFrameAreaPositionValid(false);
789 setFramePrintAreaValid(false);
790 ActionOnInvalidation( INVALID_ALL );
791 }
792 }
793 // also notify page at the same time
794 inline void InvalidateSize();
795 inline void InvalidatePrt();
796 inline void InvalidatePos();
797 inline void InvalidateLineNum();
798 inline void InvalidateAll();
799 void ImplInvalidateSize();
800 void ImplInvalidatePrt();
801 void ImplInvalidatePos();
802 void ImplInvalidateLineNum();
803
804 inline void InvalidateNextPos( bool bNoFootnote = false );
805 void ImplInvalidateNextPos( bool bNoFootnote );
806
807 /** method to invalidate printing area of next frame
808 #i11859#
809 */
810 void InvalidateNextPrtArea();
811
812 void InvalidatePage( const SwPageFrame *pPage = nullptr ) const;
813
814 virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const;
815
816 virtual bool GetModelPositionForViewPoint( SwPosition *, Point&,
817 SwCursorMoveState* = nullptr, bool bTestBackground = false ) const;
818 virtual bool GetCharRect( SwRect &, const SwPosition&,
819 SwCursorMoveState* = nullptr, bool bAllowFarAway = true ) const;
820 virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&,
821 SwPrintData const*const pPrintData = nullptr ) const;
822
823 // HACK: shortcut between frame and formatting
824 // It's your own fault if you cast void* incorrectly! In any case check
825 // the void* for 0.
826 virtual bool Prepare( const PrepareHint ePrep = PrepareHint::Clear,
827 const void *pVoid = nullptr, bool bNotify = true );
828
829 // true if it is the correct class, false otherwise
830 inline bool IsLayoutFrame() const;
831 inline bool IsRootFrame() const;
832 inline bool IsPageFrame() const;
833 inline bool IsColumnFrame() const;
834 inline bool IsFootnoteBossFrame() const; // footnote bosses might be PageFrames or ColumnFrames
835 inline bool IsHeaderFrame() const;
836 inline bool IsFooterFrame() const;
837 inline bool IsFootnoteContFrame() const;
838 inline bool IsFootnoteFrame() const;
839 inline bool IsBodyFrame() const;
840 inline bool IsColBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above ColumnFrame
841 inline bool IsPageBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above PageFrame
842 inline bool IsFlyFrame() const;
843 inline bool IsSctFrame() const;
844 inline bool IsTabFrame() const;
845 inline bool IsRowFrame() const;
846 inline bool IsCellFrame() const;
847 inline bool IsContentFrame() const;
848 inline bool IsTextFrame() const;
849 inline bool IsNoTextFrame() const;
850 // Frames where its PrtArea depends on their neighbors and that are
851 // positioned in the content flow
852 inline bool IsFlowFrame() const;
853 // Frames that are capable of retouching or that might need to retouch behind
854 // themselves
855 inline bool IsRetoucheFrame() const;
856 inline bool IsAccessibleFrame() const;
857
858 void PrepareCursor(); // CursorShell is allowed to call this
859
860 // Is the Frame (or the section containing it) protected? Same for Fly in
861 // Fly in ... and footnotes
862 bool IsProtected() const;
863
864 bool IsColLocked() const { return mbColLocked; }
865 virtual bool IsDeleteForbidden() const { return mbForbidDelete; }
866
867 /// this is the only way to delete a SwFrame instance
868 static void DestroyFrame(SwFrame *const pFrame);
869
870 bool IsInDtor() const { return mbInDtor; }
871
872 // No inline cause we need the function pointers
873 long GetTopMargin() const;
874 long GetBottomMargin() const;
875 long GetLeftMargin() const;
876 long GetRightMargin() const;
877 void SetTopBottomMargins( long, long );
878 void SetLeftRightMargins( long, long );
879 void SetRightLeftMargins( long, long );
880 long GetPrtLeft() const;
881 long GetPrtBottom() const;
882 long GetPrtRight() const;
883 long GetPrtTop() const;
884 bool SetMinLeft( long );
885 bool SetMaxBottom( long );
886 bool SetMaxRight( long );
887 void MakeBelowPos( const SwFrame*, const SwFrame*, bool );
888 void MakeLeftPos( const SwFrame*, const SwFrame*, bool );
889 void MakeRightPos( const SwFrame*, const SwFrame*, bool );
890 bool IsNeighbourFrame() const
891 { return bool(GetType() & FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell)); }
892
893 // NEW TABLES
894 // Some functions for covered/covering table cells. This way unnecessary
895 // includes can be avoided
896 virtual bool IsLeaveUpperAllowed() const;
897 virtual bool IsCoveredCell() const;
898 bool IsInCoveredCell() const;
899
900 // #i81146# new loop control
901 bool KnowsFormat( const SwFormat& rFormat ) const;
902 void RegisterToFormat( SwFormat& rFormat );
903 void ValidateThisAndAllLowers( const sal_uInt16 nStage );
904
905 void ForbidDelete() { mbForbidDelete = true; }
906 void AllowDelete() { mbForbidDelete = false; }
907
908 drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const;
909 bool supportsFullDrawingLayerFillAttributeSet() const;
910
911public:
912 // if writer is NULL, dumps the layout structure as XML in layout.xml
913 virtual void dumpAsXml(xmlTextWriterPtr writer = nullptr) const;
914 void dumpTopMostAsXml(xmlTextWriterPtr writer = nullptr) const;
915 void dumpInfosAsXml(xmlTextWriterPtr writer) const;
916 virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
917 void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
918 bool IsCollapse() const;
919};
920
921inline bool SwFrame::IsInDocBody() const
922{
923 if ( mbInfInvalid )
924 const_cast<SwFrame*>(this)->SetInfFlags();
925 return mbInfBody;
926}
927inline bool SwFrame::IsInFootnote() const
928{
929 if ( mbInfInvalid )
930 const_cast<SwFrame*>(this)->SetInfFlags();
931 return mbInfFootnote;
932}
933inline bool SwFrame::IsInTab() const
934{
935 if ( mbInfInvalid )
936 const_cast<SwFrame*>(this)->SetInfFlags();
937 return mbInfTab;
938}
939inline bool SwFrame::IsInFly() const
940{
941 if ( mbInfInvalid )
942 const_cast<SwFrame*>(this)->SetInfFlags();
943 return mbInfFly;
944}
945inline bool SwFrame::IsInSct() const
946{
947 if ( mbInfInvalid )
948 const_cast<SwFrame*>(this)->SetInfFlags();
949 return mbInfSct;
950}
951bool SwFrame::IsVertical() const
952{
953 if( mbInvalidVert )
954 const_cast<SwFrame*>(this)->SetDirFlags( true );
955 return mbVertical;
956}
957inline bool SwFrame::IsVertLR() const
958{
959 return mbVertLR;
960}
961inline bool SwFrame::IsVertLRBT() const
962{
963 return mbVertLRBT;
964}
965inline bool SwFrame::IsRightToLeft() const
966{
967 if( mbInvalidR2L )
968 const_cast<SwFrame*>(this)->SetDirFlags( false );
969 return mbRightToLeft;
970}
971
972inline void SwFrame::SetCompletePaint() const
973{
974 const_cast<SwFrame*>(this)->mbCompletePaint = true;
975}
976inline void SwFrame::ResetCompletePaint() const
977{
978 const_cast<SwFrame*>(this)->mbCompletePaint = false;
979}
980
981inline void SwFrame::SetRetouche() const
982{
983 const_cast<SwFrame*>(this)->mbRetouche = true;
984}
985inline void SwFrame::ResetRetouche() const
986{
987 const_cast<SwFrame*>(this)->mbRetouche = false;
988}
989
990inline SwLayoutFrame *SwFrame::GetNextLayoutLeaf()
991{
992 return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetNextLayoutLeaf());
993}
994inline SwLayoutFrame *SwFrame::GetPrevLayoutLeaf()
995{
996 return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetPrevLayoutLeaf());
997}
998inline const SwLayoutFrame *SwFrame::GetNextLayoutLeaf() const
999{
1000 return ImplGetNextLayoutLeaf( true );
1001}
1002inline const SwLayoutFrame *SwFrame::GetPrevLayoutLeaf() const
1003{
1004 return ImplGetNextLayoutLeaf( false );
1005}
1006
1007inline void SwFrame::InvalidateSize()
1008{
1009 if ( isFrameAreaSizeValid() )
1010 {
1011 ImplInvalidateSize();
1012 }
1013}
1014inline void SwFrame::InvalidatePrt()
1015{
1016 if ( isFramePrintAreaValid() )
1017 {
1018 ImplInvalidatePrt();
1019 }
1020}
1021inline void SwFrame::InvalidatePos()
1022{
1023 if ( isFrameAreaPositionValid() )
1024 {
1025 ImplInvalidatePos();
1026 }
1027}
1028inline void SwFrame::InvalidateLineNum()
1029{
1030 if ( mbValidLineNum )
1031 ImplInvalidateLineNum();
1032}
1033inline void SwFrame::InvalidateAll()
1034{
1035 if ( InvalidationAllowed( INVALID_ALL ) )
1036 {
1037 if ( isFrameAreaDefinitionValid() )
1038 {
1039 ImplInvalidatePos();
1040 }
1041
1042 setFrameAreaSizeValid(false);
1043 setFrameAreaPositionValid(false);
1044 setFramePrintAreaValid(false);
1045
1046 // #i28701#
1047 ActionOnInvalidation( INVALID_ALL );
1048 }
1049}
1050inline void SwFrame::InvalidateNextPos( bool bNoFootnote )
1051{
1052 if ( mpNext && !mpNext->IsSctFrame() )
1053 mpNext->InvalidatePos();
1054 else
1055 ImplInvalidateNextPos( bNoFootnote );
1056}
1057
1058inline void SwFrame::OptCalc() const
1059{
1060 if ( !isFrameAreaPositionValid() || !isFramePrintAreaValid() || !isFrameAreaSizeValid() )
1061 {
1062 const_cast<SwFrame*>(this)->OptPrepareMake();
1063 }
1064}
1065inline const SwPageFrame *SwFrame::FindPageFrame() const
1066{
1067 return const_cast<SwFrame*>(this)->FindPageFrame();
1068}
1069inline const SwFrame *SwFrame::FindColFrame() const
1070{
1071 return const_cast<SwFrame*>(this)->FindColFrame();
1072}
1073inline const SwFrame *SwFrame::FindFooterOrHeader() const
1074{
1075 return const_cast<SwFrame*>(this)->FindFooterOrHeader();
1076}
1077inline SwTabFrame *SwFrame::FindTabFrame()
1078{
1079 return IsInTab() ? ImplFindTabFrame() : nullptr;
1080}
1081inline const SwFootnoteBossFrame *SwFrame::FindFootnoteBossFrame( bool bFootnote ) const
1082{
1083 return const_cast<SwFrame*>(this)->FindFootnoteBossFrame( bFootnote );
1084}
1085inline SwFootnoteFrame *SwFrame::FindFootnoteFrame()
1086{
1087 return IsInFootnote() ? ImplFindFootnoteFrame() : nullptr;
1088}
1089inline SwFlyFrame *SwFrame::FindFlyFrame()
1090{
1091 return IsInFly() ? ImplFindFlyFrame() : nullptr;
1092}
1093inline SwSectionFrame *SwFrame::FindSctFrame()
1094{
1095 return IsInSct() ? ImplFindSctFrame() : nullptr;
1096}
1097
1098inline const SwBodyFrame *SwFrame::FindBodyFrame() const
1099{
1100 return IsInDocBody() ? ImplFindBodyFrame() : nullptr;
1101}
1102
1103inline const SwTabFrame *SwFrame::FindTabFrame() const
1104{
1105 return IsInTab() ? const_cast<SwFrame*>(this)->ImplFindTabFrame() : nullptr;
1106}
1107inline const SwFootnoteFrame *SwFrame::FindFootnoteFrame() const
1108{
1109 return IsInFootnote() ? const_cast<SwFrame*>(this)->ImplFindFootnoteFrame() : nullptr;
1110}
1111inline const SwFlyFrame *SwFrame::FindFlyFrame() const
1112{
1113 return IsInFly() ? const_cast<SwFrame*>(this)->ImplFindFlyFrame() : nullptr;
1114}
1115inline const SwSectionFrame *SwFrame::FindSctFrame() const
1116{
1117 return IsInSct() ? const_cast<SwFrame*>(this)->ImplFindSctFrame() : nullptr;
1118}
1119inline SwFrame *SwFrame::FindNext()
1120{
1121 if ( mpNext )
1122 return mpNext;
1123 else
1124 return FindNext_();
1125}
1126inline const SwFrame *SwFrame::FindNext() const
1127{
1128 if ( mpNext )
1129 return mpNext;
1130 else
1131 return const_cast<SwFrame*>(this)->FindNext_();
1132}
1133inline SwFrame *SwFrame::FindPrev()
1134{
1135 if ( mpPrev && !mpPrev->IsSctFrame() )
1136 return mpPrev;
1137 else
1138 return FindPrev_();
1139}
1140inline const SwFrame *SwFrame::FindPrev() const
1141{
1142 if ( mpPrev && !mpPrev->IsSctFrame() )
1143 return mpPrev;
1144 else
1145 return const_cast<SwFrame*>(this)->FindPrev_();
1146}
1147
1148inline bool SwFrame::IsLayoutFrame() const
1149{
1150 return bool(GetType() & FRM_LAYOUTSwFrameType(0x3bFF));
1151}
1152inline bool SwFrame::IsRootFrame() const
1153{
1154 return mnFrameType == SwFrameType::Root;
1155}
1156inline bool SwFrame::IsPageFrame() const
1157{
1158 return mnFrameType == SwFrameType::Page;
1159}
1160inline bool SwFrame::IsColumnFrame() const
1161{
1162 return mnFrameType == SwFrameType::Column;
1163}
1164inline bool SwFrame::IsFootnoteBossFrame() const
1165{
1166 return bool(GetType() & FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column));
1167}
1168inline bool SwFrame::IsHeaderFrame() const
1169{
1170 return mnFrameType == SwFrameType::Header;
1171}
1172inline bool SwFrame::IsFooterFrame() const
1173{
1174 return mnFrameType == SwFrameType::Footer;
1175}
1176inline bool SwFrame::IsFootnoteContFrame() const
1177{
1178 return mnFrameType == SwFrameType::FtnCont;
1179}
1180inline bool SwFrame::IsFootnoteFrame() const
1181{
1182 return mnFrameType == SwFrameType::Ftn;
1183}
1184inline bool SwFrame::IsBodyFrame() const
1185{
1186 return mnFrameType == SwFrameType::Body;
1187}
1188inline bool SwFrame::IsFlyFrame() const
1189{
1190 return mnFrameType == SwFrameType::Fly;
1191}
1192inline bool SwFrame::IsSctFrame() const
1193{
1194 return mnFrameType == SwFrameType::Section;
1195}
1196inline bool SwFrame::IsTabFrame() const
1197{
1198 return mnFrameType == SwFrameType::Tab;
1199}
1200inline bool SwFrame::IsRowFrame() const
1201{
1202 return mnFrameType == SwFrameType::Row;
1203}
1204inline bool SwFrame::IsCellFrame() const
1205{
1206 return mnFrameType == SwFrameType::Cell;
1207}
1208inline bool SwFrame::IsContentFrame() const
1209{
1210 return bool(GetType() & FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt));
1211}
1212inline bool SwFrame::IsTextFrame() const
1213{
1214 return mnFrameType == SwFrameType::Txt;
1215}
1216inline bool SwFrame::IsNoTextFrame() const
1217{
1218 return mnFrameType == SwFrameType::NoTxt;
1219}
1220inline bool SwFrame::IsFlowFrame() const
1221{
1222 return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section));
1223}
1224inline bool SwFrame::IsRetoucheFrame() const
1225{
1226 return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section|SwFrameType::Ftn));
1227}
1228inline bool SwFrame::IsAccessibleFrame() const
1229{
1230 return bool(GetType() & FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header |
SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType
::Tab | SwFrameType::Cell | SwFrameType::Txt)
)
;
9
Calling 'Wrap::operator bool'
12
Returning from 'Wrap::operator bool'
13
Returning zero, which participates in a condition later
1231}
1232
1233//use this to protect a SwFrame for a given scope from getting deleted
1234class SwFrameDeleteGuard
1235{
1236private:
1237 SwFrame *m_pForbidFrame;
1238public:
1239 //Flag pFrame for SwFrameDeleteGuard lifetime that we shouldn't delete
1240 //it in e.g. SwSectionFrame::MergeNext etc because we will need it
1241 //again after the SwFrameDeleteGuard dtor
1242 explicit SwFrameDeleteGuard(SwFrame* pFrame)
1243 : m_pForbidFrame((pFrame && !pFrame->IsDeleteForbidden()) ?
1244 pFrame : nullptr)
1245 {
1246 if (m_pForbidFrame)
1247 m_pForbidFrame->ForbidDelete();
1248 }
1249
1250 SwFrameDeleteGuard(const SwFrameDeleteGuard&) =delete;
1251
1252 ~SwFrameDeleteGuard()
1253 {
1254 if (m_pForbidFrame)
1255 m_pForbidFrame->AllowDelete();
1256 }
1257
1258 SwFrameDeleteGuard& operator=(const SwFrameDeleteGuard&) =delete;
1259};
1260
1261typedef long (SwFrame::*SwFrameGet)() const;
1262typedef bool (SwFrame::*SwFrameMax)( long );
1263typedef void (SwFrame::*SwFrameMakePos)( const SwFrame*, const SwFrame*, bool );
1264typedef long (*SwOperator)( long, long );
1265typedef void (SwFrame::*SwFrameSet)( long, long );
1266
1267struct SwRectFnCollection
1268{
1269 SwRectGet fnGetTop;
1270 SwRectGet fnGetBottom;
1271 SwRectGet fnGetLeft;
1272 SwRectGet fnGetRight;
1273 SwRectGet fnGetWidth;
1274 SwRectGet fnGetHeight;
1275 SwRectPoint fnGetPos;
1276 SwRectSize fnGetSize;
1277
1278 SwRectSet fnSetTop;
1279 SwRectSet fnSetBottom;
1280 SwRectSet fnSetLeft;
1281 SwRectSet fnSetRight;
1282 SwRectSet fnSetWidth;
1283 SwRectSet fnSetHeight;
1284
1285 SwRectSet fnSubTop;
1286 SwRectSet fnAddBottom;
1287 SwRectSet fnSubLeft;
1288 SwRectSet fnAddRight;
1289 SwRectSet fnAddWidth;
1290 SwRectSet fnAddHeight;
1291
1292 SwRectSet fnSetPosX;
1293 SwRectSet fnSetPosY;
1294
1295 SwFrameGet fnGetTopMargin;
1296 SwFrameGet fnGetBottomMargin;
1297 SwFrameGet fnGetLeftMargin;
1298 SwFrameGet fnGetRightMargin;
1299 SwFrameSet fnSetXMargins;
1300 SwFrameSet fnSetYMargins;
1301 SwFrameGet fnGetPrtTop;
1302 SwFrameGet fnGetPrtBottom;
1303 SwFrameGet fnGetPrtLeft;
1304 SwFrameGet fnGetPrtRight;
1305 SwRectDist fnTopDist;
1306 SwRectDist fnBottomDist;
1307 SwRectDist fnLeftDist;
1308 SwRectDist fnRightDist;
1309 SwFrameMax fnSetLimit;
1310 SwRectMax fnOverStep;
1311
1312 SwRectSetPos fnSetPos;
1313 SwFrameMakePos fnMakePos;
1314 SwOperator fnXDiff;
1315 SwOperator fnYDiff;
1316 SwOperator fnXInc;
1317 SwOperator fnYInc;
1318
1319 SwRectSetTwice fnSetLeftAndWidth;
1320 SwRectSetTwice fnSetTopAndHeight;
1321};
1322
1323typedef SwRectFnCollection* SwRectFn;
1324
1325// This class allows to use proper methods regardless of orientation (LTR/RTL, horizontal or vertical)
1326extern SwRectFn fnRectHori, fnRectVert, fnRectVertL2R, fnRectVertL2RB2T;
1327class SwRectFnSet {
1328public:
1329 explicit SwRectFnSet(const SwFrame *pFrame)
1330 : m_bVert(pFrame->IsVertical())
1331 , m_bVertL2R(pFrame->IsVertLR())
1332 , m_bVertL2RB2T(pFrame->IsVertLRBT())
1333 {
1334 m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori;
1335 }
1336
1337 void Refresh(const SwFrame *pFrame)
1338 {
1339 m_bVert = pFrame->IsVertical();
1340 m_bVertL2R = pFrame->IsVertLR();
1341 m_bVertL2RB2T = pFrame->IsVertLRBT();
1342 m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori;
1343 }
1344
1345 bool IsVert() const { return m_bVert; }
1346 bool IsVertL2R() const { return m_bVertL2R; }
1347 SwRectFn FnRect() const { return m_fnRect; }
1348
1349 bool PosDiff(const SwRect &rRect1, const SwRect &rRect2) const
1350 {
1351 return ((rRect1.*m_fnRect->fnGetTop)() != (rRect2.*m_fnRect->fnGetTop)()
1352 || (rRect1.*m_fnRect->fnGetLeft)() != (rRect2.*m_fnRect->fnGetLeft)());
1353 }
1354
1355 long GetTop (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetTop) (); }
1356 long GetBottom(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetBottom)(); }
1357 long GetLeft (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetLeft) (); }
1358 long GetRight (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetRight) (); }
1359 long GetWidth (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetWidth) (); }
1360 long GetHeight(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetHeight)(); }
1361 Point GetPos (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetPos) (); }
1362 Size GetSize (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetSize) (); }
1363
1364 void SetTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetTop) (nNew); }
1365 void SetBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetBottom)(nNew); }
1366 void SetLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetLeft) (nNew); }
1367 void SetRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetRight) (nNew); }
1368 void SetWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetWidth) (nNew); }
1369 void SetHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetHeight)(nNew); }
1370
1371 void SubTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubTop) (nNew); }
1372 void AddBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddBottom)(nNew); }
1373 void SubLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubLeft) (nNew); }
1374 void AddRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddRight) (nNew); }
1375 void AddWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddWidth) (nNew); }
1376 void AddHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddHeight)(nNew); }
1377
1378 void SetPosX(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosX)(nNew); }
1379 void SetPosY(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosY)(nNew); }
1380
1381 long GetTopMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetTopMargin) (); }
1382 long GetBottomMargin(const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetBottomMargin)(); }
1383 long GetLeftMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetLeftMargin) (); }
1384 long GetRightMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetRightMargin) (); }
1385 void SetXMargins(SwFrame& rFrame, long nLeft, long nRight) const { (rFrame.*m_fnRect->fnSetXMargins)(nLeft, nRight); }
1386 void SetYMargins(SwFrame& rFrame, long nTop, long nBottom) const { (rFrame.*m_fnRect->fnSetYMargins)(nTop, nBottom); }
1387 long GetPrtTop (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtTop) (); }
1388 long GetPrtBottom (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtBottom) (); }
1389 long GetPrtLeft (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtLeft) (); }
1390 long GetPrtRight (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtRight) (); }
1391 long TopDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnTopDist) (nPos); }
1392 long BottomDist(const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnBottomDist) (nPos); }
1393 long LeftDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnLeftDist) (nPos); }
1394 long RightDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnRightDist) (nPos); }
1395 void SetLimit (SwFrame& rFrame, long nNew) const { (rFrame.*m_fnRect->fnSetLimit) (nNew); }
1396 bool OverStep (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnOverStep) (nPos); }
1397
1398 void SetPos(SwRect& rRect, const Point& rNew) const { (rRect.*m_fnRect->fnSetPos)(rNew); }
1399 void MakePos(SwFrame& rFrame, const SwFrame* pUp, const SwFrame* pPrv, bool bNotify) const { (rFrame.*m_fnRect->fnMakePos)(pUp, pPrv, bNotify); }
1400 long XDiff(long n1, long n2) const { return (m_fnRect->fnXDiff) (n1, n2); }
1401 long YDiff(long n1, long n2) const { return (m_fnRect->fnYDiff) (n1, n2); }
1402 long XInc (long n1, long n2) const { return (m_fnRect->fnXInc) (n1, n2); }
1403 long YInc (long n1, long n2) const { return (m_fnRect->fnYInc) (n1, n2); }
1404
1405 void SetLeftAndWidth(SwRect& rRect, long nLeft, long nWidth) const { (rRect.*m_fnRect->fnSetLeftAndWidth)(nLeft, nWidth); }
1406 void SetTopAndHeight(SwRect& rRect, long nTop, long nHeight) const { (rRect.*m_fnRect->fnSetTopAndHeight)(nTop, nHeight); }
1407
1408private:
1409 bool m_bVert;
1410 bool m_bVertL2R;
1411 bool m_bVertL2RB2T;
1412 SwRectFn m_fnRect;
1413};
1414
1415#endif
1416
1417/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx

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#ifndef INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
21#define INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
22
23#include <sal/config.h>
24
25#include <cassert>
26#include <type_traits>
27
28#include <o3tl/underlyingenumvalue.hxx>
29#include <sal/types.h>
30
31namespace o3tl {
32
33namespace detail {
34
35template<typename T> constexpr
36typename std::enable_if<std::is_signed<T>::value, bool>::type isNonNegative(
37 T value)
38{
39 return value >= 0;
40}
41
42template<typename T> constexpr
43typename std::enable_if<std::is_unsigned<T>::value, bool>::type isNonNegative(T)
44{
45 return true;
46}
47
48}
49
50template<typename T> struct typed_flags {};
51
52/// Mark a (scoped) enumeration as a set of bit flags, with accompanying
53/// operations.
54///
55/// template<>
56/// struct o3tl::typed_flags<TheE>: o3tl::is_typed_flags<TheE, TheM> {};
57///
58/// All relevant values must be non-negative. (Typically, the enumeration's
59/// underlying type will either be fixed and unsigned, or it will be unfixed---
60/// and can thus default to a signed type---and all enumerators will have non-
61/// negative values.)
62///
63/// \param E the enumeration type.
64/// \param M the all-bits-set value for the bit flags.
65template<typename E, typename std::underlying_type<E>::type M>
66struct is_typed_flags {
67 static_assert(
68 M >= 0, "is_typed_flags expects only non-negative bit values");
69
70 typedef E Self;
71
72 class Wrap {
73 public:
74 typedef is_typed_flags Unwrapped;
75
76 explicit constexpr Wrap(typename std::underlying_type<E>::type value):
77 value_(value)
78 {
79 assert(detail::isNonNegative(value))(static_cast <bool> (detail::isNonNegative(value)) ? void
(0) : __assert_fail ("detail::isNonNegative(value)", "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 79, __extension__ __PRETTY_FUNCTION__))
;
80 assert((static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
81 static_cast<typename std::underlying_type<E>::type>(~0) == M(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
82 // avoid "operands don't affect result" warnings when M(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
83 // covers all bits of the underlying type(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
84 || (value & ~M) == 0)(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
;
85 }
86
87 constexpr operator E() const { return static_cast<E>(value_); }
88
89 explicit constexpr operator typename std::underlying_type<E>::type()
90 const
91 { return value_; }
92
93 explicit constexpr operator bool() const { return value_ != 0; }
10
Assuming field 'value_' is equal to 0
11
Returning zero, which participates in a condition later
94
95 private:
96 typename std::underlying_type<E>::type value_;
97 };
98
99 static typename std::underlying_type<E>::type const mask = M;
100};
101
102}
103
104template<typename E>
105constexpr typename o3tl::typed_flags<E>::Wrap operator ~(E rhs) {
106 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
107 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
108 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
;
109 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
110 o3tl::typed_flags<E>::mask
111 & ~o3tl::underlyingEnumValue(rhs));
112}
113
114template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ~(
115 typename o3tl::typed_flags<E>::Wrap rhs)
116{
117 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
118 o3tl::typed_flags<E>::mask
119 & ~o3tl::underlyingEnumValue<E>(rhs));
120}
121
122template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
123 E lhs, E rhs)
124{
125 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
126 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
127 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
;
128 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
129 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
130 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
;
131 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
132 o3tl::underlyingEnumValue(lhs)
133 ^ o3tl::underlyingEnumValue(rhs));
134}
135
136template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
137 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
138{
139 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
140 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
141 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
;
142 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
143 o3tl::underlyingEnumValue(lhs)
144 ^ o3tl::underlyingEnumValue<E>(rhs));
145}
146
147template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
148 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
149{
150 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
151 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
152 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
;
153 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
154 o3tl::underlyingEnumValue<E>(lhs)
155 ^ o3tl::underlyingEnumValue(rhs));
156}
157
158template<typename W> constexpr
159typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator ^(
160 W lhs, W rhs)
161{
162 return static_cast<W>(
163 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
164 ^ o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
165}
166
167template<typename E>
168constexpr typename o3tl::typed_flags<E>::Wrap operator &(E lhs, E rhs) {
169 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
170 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
171 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
;
172 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
173 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
174 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
;
175 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
176 o3tl::underlyingEnumValue(lhs)
177 & o3tl::underlyingEnumValue(rhs));
178}
179
180template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator &(
181 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
182{
183 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
184 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
185 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
;
186 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
187 o3tl::underlyingEnumValue(lhs)
188 & o3tl::underlyingEnumValue<E>(rhs));
189}
190
191template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator &(
192 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
193{
194 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
195 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
196 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
;
197 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
198 o3tl::underlyingEnumValue<E>(lhs)
199 & o3tl::underlyingEnumValue(rhs));
200}
201
202template<typename W> constexpr
203typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator &(
204 W lhs, W rhs)
205{
206 return static_cast<W>(
207 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
208 & o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
209}
210
211template<typename E>
212constexpr typename o3tl::typed_flags<E>::Wrap operator |(E lhs, E rhs) {
213 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
214 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
215 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
;
216 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
217 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
218 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
;
219 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
220 o3tl::underlyingEnumValue(lhs)
221 | o3tl::underlyingEnumValue(rhs));
222}
223
224template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator |(
225 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
226{
227 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
228 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
229 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
;
230 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
231 o3tl::underlyingEnumValue(lhs)
232 | o3tl::underlyingEnumValue<E>(rhs));
233}
234
235template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator |(
236 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
237{
238 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
239 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
240 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
;
241 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
242 o3tl::underlyingEnumValue<E>(lhs)
243 | o3tl::underlyingEnumValue(rhs));
244}
245
246template<typename W> constexpr
247typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator |(
248 W lhs, W rhs)
249{
250 return static_cast<W>(
251 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
252 | o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
253}
254
255template<typename E>
256inline typename o3tl::typed_flags<E>::Self operator &=(E & lhs, E rhs) {
257 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
258 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
259 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
;
260 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
261 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
262 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
;
263 lhs = lhs & rhs;
264 return lhs;
265}
266
267template<typename E>
268inline typename o3tl::typed_flags<E>::Self operator &=(
269 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
270{
271 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
272 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
273 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
;
274 lhs = lhs & rhs;
275 return lhs;
276}
277
278template<typename E>
279inline typename o3tl::typed_flags<E>::Self operator |=(E & lhs, E rhs) {
280 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
281 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
282 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
;
283 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
284 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
285 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
;
286 lhs = lhs | rhs;
287 return lhs;
288}
289
290template<typename E>
291inline typename o3tl::typed_flags<E>::Self operator |=(
292 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
293{
294 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
295 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
296 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
;
297 lhs = lhs | rhs;
298 return lhs;
299}
300
301template<typename E>
302inline typename o3tl::typed_flags<E>::Self operator ^=(E & lhs, E rhs) {
303 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
304 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
305 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
;
306 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
307 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
308 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
;
309 lhs = lhs ^ rhs;
310 return lhs;
311}
312
313template<typename E>
314inline typename o3tl::typed_flags<E>::Self operator ^=(
315 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
316{
317 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
318 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
319 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
;
320 lhs = lhs ^ rhs;
321 return lhs;
322}
323
324#endif /* INCLUDED_O3TL_TYPED_FLAGS_SET_HXX */
325
326/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

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

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-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/** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38#include <bits/stl_function.h>
39#include <bits/functional_hash.h>
40#if __cplusplus201703L > 201703L
41# include <compare>
42# include <ostream>
43#endif
44
45namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
46{
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
48
49 /**
50 * @addtogroup pointer_abstractions
51 * @{
52 */
53
54#if _GLIBCXX_USE_DEPRECATED1
55#pragma GCC diagnostic push
56#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
57 template<typename> class auto_ptr;
58#pragma GCC diagnostic pop
59#endif
60
61 /// Primary template of default_delete, used by unique_ptr for single objects
62 template<typename _Tp>
63 struct default_delete
64 {
65 /// Default constructor
66 constexpr default_delete() noexcept = default;
67
68 /** @brief Converting constructor.
69 *
70 * Allows conversion from a deleter for objects of another type, `_Up`,
71 * only if `_Up*` is convertible to `_Tp*`.
72 */
73 template<typename _Up,
74 typename = _Require<is_convertible<_Up*, _Tp*>>>
75 default_delete(const default_delete<_Up>&) noexcept { }
76
77 /// Calls `delete __ptr`
78 void
79 operator()(_Tp* __ptr) const
80 {
81 static_assert(!is_void<_Tp>::value,
82 "can't delete pointer to incomplete type");
83 static_assert(sizeof(_Tp)>0,
84 "can't delete pointer to incomplete type");
85 delete __ptr;
86 }
87 };
88
89 // _GLIBCXX_RESOLVE_LIB_DEFECTS
90 // DR 740 - omit specialization for array objects with a compile time length
91
92 /// Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
93 template<typename _Tp>
94 struct default_delete<_Tp[]>
95 {
96 public:
97 /// Default constructor
98 constexpr default_delete() noexcept = default;
99
100 /** @brief Converting constructor.
101 *
102 * Allows conversion from a deleter for arrays of another type, such as
103 * a const-qualified version of `_Tp`.
104 *
105 * Conversions from types derived from `_Tp` are not allowed because
106 * it is undefined to `delete[]` an array of derived types through a
107 * pointer to the base type.
108 */
109 template<typename _Up,
110 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
111 default_delete(const default_delete<_Up[]>&) noexcept { }
112
113 /// Calls `delete[] __ptr`
114 template<typename _Up>
115 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
116 operator()(_Up* __ptr) const
117 {
118 static_assert(sizeof(_Tp)>0,
119 "can't delete pointer to incomplete type");
120 delete [] __ptr;
121 }
122 };
123
124 /// @cond undocumented
125
126 // Manages the pointer and deleter of a unique_ptr
127 template <typename _Tp, typename _Dp>
128 class __uniq_ptr_impl
129 {
130 template <typename _Up, typename _Ep, typename = void>
131 struct _Ptr
132 {
133 using type = _Up*;
134 };
135
136 template <typename _Up, typename _Ep>
137 struct
138 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
139 {
140 using type = typename remove_reference<_Ep>::type::pointer;
141 };
142
143 public:
144 using _DeleterConstraint = enable_if<
145 __and_<__not_<is_pointer<_Dp>>,
146 is_default_constructible<_Dp>>::value>;
147
148 using pointer = typename _Ptr<_Tp, _Dp>::type;
149
150 static_assert( !is_rvalue_reference<_Dp>::value,
151 "unique_ptr's deleter type must be a function object type"
152 " or an lvalue reference type" );
153
154 __uniq_ptr_impl() = default;
155 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
156
157 template<typename _Del>
158 __uniq_ptr_impl(pointer __p, _Del&& __d)
159 : _M_t(__p, std::forward<_Del>(__d)) { }
160
161 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
162 : _M_t(std::move(__u._M_t))
163 { __u._M_ptr() = nullptr; }
164
165 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
166 {
167 reset(__u.release());
168 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
169 return *this;
170 }
171
172 pointer& _M_ptr() { return std::get<0>(_M_t); }
173 pointer _M_ptr() const { return std::get<0>(_M_t); }
174 _Dp& _M_deleter() { return std::get<1>(_M_t); }
175 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
176
177 void reset(pointer __p) noexcept
178 {
179 const pointer __old_p = _M_ptr();
180 _M_ptr() = __p;
181 if (__old_p)
182 _M_deleter()(__old_p);
183 }
184
185 pointer release() noexcept
186 {
187 pointer __p = _M_ptr();
188 _M_ptr() = nullptr;
189 return __p;
190 }
191
192 void
193 swap(__uniq_ptr_impl& __rhs) noexcept
194 {
195 using std::swap;
196 swap(this->_M_ptr(), __rhs._M_ptr());
197 swap(this->_M_deleter(), __rhs._M_deleter());
198 }
199
200 private:
201 tuple<pointer, _Dp> _M_t;
202 };
203
204 // Defines move construction + assignment as either defaulted or deleted.
205 template <typename _Tp, typename _Dp,
206 bool = is_move_constructible<_Dp>::value,
207 bool = is_move_assignable<_Dp>::value>
208 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
209 {
210 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
211 __uniq_ptr_data(__uniq_ptr_data&&) = default;
212 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
213 };
214
215 template <typename _Tp, typename _Dp>
216 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
217 {
218 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
219 __uniq_ptr_data(__uniq_ptr_data&&) = default;
220 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
221 };
222
223 template <typename _Tp, typename _Dp>
224 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
225 {
226 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
227 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
228 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
229 };
230
231 template <typename _Tp, typename _Dp>
232 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
233 {
234 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
235 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
236 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
237 };
238 /// @endcond
239
240 /// 20.7.1.2 unique_ptr for single objects.
241 template <typename _Tp, typename _Dp = default_delete<_Tp>>
242 class unique_ptr
243 {
244 template <typename _Up>
245 using _DeleterConstraint =
246 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
247
248 __uniq_ptr_data<_Tp, _Dp> _M_t;
249
250 public:
251 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
252 using element_type = _Tp;
253 using deleter_type = _Dp;
254
255 private:
256 // helper template for detecting a safe conversion from another
257 // unique_ptr
258 template<typename _Up, typename _Ep>
259 using __safe_conversion_up = __and_<
260 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
261 __not_<is_array<_Up>>
262 >;
263
264 public:
265 // Constructors.
266
267 /// Default constructor, creates a unique_ptr that owns nothing.
268 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
269 constexpr unique_ptr() noexcept
270 : _M_t()
271 { }
272
273 /** Takes ownership of a pointer.
274 *
275 * @param __p A pointer to an object of @c element_type
276 *
277 * The deleter will be value-initialized.
278 */
279 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
280 explicit
281 unique_ptr(pointer __p) noexcept
282 : _M_t(__p)
283 { }
284
285 /** Takes ownership of a pointer.
286 *
287 * @param __p A pointer to an object of @c element_type
288 * @param __d A reference to a deleter.
289 *
290 * The deleter will be initialized with @p __d
291 */
292 template<typename _Del = deleter_type,
293 typename = _Require<is_copy_constructible<_Del>>>
294 unique_ptr(pointer __p, const deleter_type& __d) noexcept
295 : _M_t(__p, __d) { }
296
297 /** Takes ownership of a pointer.
298 *
299 * @param __p A pointer to an object of @c element_type
300 * @param __d An rvalue reference to a (non-reference) deleter.
301 *
302 * The deleter will be initialized with @p std::move(__d)
303 */
304 template<typename _Del = deleter_type,
305 typename = _Require<is_move_constructible<_Del>>>
306 unique_ptr(pointer __p,
307 __enable_if_t<!is_lvalue_reference<_Del>::value,
308 _Del&&> __d) noexcept
309 : _M_t(__p, std::move(__d))
310 { }
311
312 template<typename _Del = deleter_type,
313 typename _DelUnref = typename remove_reference<_Del>::type>
314 unique_ptr(pointer,
315 __enable_if_t<is_lvalue_reference<_Del>::value,
316 _DelUnref&&>) = delete;
317
318 /// Creates a unique_ptr that owns nothing.
319 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
320 constexpr unique_ptr(nullptr_t) noexcept
321 : _M_t()
322 { }
323
324 // Move constructors.
325
326 /// Move constructor.
327 unique_ptr(unique_ptr&&) = default;
328
329 /** @brief Converting constructor from another type
330 *
331 * Requires that the pointer owned by @p __u is convertible to the
332 * type of pointer owned by this object, @p __u does not own an array,
333 * and @p __u has a compatible deleter type.
334 */
335 template<typename _Up, typename _Ep, typename = _Require<
336 __safe_conversion_up<_Up, _Ep>,
337 typename conditional<is_reference<_Dp>::value,
338 is_same<_Ep, _Dp>,
339 is_convertible<_Ep, _Dp>>::type>>
340 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
341 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
342 { }
343
344#if _GLIBCXX_USE_DEPRECATED1
345#pragma GCC diagnostic push
346#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
347 /// Converting constructor from @c auto_ptr
348 template<typename _Up, typename = _Require<
349 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
350 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
351#pragma GCC diagnostic pop
352#endif
353
354 /// Destructor, invokes the deleter if the stored pointer is not null.
355 ~unique_ptr() noexcept
356 {
357 static_assert(__is_invocable<deleter_type&, pointer>::value,
358 "unique_ptr's deleter must be invocable with a pointer");
359 auto& __ptr = _M_t._M_ptr();
360 if (__ptr != nullptr)
361 get_deleter()(std::move(__ptr));
362 __ptr = pointer();
363 }
364
365 // Assignment.
366
367 /** @brief Move assignment operator.
368 *
369 * Invokes the deleter if this object owns a pointer.
370 */
371 unique_ptr& operator=(unique_ptr&&) = default;
372
373 /** @brief Assignment from another type.
374 *
375 * @param __u The object to transfer ownership from, which owns a
376 * convertible pointer to a non-array object.
377 *
378 * Invokes the deleter if this object owns a pointer.
379 */
380 template<typename _Up, typename _Ep>
381 typename enable_if< __and_<
382 __safe_conversion_up<_Up, _Ep>,
383 is_assignable<deleter_type&, _Ep&&>
384 >::value,
385 unique_ptr&>::type
386 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
387 {
388 reset(__u.release());
389 get_deleter() = std::forward<_Ep>(__u.get_deleter());
390 return *this;
391 }
392
393 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
394 unique_ptr&
395 operator=(nullptr_t) noexcept
396 {
397 reset();
398 return *this;
399 }
400
401 // Observers.
402
403 /// Dereference the stored pointer.
404 typename add_lvalue_reference<element_type>::type
405 operator*() const
406 {
407 __glibcxx_assert(get() != pointer());
408 return *get();
409 }
410
411 /// Return the stored pointer.
412 pointer
413 operator->() const noexcept
414 {
415 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
416 return get();
417 }
418
419 /// Return the stored pointer.
420 pointer
421 get() const noexcept
422 { return _M_t._M_ptr(); }
423
424 /// Return a reference to the stored deleter.
425 deleter_type&
426 get_deleter() noexcept
427 { return _M_t._M_deleter(); }
428
429 /// Return a reference to the stored deleter.
430 const deleter_type&
431 get_deleter() const noexcept
432 { return _M_t._M_deleter(); }
433
434 /// Return @c true if the stored pointer is not null.
435 explicit operator bool() const noexcept
436 { return get() == pointer() ? false : true; }
16
Assuming the condition is false
17
'?' condition is false
18
Returning the value 1, which participates in a condition later
437
438 // Modifiers.
439
440 /// Release ownership of any stored pointer.
441 pointer
442 release() noexcept
443 { return _M_t.release(); }
444
445 /** @brief Replace the stored pointer.
446 *
447 * @param __p The new pointer to store.
448 *
449 * The deleter will be invoked if a pointer is already owned.
450 */
451 void
452 reset(pointer __p = pointer()) noexcept
453 {
454 static_assert(__is_invocable<deleter_type&, pointer>::value,
455 "unique_ptr's deleter must be invocable with a pointer");
456 _M_t.reset(std::move(__p));
457 }
458
459 /// Exchange the pointer and deleter with another object.
460 void
461 swap(unique_ptr& __u) noexcept
462 {
463 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
464 _M_t.swap(__u._M_t);
465 }
466
467 // Disable copy from lvalue.
468 unique_ptr(const unique_ptr&) = delete;
469 unique_ptr& operator=(const unique_ptr&) = delete;
470 };
471
472 /// 20.7.1.3 unique_ptr for array objects with a runtime length
473 // [unique.ptr.runtime]
474 // _GLIBCXX_RESOLVE_LIB_DEFECTS
475 // DR 740 - omit specialization for array objects with a compile time length
476 template<typename _Tp, typename _Dp>
477 class unique_ptr<_Tp[], _Dp>
478 {
479 template <typename _Up>
480 using _DeleterConstraint =
481 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
482
483 __uniq_ptr_data<_Tp, _Dp> _M_t;
484
485 template<typename _Up>
486 using __remove_cv = typename remove_cv<_Up>::type;
487
488 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
489 template<typename _Up>
490 using __is_derived_Tp
491 = __and_< is_base_of<_Tp, _Up>,
492 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
493
494 public:
495 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
496 using element_type = _Tp;
497 using deleter_type = _Dp;
498
499 // helper template for detecting a safe conversion from another
500 // unique_ptr
501 template<typename _Up, typename _Ep,
502 typename _UPtr = unique_ptr<_Up, _Ep>,
503 typename _UP_pointer = typename _UPtr::pointer,
504 typename _UP_element_type = typename _UPtr::element_type>
505 using __safe_conversion_up = __and_<
506 is_array<_Up>,
507 is_same<pointer, element_type*>,
508 is_same<_UP_pointer, _UP_element_type*>,
509 is_convertible<_UP_element_type(*)[], element_type(*)[]>
510 >;
511
512 // helper template for detecting a safe conversion from a raw pointer
513 template<typename _Up>
514 using __safe_conversion_raw = __and_<
515 __or_<__or_<is_same<_Up, pointer>,
516 is_same<_Up, nullptr_t>>,
517 __and_<is_pointer<_Up>,
518 is_same<pointer, element_type*>,
519 is_convertible<
520 typename remove_pointer<_Up>::type(*)[],
521 element_type(*)[]>
522 >
523 >
524 >;
525
526 // Constructors.
527
528 /// Default constructor, creates a unique_ptr that owns nothing.
529 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
530 constexpr unique_ptr() noexcept
531 : _M_t()
532 { }
533
534 /** Takes ownership of a pointer.
535 *
536 * @param __p A pointer to an array of a type safely convertible
537 * to an array of @c element_type
538 *
539 * The deleter will be value-initialized.
540 */
541 template<typename _Up,
542 typename _Vp = _Dp,
543 typename = _DeleterConstraint<_Vp>,
544 typename = typename enable_if<
545 __safe_conversion_raw<_Up>::value, bool>::type>
546 explicit
547 unique_ptr(_Up __p) noexcept
548 : _M_t(__p)
549 { }
550
551 /** Takes ownership of a pointer.
552 *
553 * @param __p A pointer to an array of a type safely convertible
554 * to an array of @c element_type
555 * @param __d A reference to a deleter.
556 *
557 * The deleter will be initialized with @p __d
558 */
559 template<typename _Up, typename _Del = deleter_type,
560 typename = _Require<__safe_conversion_raw<_Up>,
561 is_copy_constructible<_Del>>>
562 unique_ptr(_Up __p, const deleter_type& __d) noexcept
563 : _M_t(__p, __d) { }
564
565 /** Takes ownership of a pointer.
566 *
567 * @param __p A pointer to an array of a type safely convertible
568 * to an array of @c element_type
569 * @param __d A reference to a deleter.
570 *
571 * The deleter will be initialized with @p std::move(__d)
572 */
573 template<typename _Up, typename _Del = deleter_type,
574 typename = _Require<__safe_conversion_raw<_Up>,
575 is_move_constructible<_Del>>>
576 unique_ptr(_Up __p,
577 __enable_if_t<!is_lvalue_reference<_Del>::value,
578 _Del&&> __d) noexcept
579 : _M_t(std::move(__p), std::move(__d))
580 { }
581
582 template<typename _Up, typename _Del = deleter_type,
583 typename _DelUnref = typename remove_reference<_Del>::type,
584 typename = _Require<__safe_conversion_raw<_Up>>>
585 unique_ptr(_Up,
586 __enable_if_t<is_lvalue_reference<_Del>::value,
587 _DelUnref&&>) = delete;
588
589 /// Move constructor.
590 unique_ptr(unique_ptr&&) = default;
591
592 /// Creates a unique_ptr that owns nothing.
593 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
594 constexpr unique_ptr(nullptr_t) noexcept
595 : _M_t()
596 { }
597
598 template<typename _Up, typename _Ep, typename = _Require<
599 __safe_conversion_up<_Up, _Ep>,
600 typename conditional<is_reference<_Dp>::value,
601 is_same<_Ep, _Dp>,
602 is_convertible<_Ep, _Dp>>::type>>
603 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
604 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
605 { }
606
607 /// Destructor, invokes the deleter if the stored pointer is not null.
608 ~unique_ptr()
609 {
610 auto& __ptr = _M_t._M_ptr();
611 if (__ptr != nullptr)
612 get_deleter()(__ptr);
613 __ptr = pointer();
614 }
615
616 // Assignment.
617
618 /** @brief Move assignment operator.
619 *
620 * Invokes the deleter if this object owns a pointer.
621 */
622 unique_ptr&
623 operator=(unique_ptr&&) = default;
624
625 /** @brief Assignment from another type.
626 *
627 * @param __u The object to transfer ownership from, which owns a
628 * convertible pointer to an array object.
629 *
630 * Invokes the deleter if this object owns a pointer.
631 */
632 template<typename _Up, typename _Ep>
633 typename
634 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
635 is_assignable<deleter_type&, _Ep&&>
636 >::value,
637 unique_ptr&>::type
638 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
639 {
640 reset(__u.release());
641 get_deleter() = std::forward<_Ep>(__u.get_deleter());
642 return *this;
643 }
644
645 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
646 unique_ptr&
647 operator=(nullptr_t) noexcept
648 {
649 reset();
650 return *this;
651 }
652
653 // Observers.
654
655 /// Access an element of owned array.
656 typename std::add_lvalue_reference<element_type>::type
657 operator[](size_t __i) const
658 {
659 __glibcxx_assert(get() != pointer());
660 return get()[__i];
661 }
662
663 /// Return the stored pointer.
664 pointer
665 get() const noexcept
666 { return _M_t._M_ptr(); }
667
668 /// Return a reference to the stored deleter.
669 deleter_type&
670 get_deleter() noexcept
671 { return _M_t._M_deleter(); }
672
673 /// Return a reference to the stored deleter.
674 const deleter_type&
675 get_deleter() const noexcept
676 { return _M_t._M_deleter(); }
677
678 /// Return @c true if the stored pointer is not null.
679 explicit operator bool() const noexcept
680 { return get() == pointer() ? false : true; }
681
682 // Modifiers.
683
684 /// Release ownership of any stored pointer.
685 pointer
686 release() noexcept
687 { return _M_t.release(); }
688
689 /** @brief Replace the stored pointer.
690 *
691 * @param __p The new pointer to store.
692 *
693 * The deleter will be invoked if a pointer is already owned.
694 */
695 template <typename _Up,
696 typename = _Require<
697 __or_<is_same<_Up, pointer>,
698 __and_<is_same<pointer, element_type*>,
699 is_pointer<_Up>,
700 is_convertible<
701 typename remove_pointer<_Up>::type(*)[],
702 element_type(*)[]
703 >
704 >
705 >
706 >>
707 void
708 reset(_Up __p) noexcept
709 { _M_t.reset(std::move(__p)); }
710
711 void reset(nullptr_t = nullptr) noexcept
712 { reset(pointer()); }
713
714 /// Exchange the pointer and deleter with another object.
715 void
716 swap(unique_ptr& __u) noexcept
717 {
718 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
719 _M_t.swap(__u._M_t);
720 }
721
722 // Disable copy from lvalue.
723 unique_ptr(const unique_ptr&) = delete;
724 unique_ptr& operator=(const unique_ptr&) = delete;
725 };
726
727 /// @relates unique_ptr @{
728
729 /// Swap overload for unique_ptr
730 template<typename _Tp, typename _Dp>
731 inline
732#if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
733 // Constrained free swap overload, see p0185r1
734 typename enable_if<__is_swappable<_Dp>::value>::type
735#else
736 void
737#endif
738 swap(unique_ptr<_Tp, _Dp>& __x,
739 unique_ptr<_Tp, _Dp>& __y) noexcept
740 { __x.swap(__y); }
741
742#if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
743 template<typename _Tp, typename _Dp>
744 typename enable_if<!__is_swappable<_Dp>::value>::type
745 swap(unique_ptr<_Tp, _Dp>&,
746 unique_ptr<_Tp, _Dp>&) = delete;
747#endif
748
749 /// Equality operator for unique_ptr objects, compares the owned pointers
750 template<typename _Tp, typename _Dp,
751 typename _Up, typename _Ep>
752 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
753 operator==(const unique_ptr<_Tp, _Dp>& __x,
754 const unique_ptr<_Up, _Ep>& __y)
755 { return __x.get() == __y.get(); }
756
757 /// unique_ptr comparison with nullptr
758 template<typename _Tp, typename _Dp>
759 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
760 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
761 { return !__x; }
762
763#ifndef __cpp_lib_three_way_comparison
764 /// unique_ptr comparison with nullptr
765 template<typename _Tp, typename _Dp>
766 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
767 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
768 { return !__x; }
769
770 /// Inequality operator for unique_ptr objects, compares the owned pointers
771 template<typename _Tp, typename _Dp,
772 typename _Up, typename _Ep>
773 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
774 operator!=(const unique_ptr<_Tp, _Dp>& __x,
775 const unique_ptr<_Up, _Ep>& __y)
776 { return __x.get() != __y.get(); }
777
778 /// unique_ptr comparison with nullptr
779 template<typename _Tp, typename _Dp>
780 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
781 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
782 { return (bool)__x; }
783
784 /// unique_ptr comparison with nullptr
785 template<typename _Tp, typename _Dp>
786 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
787 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
788 { return (bool)__x; }
789#endif // three way comparison
790
791 /// Relational operator for unique_ptr objects, compares the owned pointers
792 template<typename _Tp, typename _Dp,
793 typename _Up, typename _Ep>
794 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
795 operator<(const unique_ptr<_Tp, _Dp>& __x,
796 const unique_ptr<_Up, _Ep>& __y)
797 {
798 typedef typename
799 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
800 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
801 return std::less<_CT>()(__x.get(), __y.get());
802 }
803
804 /// unique_ptr comparison with nullptr
805 template<typename _Tp, typename _Dp>
806 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
807 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
808 {
809 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
810 nullptr);
811 }
812
813 /// unique_ptr comparison with nullptr
814 template<typename _Tp, typename _Dp>
815 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
816 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
817 {
818 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
819 __x.get());
820 }
821
822 /// Relational operator for unique_ptr objects, compares the owned pointers
823 template<typename _Tp, typename _Dp,
824 typename _Up, typename _Ep>
825 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
826 operator<=(const unique_ptr<_Tp, _Dp>& __x,
827 const unique_ptr<_Up, _Ep>& __y)
828 { return !(__y < __x); }
829
830 /// unique_ptr comparison with nullptr
831 template<typename _Tp, typename _Dp>
832 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
833 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
834 { return !(nullptr < __x); }
835
836 /// unique_ptr comparison with nullptr
837 template<typename _Tp, typename _Dp>
838 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
839 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
840 { return !(__x < nullptr); }
841
842 /// Relational operator for unique_ptr objects, compares the owned pointers
843 template<typename _Tp, typename _Dp,
844 typename _Up, typename _Ep>
845 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
846 operator>(const unique_ptr<_Tp, _Dp>& __x,
847 const unique_ptr<_Up, _Ep>& __y)
848 { return (__y < __x); }
849
850 /// unique_ptr comparison with nullptr
851 template<typename _Tp, typename _Dp>
852 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
853 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
854 {
855 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
856 __x.get());
857 }
858
859 /// unique_ptr comparison with nullptr
860 template<typename _Tp, typename _Dp>
861 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
862 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
863 {
864 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
865 nullptr);
866 }
867
868 /// Relational operator for unique_ptr objects, compares the owned pointers
869 template<typename _Tp, typename _Dp,
870 typename _Up, typename _Ep>
871 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
872 operator>=(const unique_ptr<_Tp, _Dp>& __x,
873 const unique_ptr<_Up, _Ep>& __y)
874 { return !(__x < __y); }
875
876 /// unique_ptr comparison with nullptr
877 template<typename _Tp, typename _Dp>
878 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
879 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
880 { return !(__x < nullptr); }
881
882 /// unique_ptr comparison with nullptr
883 template<typename _Tp, typename _Dp>
884 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
885 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
886 { return !(nullptr < __x); }
887
888#ifdef __cpp_lib_three_way_comparison
889 template<typename _Tp, typename _Dp, typename _Up, typename _Ep>
890 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
891 typename unique_ptr<_Up, _Ep>::pointer>
892 inline
893 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
894 typename unique_ptr<_Up, _Ep>::pointer>
895 operator<=>(const unique_ptr<_Tp, _Dp>& __x,
896 const unique_ptr<_Up, _Ep>& __y)
897 { return compare_three_way()(__x.get(), __y.get()); }
898
899 template<typename _Tp, typename _Dp>
900 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
901 inline
902 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
903 operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
904 {
905 using pointer = typename unique_ptr<_Tp, _Dp>::pointer;
906 return compare_three_way()(__x.get(), static_cast<pointer>(nullptr));
907 }
908#endif
909 // @} relates unique_ptr
910
911 /// @cond undocumented
912 template<typename _Up, typename _Ptr = typename _Up::pointer,
913 bool = __poison_hash<_Ptr>::__enable_hash_call>
914 struct __uniq_ptr_hash
915#if ! _GLIBCXX_INLINE_VERSION0
916 : private __poison_hash<_Ptr>
917#endif
918 {
919 size_t
920 operator()(const _Up& __u) const
921 noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
922 { return hash<_Ptr>()(__u.get()); }
923 };
924
925 template<typename _Up, typename _Ptr>
926 struct __uniq_ptr_hash<_Up, _Ptr, false>
927 : private __poison_hash<_Ptr>
928 { };
929 /// @endcond
930
931 /// std::hash specialization for unique_ptr.
932 template<typename _Tp, typename _Dp>
933 struct hash<unique_ptr<_Tp, _Dp>>
934 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
935 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
936 { };
937
938#if __cplusplus201703L >= 201402L
939 /// @relates unique_ptr @{
940#define __cpp_lib_make_unique201304 201304
941
942 /// @cond undocumented
943
944 template<typename _Tp>
945 struct _MakeUniq
946 { typedef unique_ptr<_Tp> __single_object; };
947
948 template<typename _Tp>
949 struct _MakeUniq<_Tp[]>
950 { typedef unique_ptr<_Tp[]> __array; };
951
952 template<typename _Tp, size_t _Bound>
953 struct _MakeUniq<_Tp[_Bound]>
954 { struct __invalid_type { }; };
955
956 /// @endcond
957
958 /// std::make_unique for single objects
959 template<typename _Tp, typename... _Args>
960 inline typename _MakeUniq<_Tp>::__single_object
961 make_unique(_Args&&... __args)
962 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
963
964 /// std::make_unique for arrays of unknown bound
965 template<typename _Tp>
966 inline typename _MakeUniq<_Tp>::__array
967 make_unique(size_t __num)
968 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
969
970 /// Disable std::make_unique for arrays of known bound
971 template<typename _Tp, typename... _Args>
972 inline typename _MakeUniq<_Tp>::__invalid_type
973 make_unique(_Args&&...) = delete;
974 // @} relates unique_ptr
975#endif // C++14
976
977#if __cplusplus201703L > 201703L && __cpp_concepts
978 // _GLIBCXX_RESOLVE_LIB_DEFECTS
979 // 2948. unique_ptr does not define operator<< for stream output
980 /// Stream output operator for unique_ptr
981 template<typename _CharT, typename _Traits, typename _Tp, typename _Dp>
982 inline basic_ostream<_CharT, _Traits>&
983 operator<<(basic_ostream<_CharT, _Traits>& __os,
984 const unique_ptr<_Tp, _Dp>& __p)
985 requires requires { __os << __p.get(); }
986 {
987 __os << __p.get();
988 return __os;
989 }
990#endif // C++20
991
992 // @} group pointer_abstractions
993
994#if __cplusplus201703L >= 201703L
995 namespace __detail::__variant
996 {
997 template<typename> struct _Never_valueless_alt; // see <variant>
998
999 // Provide the strong exception-safety guarantee when emplacing a
1000 // unique_ptr into a variant.
1001 template<typename _Tp, typename _Del>
1002 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
1003 : std::true_type
1004 { };
1005 } // namespace __detail::__variant
1006#endif // C++17
1007
1008_GLIBCXX_END_NAMESPACE_VERSION
1009} // namespace
1010
1011#endif /* _UNIQUE_PTR_H */