Bug Summary

File:home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx
Warning:line 259, column 43
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 svdundo.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 SVXCORE_DLLIMPLEMENTATION -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -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/svx/inc -I /home/maarten/src/libreoffice/core/svx/source/inc -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/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/svx/sdi -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/svx/source/svdraw/svdundo.cxx

/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.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 <com/sun/star/drawing/FillStyle.hpp>
21
22#include <svx/svdundo.hxx>
23#include <svx/svdotext.hxx>
24#include <svx/svdobj.hxx>
25#include <svx/svdpage.hxx>
26#include <svx/svdlayer.hxx>
27#include <svx/svdmodel.hxx>
28#include <svx/svdview.hxx>
29#include <svx/xfillit0.hxx>
30#include <svx/strings.hrc>
31#include <svx/dialmgr.hxx>
32#include <svx/scene3d.hxx>
33#include <editeng/outlobj.hxx>
34#include <svx/svdogrp.hxx>
35#include <sdr/properties/itemsettools.hxx>
36#include <svx/sdr/properties/properties.hxx>
37#include <svx/svdocapt.hxx>
38#include <svl/whiter.hxx>
39#include <svx/e3dsceneupdater.hxx>
40#include <svx/svdviter.hxx>
41#include <svx/svdotable.hxx> // #i124389#
42#include <vcl/svapp.hxx>
43#include <sfx2/viewsh.hxx>
44#include <svx/svdoashp.hxx>
45
46
47// iterates over all views and unmarks this SdrObject if it is marked
48static void ImplUnmarkObject( SdrObject* pObj )
49{
50 SdrViewIter aIter( pObj );
51 for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
52 {
53 pView->MarkObj( pObj, pView->GetSdrPageView(), true );
54 }
55}
56
57SdrUndoAction::SdrUndoAction(SdrModel& rNewMod)
58 : rMod(rNewMod), m_nViewShellId(-1)
59{
60 if (SfxViewShell* pViewShell = SfxViewShell::Current())
61 m_nViewShellId = pViewShell->GetViewShellId();
62}
63
64SdrUndoAction::~SdrUndoAction() {}
65
66bool SdrUndoAction::CanRepeat(SfxRepeatTarget& rView) const
67{
68 SdrView* pV=dynamic_cast<SdrView*>( &rView );
69 if (pV!=nullptr) return CanSdrRepeat(*pV);
70 return false;
71}
72
73void SdrUndoAction::Repeat(SfxRepeatTarget& rView)
74{
75 SdrView* pV=dynamic_cast<SdrView*>( &rView );
76 if (pV!=nullptr) SdrRepeat(*pV);
77 DBG_ASSERT(pV!=nullptr,"Repeat: SfxRepeatTarget that was handed over is not a SdrView")do { if (true && (!(pV!=nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "77" ": "), "%s", "Repeat: SfxRepeatTarget that was handed over is not a SdrView"
); } } while (false)
;
78}
79
80OUString SdrUndoAction::GetRepeatComment(SfxRepeatTarget& rView) const
81{
82 SdrView* pV=dynamic_cast<SdrView*>( &rView );
83 if (pV!=nullptr) return GetSdrRepeatComment();
84 return OUString();
85}
86
87bool SdrUndoAction::CanSdrRepeat(SdrView& /*rView*/) const
88{
89 return false;
90}
91
92void SdrUndoAction::SdrRepeat(SdrView& /*rView*/)
93{
94}
95
96OUString SdrUndoAction::GetSdrRepeatComment() const
97{
98 return OUString();
99}
100
101ViewShellId SdrUndoAction::GetViewShellId() const
102{
103 return m_nViewShellId;
104}
105
106SdrUndoGroup::SdrUndoGroup(SdrModel& rNewMod)
107: SdrUndoAction(rNewMod),
108 eFunction(SdrRepeatFunc::NONE)
109{}
110
111SdrUndoGroup::~SdrUndoGroup()
112{
113}
114
115void SdrUndoGroup::AddAction(std::unique_ptr<SdrUndoAction> pAct)
116{
117 maActions.push_back(std::move(pAct));
118}
119
120void SdrUndoGroup::Undo()
121{
122 for (auto it = maActions.rbegin(); it != maActions.rend(); ++it)
123 (*it)->Undo();
124}
125
126void SdrUndoGroup::Redo()
127{
128 for (std::unique_ptr<SdrUndoAction> & pAction : maActions)
129 pAction->Redo();
130}
131
132OUString SdrUndoGroup::GetComment() const
133{
134 return aComment.replaceAll("%1", aObjDescription);
135}
136
137bool SdrUndoGroup::CanSdrRepeat(SdrView& rView) const
138{
139 switch (eFunction)
140 {
141 case SdrRepeatFunc::NONE : return false;
142 case SdrRepeatFunc::Delete : return rView.AreObjectsMarked();
143 case SdrRepeatFunc::CombinePolyPoly: return rView.IsCombinePossible();
144 case SdrRepeatFunc::CombineOnePoly : return rView.IsCombinePossible(true);
145 case SdrRepeatFunc::DismantlePolys : return rView.IsDismantlePossible();
146 case SdrRepeatFunc::DismantleLines : return rView.IsDismantlePossible(true);
147 case SdrRepeatFunc::ConvertToPoly : return rView.IsConvertToPolyObjPossible();
148 case SdrRepeatFunc::ConvertToPath : return rView.IsConvertToPathObjPossible();
149 case SdrRepeatFunc::Group : return rView.IsGroupPossible();
150 case SdrRepeatFunc::Ungroup : return rView.IsUnGroupPossible();
151 case SdrRepeatFunc::PutToTop : return rView.IsToTopPossible();
152 case SdrRepeatFunc::PutToBottom : return rView.IsToBtmPossible();
153 case SdrRepeatFunc::MoveToTop : return rView.IsToTopPossible();
154 case SdrRepeatFunc::MoveToBottom : return rView.IsToBtmPossible();
155 case SdrRepeatFunc::ReverseOrder : return rView.IsReverseOrderPossible();
156 case SdrRepeatFunc::ImportMtf : return rView.IsImportMtfPossible();
157 default: break;
158 } // switch
159 return false;
160}
161
162void SdrUndoGroup::SdrRepeat(SdrView& rView)
163{
164 switch (eFunction)
165 {
166 case SdrRepeatFunc::NONE : break;
167 case SdrRepeatFunc::Delete : rView.DeleteMarked(); break;
168 case SdrRepeatFunc::CombinePolyPoly : rView.CombineMarkedObjects(false); break;
169 case SdrRepeatFunc::CombineOnePoly : rView.CombineMarkedObjects(); break;
170 case SdrRepeatFunc::DismantlePolys : rView.DismantleMarkedObjects(); break;
171 case SdrRepeatFunc::DismantleLines : rView.DismantleMarkedObjects(true); break;
172 case SdrRepeatFunc::ConvertToPoly : rView.ConvertMarkedToPolyObj(); break;
173 case SdrRepeatFunc::ConvertToPath : rView.ConvertMarkedToPathObj(false); break;
174 case SdrRepeatFunc::Group : rView.GroupMarked(); break;
175 case SdrRepeatFunc::Ungroup : rView.UnGroupMarked(); break;
176 case SdrRepeatFunc::PutToTop : rView.PutMarkedToTop(); break;
177 case SdrRepeatFunc::PutToBottom : rView.PutMarkedToBtm(); break;
178 case SdrRepeatFunc::MoveToTop : rView.MovMarkedToTop(); break;
179 case SdrRepeatFunc::MoveToBottom : rView.MovMarkedToBtm(); break;
180 case SdrRepeatFunc::ReverseOrder : rView.ReverseOrderOfMarked(); break;
181 case SdrRepeatFunc::ImportMtf : rView.DoImportMarkedMtf(); break;
182 default: break;
183 } // switch
184}
185
186OUString SdrUndoGroup::GetSdrRepeatComment() const
187{
188 return aComment.replaceAll("%1", SvxResId(STR_ObjNameSingulPluralreinterpret_cast<char const *>("STR_ObjNameSingulPlural"
"\004" u8"Draw object(s)")
));
189}
190
191SdrUndoObj::SdrUndoObj(SdrObject& rNewObj)
192: SdrUndoAction(rNewObj.getSdrModelFromSdrObject())
193 ,pObj(&rNewObj)
194{
195}
196
197OUString SdrUndoObj::GetDescriptionStringForObject( const SdrObject& _rForObject, const char* pStrCacheID, bool bRepeat )
198{
199 const OUString rStr {SvxResId(pStrCacheID)};
200
201 const sal_Int32 nPos = rStr.indexOf("%1");
202 if (nPos < 0)
203 return rStr;
204
205 if (bRepeat)
206 return rStr.replaceAt(nPos, 2, SvxResId(STR_ObjNameSingulPluralreinterpret_cast<char const *>("STR_ObjNameSingulPlural"
"\004" u8"Draw object(s)")
));
207
208 return rStr.replaceAt(nPos, 2, _rForObject.TakeObjNameSingul());
209}
210
211OUString SdrUndoObj::ImpGetDescriptionStr(const char* pStrCacheID, bool bRepeat) const
212{
213 if ( pObj )
214 return GetDescriptionStringForObject( *pObj, pStrCacheID, bRepeat );
215 return OUString();
216}
217
218// common call method for possible change of the page when UNDO/REDO is triggered
219void SdrUndoObj::ImpShowPageOfThisObject()
220{
221 if(pObj && pObj->IsInserted() && pObj->getSdrPageFromSdrObject())
222 {
223 SdrHint aHint(SdrHintKind::SwitchToPage, *pObj, pObj->getSdrPageFromSdrObject());
224 pObj->getSdrModelFromSdrObject().Broadcast(aHint);
225 }
226}
227
228void SdrUndoAttrObj::ensureStyleSheetInStyleSheetPool(SfxStyleSheetBasePool& rStyleSheetPool, SfxStyleSheet& rSheet)
229{
230 SfxStyleSheetBase* pThere = rStyleSheetPool.Find(rSheet.GetName(), rSheet.GetFamily());
231
232 if(!pThere)
233 {
234 // re-insert remembered style which was removed in the meantime. To do this
235 // without assertion, do it without parent and set parent after insertion
236 const OUString aParent(rSheet.GetParent());
237
238 rSheet.SetParent(OUString());
239 rStyleSheetPool.Insert(&rSheet);
240 rSheet.SetParent(aParent);
241 }
242}
243
244SdrUndoAttrObj::SdrUndoAttrObj(SdrObject& rNewObj, bool bStyleSheet1, bool bSaveText)
3
Calling default constructor for 'unique_ptr<SdrUndoGroup, std::default_delete<SdrUndoGroup>>'
17
Returning from default constructor for 'unique_ptr<SdrUndoGroup, std::default_delete<SdrUndoGroup>>'
245 : SdrUndoObj(rNewObj)
246 , mxUndoStyleSheet()
247 , mxRedoStyleSheet()
248 , bHaveToTakeRedoSet(true)
249{
250 bStyleSheet = bStyleSheet1;
251
252 SdrObjList* pOL = rNewObj.GetSubList();
253 bool bIsGroup(pOL!=nullptr && pOL->GetObjCount());
18
Assuming the condition is true
254 bool bIs3DScene(bIsGroup && dynamic_cast< E3dScene* >(pObj) != nullptr);
19
Assuming 'bIsGroup' is true
20
Assuming the condition is false
21
Assuming pointer value is null
255
256 if(bIsGroup
21.1
'bIsGroup' is true
21.1
'bIsGroup' is true
21.1
'bIsGroup' is true
)
22
Taking true branch
257 {
258 // it's a group object!
259 pUndoGroup.reset(new SdrUndoGroup(pObj->getSdrModelFromSdrObject()));
23
Called C++ object pointer is null
260 const size_t nObjCount(pOL->GetObjCount());
261
262 for(size_t nObjNum = 0; nObjNum < nObjCount; ++nObjNum)
263 {
264 pUndoGroup->AddAction(
265 std::make_unique<SdrUndoAttrObj>(*pOL->GetObj(nObjNum), bStyleSheet1));
266 }
267 }
268
269 if(bIsGroup && !bIs3DScene)
270 return;
271
272 pUndoSet.reset( new SfxItemSet(pObj->GetMergedItemSet()) );
273
274 if(bStyleSheet)
275 mxUndoStyleSheet = pObj->GetStyleSheet();
276
277 if(bSaveText)
278 {
279 auto p = pObj->GetOutlinerParaObject();
280 if(p)
281 pTextUndo.reset( new OutlinerParaObject(*p) );
282 }
283}
284
285SdrUndoAttrObj::~SdrUndoAttrObj()
286{
287 pUndoSet.reset();
288 pRedoSet.reset();
289 pUndoGroup.reset();
290 pTextUndo.reset();
291 pTextRedo.reset();
292}
293
294void SdrUndoAttrObj::Undo()
295{
296 E3DModifySceneSnapRectUpdater aUpdater(pObj);
297 bool bIs3DScene(dynamic_cast< E3dScene* >(pObj) != nullptr);
298
299 // Trigger PageChangeCall
300 ImpShowPageOfThisObject();
301
302 if(!pUndoGroup || bIs3DScene)
303 {
304 if(bHaveToTakeRedoSet)
305 {
306 bHaveToTakeRedoSet = false;
307
308 pRedoSet.reset( new SfxItemSet(pObj->GetMergedItemSet()) );
309
310 if(bStyleSheet)
311 mxRedoStyleSheet = pObj->GetStyleSheet();
312
313 if(pTextUndo)
314 {
315 // #i8508#
316 auto p = pObj->GetOutlinerParaObject();
317 if(p)
318 pTextRedo.reset( new OutlinerParaObject(*p) );
319 }
320 }
321
322 if(bStyleSheet)
323 {
324 mxRedoStyleSheet = pObj->GetStyleSheet();
325 SfxStyleSheet* pSheet = dynamic_cast< SfxStyleSheet* >(mxUndoStyleSheet.get());
326
327 if(pSheet && pObj->getSdrModelFromSdrObject().GetStyleSheetPool())
328 {
329 ensureStyleSheetInStyleSheetPool(*pObj->getSdrModelFromSdrObject().GetStyleSheetPool(), *pSheet);
330 pObj->SetStyleSheet(pSheet, true);
331 }
332 else
333 {
334 OSL_ENSURE(false, "OOps, something went wrong in SdrUndoAttrObj (!)")do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "334" ": "), "%s", "OOps, something went wrong in SdrUndoAttrObj (!)"
); } } while (false)
;
335 }
336 }
337
338 sdr::properties::ItemChangeBroadcaster aItemChange(*pObj);
339
340 // Since ClearItem sets back everything to normal
341 // it also sets fit-to-size text to non-fit-to-size text and
342 // switches on autogrowheight (the default). That may lead to
343 // losing the geometry size info for the object when it is
344 // laid out again from AdjustTextFrameWidthAndHeight(). This makes
345 // rescuing the size of the object necessary.
346 const tools::Rectangle aSnapRect = pObj->GetSnapRect();
347 // SdrObjCustomShape::NbcSetSnapRect needs logic instead of snap rect
348 const tools::Rectangle aLogicRect = pObj->GetLogicRect();
349
350 if(pUndoSet)
351 {
352 if(dynamic_cast<const SdrCaptionObj*>( pObj) != nullptr)
353 {
354 // do a more smooth item deletion here, else the text
355 // rect will be reformatted, especially when information regarding
356 // vertical text is changed. When clearing only set items it's
357 // slower, but safer regarding such information (it's not changed
358 // usually)
359 SfxWhichIter aIter(*pUndoSet);
360 sal_uInt16 nWhich(aIter.FirstWhich());
361
362 while(nWhich)
363 {
364 if(SfxItemState::SET != pUndoSet->GetItemState(nWhich, false))
365 {
366 pObj->ClearMergedItem(nWhich);
367 }
368
369 nWhich = aIter.NextWhich();
370 }
371 }
372 else
373 {
374 pObj->ClearMergedItem();
375 }
376
377 pObj->SetMergedItemSet(*pUndoSet);
378 }
379
380 // Restore previous size here when it was changed.
381 if(aSnapRect != pObj->GetSnapRect())
382 {
383 if(dynamic_cast<const SdrObjCustomShape*>(pObj))
384 pObj->NbcSetSnapRect(aLogicRect);
385 else
386 pObj->NbcSetSnapRect(aSnapRect);
387 }
388
389 pObj->GetProperties().BroadcastItemChange(aItemChange);
390
391 if(pTextUndo)
392 {
393 pObj->SetOutlinerParaObject(std::make_unique<OutlinerParaObject>(*pTextUndo));
394 }
395 }
396
397 if(pUndoGroup)
398 {
399 pUndoGroup->Undo();
400 }
401}
402
403void SdrUndoAttrObj::Redo()
404{
405 E3DModifySceneSnapRectUpdater aUpdater(pObj);
406 bool bIs3DScene(dynamic_cast< E3dScene* >(pObj) != nullptr);
407
408 if(!pUndoGroup || bIs3DScene)
409 {
410 if(bStyleSheet)
411 {
412 mxUndoStyleSheet = pObj->GetStyleSheet();
413 SfxStyleSheet* pSheet = dynamic_cast< SfxStyleSheet* >(mxRedoStyleSheet.get());
414
415 if(pSheet && pObj->getSdrModelFromSdrObject().GetStyleSheetPool())
416 {
417 ensureStyleSheetInStyleSheetPool(*pObj->getSdrModelFromSdrObject().GetStyleSheetPool(), *pSheet);
418 pObj->SetStyleSheet(pSheet, true);
419 }
420 else
421 {
422 OSL_ENSURE(false, "OOps, something went wrong in SdrUndoAttrObj (!)")do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "422" ": "), "%s", "OOps, something went wrong in SdrUndoAttrObj (!)"
); } } while (false)
;
423 }
424 }
425
426 sdr::properties::ItemChangeBroadcaster aItemChange(*pObj);
427
428 const tools::Rectangle aSnapRect = pObj->GetSnapRect();
429 const tools::Rectangle aLogicRect = pObj->GetLogicRect();
430
431 if(pRedoSet)
432 {
433 if(dynamic_cast<const SdrCaptionObj*>( pObj) != nullptr)
434 {
435 // do a more smooth item deletion here, else the text
436 // rect will be reformatted, especially when information regarding
437 // vertical text is changed. When clearing only set items it's
438 // slower, but safer regarding such information (it's not changed
439 // usually)
440 SfxWhichIter aIter(*pRedoSet);
441 sal_uInt16 nWhich(aIter.FirstWhich());
442
443 while(nWhich)
444 {
445 if(SfxItemState::SET != pRedoSet->GetItemState(nWhich, false))
446 {
447 pObj->ClearMergedItem(nWhich);
448 }
449
450 nWhich = aIter.NextWhich();
451 }
452 }
453 else
454 {
455 pObj->ClearMergedItem();
456 }
457
458 pObj->SetMergedItemSet(*pRedoSet);
459 }
460
461 // Restore previous size here when it was changed.
462 if(aSnapRect != pObj->GetSnapRect())
463 {
464 if(dynamic_cast<const SdrObjCustomShape*>(pObj))
465 pObj->NbcSetSnapRect(aLogicRect);
466 else
467 pObj->NbcSetSnapRect(aSnapRect);
468 }
469
470 pObj->GetProperties().BroadcastItemChange(aItemChange);
471
472 // #i8508#
473 if(pTextRedo)
474 {
475 pObj->SetOutlinerParaObject(std::make_unique<OutlinerParaObject>(*pTextRedo));
476 }
477 }
478
479 if(pUndoGroup)
480 {
481 pUndoGroup->Redo();
482 }
483
484 // Trigger PageChangeCall
485 ImpShowPageOfThisObject();
486}
487
488OUString SdrUndoAttrObj::GetComment() const
489{
490 if(bStyleSheet)
491 {
492 return ImpGetDescriptionStr(STR_EditSetStylesheetreinterpret_cast<char const *>("STR_EditSetStylesheet" "\004"
u8"Apply Styles to %1")
);
493 }
494 else
495 {
496 return ImpGetDescriptionStr(STR_EditSetAttributesreinterpret_cast<char const *>("STR_EditSetAttributes" "\004"
u8"Apply attributes to %1")
);
497 }
498}
499
500OUString SdrUndoAttrObj::GetSdrRepeatComment() const
501{
502 if(bStyleSheet)
503 {
504 return ImpGetDescriptionStr(STR_EditSetStylesheetreinterpret_cast<char const *>("STR_EditSetStylesheet" "\004"
u8"Apply Styles to %1")
, true);
505 }
506 else
507 {
508 return ImpGetDescriptionStr(STR_EditSetAttributesreinterpret_cast<char const *>("STR_EditSetAttributes" "\004"
u8"Apply attributes to %1")
, true);
509 }
510}
511
512
513SdrUndoMoveObj::~SdrUndoMoveObj() {}
514
515void SdrUndoMoveObj::Undo()
516{
517 // Trigger PageChangeCall
518 ImpShowPageOfThisObject();
519
520 pObj->Move(Size(-aDistance.Width(),-aDistance.Height()));
521}
522
523void SdrUndoMoveObj::Redo()
524{
525 pObj->Move(Size(aDistance.Width(),aDistance.Height()));
526
527 // Trigger PageChangeCall
528 ImpShowPageOfThisObject();
529}
530
531OUString SdrUndoMoveObj::GetComment() const
532{
533 return ImpGetDescriptionStr(STR_EditMovereinterpret_cast<char const *>("STR_EditMove" "\004" u8"Move %1"
)
);
534}
535
536void SdrUndoMoveObj::SdrRepeat(SdrView& rView)
537{
538 rView.MoveMarkedObj(aDistance);
539}
540
541bool SdrUndoMoveObj::CanSdrRepeat(SdrView& rView) const
542{
543 return rView.AreObjectsMarked();
544}
545
546OUString SdrUndoMoveObj::GetSdrRepeatComment() const
547{
548 return ImpGetDescriptionStr(STR_EditMovereinterpret_cast<char const *>("STR_EditMove" "\004" u8"Move %1"
)
,true);
549}
550
551
552SdrUndoGeoObj::SdrUndoGeoObj(SdrObject& rNewObj)
553 : SdrUndoObj(rNewObj)
554 , mbSkipChangeLayout(false)
555{
556 SdrObjList* pOL=rNewObj.GetSubList();
557 if (pOL!=nullptr && pOL->GetObjCount() && dynamic_cast<const E3dScene* >( &rNewObj) == nullptr)
558 {
559 // this is a group object!
560 // If this were 3D scene, we'd only add an Undo for the scene itself
561 // (which we do elsewhere).
562 pUndoGroup.reset(new SdrUndoGroup(pObj->getSdrModelFromSdrObject()));
563 const size_t nObjCount = pOL->GetObjCount();
564 for (size_t nObjNum = 0; nObjNum<nObjCount; ++nObjNum) {
565 pUndoGroup->AddAction(std::make_unique<SdrUndoGeoObj>(*pOL->GetObj(nObjNum)));
566 }
567 }
568 else
569 {
570 pUndoGeo.reset(pObj->GetGeoData());
571 }
572}
573
574SdrUndoGeoObj::~SdrUndoGeoObj()
575{
576 pUndoGeo.reset();
577 pRedoGeo.reset();
578 pUndoGroup.reset();
579}
580
581void SdrUndoGeoObj::Undo()
582{
583 // Trigger PageChangeCall
584 ImpShowPageOfThisObject();
585
586 if(pUndoGroup)
587 {
588 pUndoGroup->Undo();
589
590 // only repaint, no objectchange
591 pObj->ActionChanged();
592 }
593 else
594 {
595 pRedoGeo.reset(pObj->GetGeoData());
596
597 auto pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pObj);
598 if (pTableObj && mbSkipChangeLayout)
599 pTableObj->SetSkipChangeLayout(true);
600 pObj->SetGeoData(*pUndoGeo);
601 if (pTableObj && mbSkipChangeLayout)
602 pTableObj->SetSkipChangeLayout(false);
603 }
604}
605
606void SdrUndoGeoObj::Redo()
607{
608 if(pUndoGroup)
609 {
610 pUndoGroup->Redo();
611
612 // only repaint, no objectchange
613 pObj->ActionChanged();
614 }
615 else
616 {
617 pUndoGeo.reset(pObj->GetGeoData());
618 pObj->SetGeoData(*pRedoGeo);
619 }
620
621 // Trigger PageChangeCall
622 ImpShowPageOfThisObject();
623}
624
625OUString SdrUndoGeoObj::GetComment() const
626{
627 return ImpGetDescriptionStr(STR_DragMethObjOwnreinterpret_cast<char const *>("STR_DragMethObjOwn" "\004"
u8"Geometrically change %1")
);
628}
629
630
631SdrUndoObjList::SdrUndoObjList(SdrObject& rNewObj, bool bOrdNumDirect)
632 : SdrUndoObj(rNewObj)
633 , bOwner(false)
634{
635 pObjList=pObj->getParentSdrObjListFromSdrObject();
636 if (bOrdNumDirect)
637 {
638 nOrdNum=pObj->GetOrdNumDirect();
639 }
640 else
641 {
642 nOrdNum=pObj->GetOrdNum();
643 }
644}
645
646SdrUndoObjList::~SdrUndoObjList()
647{
648 SolarMutexGuard aGuard;
649
650 if (pObj!=nullptr && IsOwner())
651 {
652 // Attribute have to go back to the regular Pool
653 SetOwner(false);
654
655 // now delete
656 SdrObject::Free( pObj );
657 }
658}
659
660void SdrUndoObjList::SetOwner(bool bNew)
661{
662 bOwner = bNew;
663}
664
665
666void SdrUndoRemoveObj::Undo()
667{
668 // Trigger PageChangeCall
669 ImpShowPageOfThisObject();
670
671 DBG_ASSERT(!pObj->IsInserted(),"UndoRemoveObj: pObj has already been inserted.")do { if (true && (!(!pObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "671" ": "), "%s", "UndoRemoveObj: pObj has already been inserted."
); } } while (false)
;
672 if (pObj->IsInserted())
673 return;
674
675 // #i11426#
676 // For UNDOs in Calc/Writer it is necessary to adapt the anchor
677 // position of the target object.
678 Point aOwnerAnchorPos(0, 0);
679
680 if (dynamic_cast< const SdrObjGroup* >(pObjList->getSdrObjectFromSdrObjList()) != nullptr)
681 {
682 aOwnerAnchorPos = pObjList->getSdrObjectFromSdrObjList()->GetAnchorPos();
683 }
684
685 E3DModifySceneSnapRectUpdater aUpdater(pObjList->getSdrObjectFromSdrObjList());
686 pObjList->InsertObject(pObj,nOrdNum);
687
688 // #i11426#
689 if(aOwnerAnchorPos.X() || aOwnerAnchorPos.Y())
690 {
691 pObj->NbcSetAnchorPos(aOwnerAnchorPos);
692 }
693}
694
695void SdrUndoRemoveObj::Redo()
696{
697 DBG_ASSERT(pObj->IsInserted(),"RedoRemoveObj: pObj is not inserted.")do { if (true && (!(pObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "697" ": "), "%s", "RedoRemoveObj: pObj is not inserted."
); } } while (false)
;
698 if (pObj->IsInserted())
699 {
700 ImplUnmarkObject( pObj );
701 E3DModifySceneSnapRectUpdater aUpdater(pObj);
702 pObjList->RemoveObject(pObj->GetOrdNum());
703 }
704
705 // Trigger PageChangeCall
706 ImpShowPageOfThisObject();
707}
708
709SdrUndoRemoveObj::~SdrUndoRemoveObj()
710{
711}
712
713
714void SdrUndoInsertObj::Undo()
715{
716 // Trigger PageChangeCall
717 ImpShowPageOfThisObject();
718
719 DBG_ASSERT(pObj->IsInserted(),"UndoInsertObj: pObj is not inserted.")do { if (true && (!(pObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "719" ": "), "%s", "UndoInsertObj: pObj is not inserted."
); } } while (false)
;
720 if (pObj->IsInserted())
721 {
722 ImplUnmarkObject( pObj );
723
724 SdrObject* pChkObj= pObjList->RemoveObject(pObj->GetOrdNum());
725 DBG_ASSERT(pChkObj==pObj,"UndoInsertObj: RemoveObjNum!=pObj")do { if (true && (!(pChkObj==pObj))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "725" ": "), "%s", "UndoInsertObj: RemoveObjNum!=pObj");
} } while (false)
;
726 }
727}
728
729void SdrUndoInsertObj::Redo()
730{
731 DBG_ASSERT(!pObj->IsInserted(),"RedoInsertObj: pObj is already inserted")do { if (true && (!(!pObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "731" ": "), "%s", "RedoInsertObj: pObj is already inserted"
); } } while (false)
;
732 if (!pObj->IsInserted())
733 {
734 // Restore anchor position of an object,
735 // which becomes a member of a group, because its cleared in method
736 // <InsertObject(..)>. Needed for correct Redo in Writer. (#i45952#)
737 Point aAnchorPos( 0, 0 );
738
739 if (dynamic_cast<const SdrObjGroup*>(pObjList->getSdrObjectFromSdrObjList()) != nullptr)
740 {
741 aAnchorPos = pObj->GetAnchorPos();
742 }
743
744 pObjList->InsertObject(pObj,nOrdNum);
745
746 // Arcs lose position when grouped (#i45952#)
747 if ( aAnchorPos.X() || aAnchorPos.Y() )
748 {
749 pObj->NbcSetAnchorPos( aAnchorPos );
750 }
751 }
752
753 // Trigger PageChangeCall
754 ImpShowPageOfThisObject();
755}
756
757SdrUndoDelObj::SdrUndoDelObj(SdrObject& rNewObj, bool bOrdNumDirect)
758: SdrUndoRemoveObj(rNewObj,bOrdNumDirect)
759{
760 SetOwner(true);
761}
762
763void SdrUndoDelObj::Undo()
764{
765 SdrUndoRemoveObj::Undo();
766 DBG_ASSERT(IsOwner(),"UndoDeleteObj: pObj does not belong to UndoAction")do { if (true && (!(IsOwner()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "766" ": "), "%s", "UndoDeleteObj: pObj does not belong to UndoAction"
); } } while (false)
;
767 SetOwner(false);
768}
769
770void SdrUndoDelObj::Redo()
771{
772 SdrUndoRemoveObj::Redo();
773 DBG_ASSERT(!IsOwner(),"RedoDeleteObj: pObj already belongs to UndoAction")do { if (true && (!(!IsOwner()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "773" ": "), "%s", "RedoDeleteObj: pObj already belongs to UndoAction"
); } } while (false)
;
774 SetOwner(true);
775}
776
777OUString SdrUndoDelObj::GetComment() const
778{
779 return ImpGetDescriptionStr(STR_EditDeletereinterpret_cast<char const *>("STR_EditDelete" "\004" u8"Delete %1"
)
);
780}
781
782void SdrUndoDelObj::SdrRepeat(SdrView& rView)
783{
784 rView.DeleteMarked();
785}
786
787bool SdrUndoDelObj::CanSdrRepeat(SdrView& rView) const
788{
789 return rView.AreObjectsMarked();
790}
791
792OUString SdrUndoDelObj::GetSdrRepeatComment() const
793{
794 return ImpGetDescriptionStr(STR_EditDeletereinterpret_cast<char const *>("STR_EditDelete" "\004" u8"Delete %1"
)
,true);
795}
796
797
798void SdrUndoNewObj::Undo()
799{
800 SdrUndoInsertObj::Undo();
801 DBG_ASSERT(!IsOwner(),"RedoNewObj: pObj already belongs to UndoAction")do { if (true && (!(!IsOwner()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "801" ": "), "%s", "RedoNewObj: pObj already belongs to UndoAction"
); } } while (false)
;
802 SetOwner(true);
803}
804
805void SdrUndoNewObj::Redo()
806{
807 SdrUndoInsertObj::Redo();
808 DBG_ASSERT(IsOwner(),"RedoNewObj: pObj does not belong to UndoAction")do { if (true && (!(IsOwner()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "808" ": "), "%s", "RedoNewObj: pObj does not belong to UndoAction"
); } } while (false)
;
809 SetOwner(false);
810}
811
812OUString SdrUndoNewObj::GetComment( const SdrObject& _rForObject )
813{
814 return GetDescriptionStringForObject( _rForObject, STR_UndoInsertObjreinterpret_cast<char const *>("STR_UndoInsertObj" "\004"
u8"Insert %1")
);
815}
816
817OUString SdrUndoNewObj::GetComment() const
818{
819 return ImpGetDescriptionStr(STR_UndoInsertObjreinterpret_cast<char const *>("STR_UndoInsertObj" "\004"
u8"Insert %1")
);
820}
821
822SdrUndoReplaceObj::SdrUndoReplaceObj(SdrObject& rOldObj1, SdrObject& rNewObj1)
823 : SdrUndoObj(rOldObj1)
824 , bOldOwner(false)
825 , bNewOwner(false)
826 , pNewObj(&rNewObj1)
827{
828 SetOldOwner(true);
829 pObjList=pObj->getParentSdrObjListFromSdrObject();
830}
831
832SdrUndoReplaceObj::~SdrUndoReplaceObj()
833{
834 if (pObj!=nullptr && IsOldOwner())
835 {
836 // Attribute have to go back into the Pool
837 SetOldOwner(false);
838
839 // now delete
840 SdrObject::Free( pObj );
841 }
842 if (pNewObj!=nullptr && IsNewOwner())
843 {
844 // Attribute have to go back into the Pool
845 SetNewOwner(false);
846
847 // now delete
848 SdrObject::Free( pNewObj );
849 }
850}
851
852void SdrUndoReplaceObj::Undo()
853{
854 // Trigger PageChangeCall
855 ImpShowPageOfThisObject();
856
857 if (IsOldOwner() && !IsNewOwner())
858 {
859 DBG_ASSERT(!pObj->IsInserted(),"SdrUndoReplaceObj::Undo(): Old object is already inserted!")do { if (true && (!(!pObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "859" ": "), "%s", "SdrUndoReplaceObj::Undo(): Old object is already inserted!"
); } } while (false)
;
860 DBG_ASSERT(pNewObj->IsInserted(),"SdrUndoReplaceObj::Undo(): New object is not inserted!")do { if (true && (!(pNewObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "860" ": "), "%s", "SdrUndoReplaceObj::Undo(): New object is not inserted!"
); } } while (false)
;
861 SetOldOwner(false);
862 SetNewOwner(true);
863
864 ImplUnmarkObject( pNewObj );
865 pObjList->ReplaceObject(pObj,pNewObj->GetOrdNum());
866 }
867 else
868 {
869 OSL_FAIL("SdrUndoReplaceObj::Undo(): Wrong IsMine flags. Did you call Undo twice?")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "869" ": "), "%s", "SdrUndoReplaceObj::Undo(): Wrong IsMine flags. Did you call Undo twice?"
); } } while (false)
;
870 }
871}
872
873void SdrUndoReplaceObj::Redo()
874{
875 if (!IsOldOwner() && IsNewOwner())
876 {
877 DBG_ASSERT(!pNewObj->IsInserted(),"SdrUndoReplaceObj::Redo(): New object is already inserted!!")do { if (true && (!(!pNewObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "877" ": "), "%s", "SdrUndoReplaceObj::Redo(): New object is already inserted!!"
); } } while (false)
;
878 DBG_ASSERT(pObj->IsInserted(),"SdrUndoReplaceObj::Redo(): Old object is not inserted!!")do { if (true && (!(pObj->IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "878" ": "), "%s", "SdrUndoReplaceObj::Redo(): Old object is not inserted!!"
); } } while (false)
;
879 SetOldOwner(true);
880 SetNewOwner(false);
881
882 ImplUnmarkObject( pObj );
883 pObjList->ReplaceObject(pNewObj,pObj->GetOrdNum());
884
885 }
886 else
887 {
888 OSL_FAIL("SdrUndoReplaceObj::Redo(): Wrong IsMine flags. Did you call Redo twice?")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "888" ": "), "%s", "SdrUndoReplaceObj::Redo(): Wrong IsMine flags. Did you call Redo twice?"
); } } while (false)
;
889 }
890
891 // Trigger PageChangeCall
892 ImpShowPageOfThisObject();
893}
894
895void SdrUndoReplaceObj::SetNewOwner(bool bNew)
896{
897 bNewOwner = bNew;
898}
899
900void SdrUndoReplaceObj::SetOldOwner(bool bNew)
901{
902 bOldOwner = bNew;
903}
904
905
906OUString SdrUndoCopyObj::GetComment() const
907{
908 return ImpGetDescriptionStr(STR_UndoCopyObjreinterpret_cast<char const *>("STR_UndoCopyObj" "\004"
u8"Copy %1")
);
909}
910
911
912// #i11702#
913
914SdrUndoObjectLayerChange::SdrUndoObjectLayerChange(SdrObject& rObj, SdrLayerID aOldLayer, SdrLayerID aNewLayer)
915 : SdrUndoObj(rObj)
916 , maOldLayer(aOldLayer)
917 , maNewLayer(aNewLayer)
918{
919}
920
921void SdrUndoObjectLayerChange::Undo()
922{
923 ImpShowPageOfThisObject();
924 pObj->SetLayer(maOldLayer);
925}
926
927void SdrUndoObjectLayerChange::Redo()
928{
929 pObj->SetLayer(maNewLayer);
930 ImpShowPageOfThisObject();
931}
932
933
934SdrUndoObjOrdNum::SdrUndoObjOrdNum(SdrObject& rNewObj, sal_uInt32 nOldOrdNum1, sal_uInt32 nNewOrdNum1)
935 : SdrUndoObj(rNewObj)
936 , nOldOrdNum(nOldOrdNum1)
937 , nNewOrdNum(nNewOrdNum1)
938{
939}
940
941void SdrUndoObjOrdNum::Undo()
942{
943 // Trigger PageChangeCall
944 ImpShowPageOfThisObject();
945
946 SdrObjList* pOL=pObj->getParentSdrObjListFromSdrObject();
947 if (pOL==nullptr)
948 {
949 OSL_FAIL("UndoObjOrdNum: pObj does not have an ObjList.")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "949" ": "), "%s", "UndoObjOrdNum: pObj does not have an ObjList."
); } } while (false)
;
950 return;
951 }
952 pOL->SetObjectOrdNum(nNewOrdNum,nOldOrdNum);
953}
954
955void SdrUndoObjOrdNum::Redo()
956{
957 SdrObjList* pOL=pObj->getParentSdrObjListFromSdrObject();
958 if (pOL==nullptr)
959 {
960 OSL_FAIL("RedoObjOrdNum: pObj does not have an ObjList.")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "960" ": "), "%s", "RedoObjOrdNum: pObj does not have an ObjList."
); } } while (false)
;
961 return;
962 }
963 pOL->SetObjectOrdNum(nOldOrdNum,nNewOrdNum);
964
965 // Trigger PageChangeCall
966 ImpShowPageOfThisObject();
967}
968
969OUString SdrUndoObjOrdNum::GetComment() const
970{
971 return ImpGetDescriptionStr(STR_UndoObjOrdNumreinterpret_cast<char const *>("STR_UndoObjOrdNum" "\004"
u8"Change object order of %1")
);
972}
973
974
975SdrUndoObjSetText::SdrUndoObjSetText(SdrObject& rNewObj, sal_Int32 nText)
976 : SdrUndoObj(rNewObj)
977 , bNewTextAvailable(false)
978 , bEmptyPresObj(false)
979 , mnText(nText)
980{
981 SdrText* pText = static_cast< SdrTextObj*>( &rNewObj )->getText(mnText);
982 if( pText && pText->GetOutlinerParaObject() )
983 pOldText.reset( new OutlinerParaObject(*pText->GetOutlinerParaObject()) );
984
985 bEmptyPresObj = rNewObj.IsEmptyPresObj();
986}
987
988SdrUndoObjSetText::~SdrUndoObjSetText()
989{
990 pOldText.reset();
991 pNewText.reset();
992}
993
994void SdrUndoObjSetText::AfterSetText()
995{
996 if (!bNewTextAvailable)
997 {
998 SdrText* pText = static_cast< SdrTextObj*>( pObj )->getText(mnText);
999 if( pText && pText->GetOutlinerParaObject() )
1000 pNewText.reset( new OutlinerParaObject(*pText->GetOutlinerParaObject()) );
1001 bNewTextAvailable=true;
1002 }
1003}
1004
1005void SdrUndoObjSetText::Undo()
1006{
1007 // only works with SdrTextObj
1008 SdrTextObj* pTarget = dynamic_cast< SdrTextObj* >(pObj);
1009
1010 if(!pTarget)
1011 {
1012 OSL_ENSURE(false, "SdrUndoObjSetText::Undo with SdrObject not based on SdrTextObj (!)")do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1012" ": "), "%s", "SdrUndoObjSetText::Undo with SdrObject not based on SdrTextObj (!)"
); } } while (false)
;
1013 return;
1014 }
1015
1016 // Trigger PageChangeCall
1017 ImpShowPageOfThisObject();
1018
1019 // save old text for Redo
1020 if(!bNewTextAvailable)
1021 {
1022 AfterSetText();
1023 }
1024
1025 SdrText* pText = pTarget->getText(mnText);
1026 if (pText)
1027 {
1028 // copy text for Undo, because the original now belongs to SetOutlinerParaObject()
1029 std::unique_ptr<OutlinerParaObject> pText1( pOldText ? new OutlinerParaObject(*pOldText) : nullptr );
1030 pTarget->NbcSetOutlinerParaObjectForText(std::move(pText1), pText);
1031 }
1032
1033 pTarget->SetEmptyPresObj(bEmptyPresObj);
1034 pTarget->ActionChanged();
1035
1036 // #i124389# if it's a table, also need to relayout TextFrame
1037 if(dynamic_cast< sdr::table::SdrTableObj* >(pTarget) != nullptr)
1038 {
1039 pTarget->NbcAdjustTextFrameWidthAndHeight();
1040 }
1041
1042 // #i122410# SetOutlinerParaObject at SdrText does not trigger a
1043 // BroadcastObjectChange, but it is needed to make evtl. SlideSorters
1044 // update their preview.
1045 pTarget->BroadcastObjectChange();
1046}
1047
1048void SdrUndoObjSetText::Redo()
1049{
1050 // only works with SdrTextObj
1051 SdrTextObj* pTarget = dynamic_cast< SdrTextObj* >(pObj);
1052
1053 if(!pTarget)
1054 {
1055 OSL_ENSURE(false, "SdrUndoObjSetText::Redo with SdrObject not based on SdrTextObj (!)")do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1055" ": "), "%s", "SdrUndoObjSetText::Redo with SdrObject not based on SdrTextObj (!)"
); } } while (false)
;
1056 return;
1057 }
1058
1059 SdrText* pText = pTarget->getText(mnText);
1060 if (pText)
1061 {
1062 // copy text for Undo, because the original now belongs to SetOutlinerParaObject()
1063 std::unique_ptr<OutlinerParaObject> pText1( pNewText ? new OutlinerParaObject(*pNewText) : nullptr );
1064 pTarget->NbcSetOutlinerParaObjectForText( std::move(pText1), pText );
1065 }
1066
1067 pTarget->ActionChanged();
1068
1069 // #i124389# if it's a table, also need to relayout TextFrame
1070 if(dynamic_cast< sdr::table::SdrTableObj* >(pTarget) != nullptr)
1071 {
1072 pTarget->NbcAdjustTextFrameWidthAndHeight();
1073 }
1074
1075 // #i122410# NbcSetOutlinerParaObjectForText at SdrTextObj does not trigger a
1076 // BroadcastObjectChange, but it is needed to make evtl. SlideSorters
1077 // update their preview.
1078 pTarget->BroadcastObjectChange();
1079
1080 // Trigger PageChangeCall
1081 ImpShowPageOfThisObject();
1082}
1083
1084OUString SdrUndoObjSetText::GetComment() const
1085{
1086 return ImpGetDescriptionStr(STR_UndoObjSetTextreinterpret_cast<char const *>("STR_UndoObjSetText" "\004"
u8"Edit text of %1")
);
1087}
1088
1089OUString SdrUndoObjSetText::GetSdrRepeatComment() const
1090{
1091 return ImpGetDescriptionStr(STR_UndoObjSetTextreinterpret_cast<char const *>("STR_UndoObjSetText" "\004"
u8"Edit text of %1")
);
1092}
1093
1094void SdrUndoObjSetText::SdrRepeat(SdrView& rView)
1095{
1096 if (!(bNewTextAvailable && rView.AreObjectsMarked()))
1097 return;
1098
1099 const SdrMarkList& rML=rView.GetMarkedObjectList();
1100
1101 const bool bUndo = rView.IsUndoEnabled();
1102 if( bUndo )
1103 {
1104 OUString aStr = ImpGetDescriptionStr(STR_UndoObjSetTextreinterpret_cast<char const *>("STR_UndoObjSetText" "\004"
u8"Edit text of %1")
);
1105 rView.BegUndo(aStr);
1106 }
1107
1108 const size_t nCount=rML.GetMarkCount();
1109 for (size_t nm=0; nm<nCount; ++nm)
1110 {
1111 SdrObject* pObj2=rML.GetMark(nm)->GetMarkedSdrObj();
1112 SdrTextObj* pTextObj=dynamic_cast<SdrTextObj*>( pObj2 );
1113 if (pTextObj!=nullptr)
1114 {
1115 if( bUndo )
1116 rView.AddUndo(std::make_unique<SdrUndoObjSetText>(*pTextObj,0));
1117
1118 std::unique_ptr<OutlinerParaObject> pText1;
1119 if (pNewText)
1120 pText1.reset(new OutlinerParaObject(*pNewText));
1121 pTextObj->SetOutlinerParaObject(std::move(pText1));
1122 }
1123 }
1124
1125 if( bUndo )
1126 rView.EndUndo();
1127}
1128
1129bool SdrUndoObjSetText::CanSdrRepeat(SdrView& rView) const
1130{
1131 bool bOk = false;
1132 if (bNewTextAvailable && rView.AreObjectsMarked()) {
1133 bOk=true;
1134 }
1135 return bOk;
1136}
1137
1138// Undo/Redo for setting object's name (#i73249#)
1139SdrUndoObjStrAttr::SdrUndoObjStrAttr( SdrObject& rNewObj,
1140 const ObjStrAttrType eObjStrAttr,
1141 const OUString& sOldStr,
1142 const OUString& sNewStr)
1143 : SdrUndoObj( rNewObj )
1144 , meObjStrAttr( eObjStrAttr )
1145 , msOldStr( sOldStr )
1146 , msNewStr( sNewStr )
1147{
1148}
1149
1150void SdrUndoObjStrAttr::Undo()
1151{
1152 ImpShowPageOfThisObject();
1153
1154 switch ( meObjStrAttr )
1155 {
1156 case ObjStrAttrType::Name:
1157 pObj->SetName( msOldStr );
1158 break;
1159 case ObjStrAttrType::Title:
1160 pObj->SetTitle( msOldStr );
1161 break;
1162 case ObjStrAttrType::Description:
1163 pObj->SetDescription( msOldStr );
1164 break;
1165 }
1166}
1167
1168void SdrUndoObjStrAttr::Redo()
1169{
1170 switch ( meObjStrAttr )
1171 {
1172 case ObjStrAttrType::Name:
1173 pObj->SetName( msNewStr );
1174 break;
1175 case ObjStrAttrType::Title:
1176 pObj->SetTitle( msNewStr );
1177 break;
1178 case ObjStrAttrType::Description:
1179 pObj->SetDescription( msNewStr );
1180 break;
1181 }
1182
1183 ImpShowPageOfThisObject();
1184}
1185
1186OUString SdrUndoObjStrAttr::GetComment() const
1187{
1188 OUString aStr;
1189 switch ( meObjStrAttr )
1190 {
1191 case ObjStrAttrType::Name:
1192 aStr = ImpGetDescriptionStr( STR_UndoObjNamereinterpret_cast<char const *>("STR_UndoObjName" "\004"
u8"Change object name of %1 to")
) +
1193 " '" + msNewStr + "'";
1194 break;
1195 case ObjStrAttrType::Title:
1196 aStr = ImpGetDescriptionStr( STR_UndoObjTitlereinterpret_cast<char const *>("STR_UndoObjTitle" "\004"
u8"Change object title of %1")
);
1197 break;
1198 case ObjStrAttrType::Description:
1199 aStr = ImpGetDescriptionStr( STR_UndoObjDescriptionreinterpret_cast<char const *>("STR_UndoObjDescription"
"\004" u8"Change object description of %1")
);
1200 break;
1201 }
1202
1203 return aStr;
1204}
1205
1206
1207SdrUndoLayer::SdrUndoLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
1208 : SdrUndoAction(rNewModel)
1209 , pLayer(rNewLayerAdmin.GetLayer(nLayerNum))
1210 , pLayerAdmin(&rNewLayerAdmin)
1211 , nNum(nLayerNum)
1212 , bItsMine(false)
1213{
1214}
1215
1216SdrUndoLayer::~SdrUndoLayer()
1217{
1218 if (bItsMine)
1219 {
1220 delete pLayer;
1221 }
1222}
1223
1224
1225void SdrUndoNewLayer::Undo()
1226{
1227 DBG_ASSERT(!bItsMine,"SdrUndoNewLayer::Undo(): Layer already belongs to UndoAction.")do { if (true && (!(!bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1227" ": "), "%s", "SdrUndoNewLayer::Undo(): Layer already belongs to UndoAction."
); } } while (false)
;
1228 bItsMine=true;
1229 SdrLayer* pCmpLayer= pLayerAdmin->RemoveLayer(nNum).release();
1230 DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoNewLayer::Undo(): Removed layer is != pLayer.")do { if (true && (!(pCmpLayer==pLayer))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1230" ": "), "%s", "SdrUndoNewLayer::Undo(): Removed layer is != pLayer."
); } } while (false)
;
1231}
1232
1233void SdrUndoNewLayer::Redo()
1234{
1235 DBG_ASSERT(bItsMine,"SdrUndoNewLayer::Undo(): Layer does not belong to UndoAction.")do { if (true && (!(bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1235" ": "), "%s", "SdrUndoNewLayer::Undo(): Layer does not belong to UndoAction."
); } } while (false)
;
1236 bItsMine=false;
1237 pLayerAdmin->InsertLayer(std::unique_ptr<SdrLayer>(pLayer),nNum);
1238}
1239
1240OUString SdrUndoNewLayer::GetComment() const
1241{
1242 return SvxResId(STR_UndoNewLayerreinterpret_cast<char const *>("STR_UndoNewLayer" "\004"
u8"Insert Layer")
);
1243}
1244
1245
1246void SdrUndoDelLayer::Undo()
1247{
1248 DBG_ASSERT(bItsMine,"SdrUndoDelLayer::Undo(): Layer does not belong to UndoAction.")do { if (true && (!(bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1248" ": "), "%s", "SdrUndoDelLayer::Undo(): Layer does not belong to UndoAction."
); } } while (false)
;
1249 bItsMine=false;
1250 pLayerAdmin->InsertLayer(std::unique_ptr<SdrLayer>(pLayer),nNum);
1251}
1252
1253void SdrUndoDelLayer::Redo()
1254{
1255 DBG_ASSERT(!bItsMine,"SdrUndoDelLayer::Undo(): Layer already belongs to UndoAction.")do { if (true && (!(!bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1255" ": "), "%s", "SdrUndoDelLayer::Undo(): Layer already belongs to UndoAction."
); } } while (false)
;
1256 bItsMine=true;
1257 SdrLayer* pCmpLayer= pLayerAdmin->RemoveLayer(nNum).release();
1258 DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoDelLayer::Redo(): Removed layer is != pLayer.")do { if (true && (!(pCmpLayer==pLayer))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1258" ": "), "%s", "SdrUndoDelLayer::Redo(): Removed layer is != pLayer."
); } } while (false)
;
1259}
1260
1261OUString SdrUndoDelLayer::GetComment() const
1262{
1263 return SvxResId(STR_UndoDelLayerreinterpret_cast<char const *>("STR_UndoDelLayer" "\004"
u8"Delete layer")
);
1264}
1265
1266
1267SdrUndoPage::SdrUndoPage(SdrPage& rNewPg)
1268: SdrUndoAction(rNewPg.getSdrModelFromSdrPage())
1269 ,mrPage(rNewPg)
1270{
1271}
1272
1273void SdrUndoPage::ImpInsertPage(sal_uInt16 nNum)
1274{
1275 DBG_ASSERT(!mrPage.IsInserted(),"SdrUndoPage::ImpInsertPage(): mrPage is already inserted.")do { if (true && (!(!mrPage.IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1275" ": "), "%s", "SdrUndoPage::ImpInsertPage(): mrPage is already inserted."
); } } while (false)
;
1276 if (!mrPage.IsInserted())
1277 {
1278 if (mrPage.IsMasterPage())
1279 {
1280 rMod.InsertMasterPage(&mrPage,nNum);
1281 }
1282 else
1283 {
1284 rMod.InsertPage(&mrPage,nNum);
1285 }
1286 }
1287}
1288
1289void SdrUndoPage::ImpRemovePage(sal_uInt16 nNum)
1290{
1291 DBG_ASSERT(mrPage.IsInserted(),"SdrUndoPage::ImpRemovePage(): mrPage is not inserted.")do { if (true && (!(mrPage.IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1291" ": "), "%s", "SdrUndoPage::ImpRemovePage(): mrPage is not inserted."
); } } while (false)
;
1292 if (!mrPage.IsInserted())
1293 return;
1294
1295 SdrPage* pChkPg=nullptr;
1296 if (mrPage.IsMasterPage())
1297 {
1298 pChkPg=rMod.RemoveMasterPage(nNum);
1299 }
1300 else
1301 {
1302 pChkPg=rMod.RemovePage(nNum);
1303 }
1304 DBG_ASSERT(pChkPg==&mrPage,"SdrUndoPage::ImpRemovePage(): RemovePage!=&mrPage")do { if (true && (!(pChkPg==&mrPage))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1304" ": "), "%s", "SdrUndoPage::ImpRemovePage(): RemovePage!=&mrPage"
); } } while (false)
;
1305}
1306
1307void SdrUndoPage::ImpMovePage(sal_uInt16 nOldNum, sal_uInt16 nNewNum)
1308{
1309 DBG_ASSERT(mrPage.IsInserted(),"SdrUndoPage::ImpMovePage(): mrPage is not inserted.")do { if (true && (!(mrPage.IsInserted()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1309" ": "), "%s", "SdrUndoPage::ImpMovePage(): mrPage is not inserted."
); } } while (false)
;
1310 if (mrPage.IsInserted())
1311 {
1312 if (mrPage.IsMasterPage())
1313 {
1314 rMod.MoveMasterPage(nOldNum,nNewNum);
1315 }
1316 else
1317 {
1318 rMod.MovePage(nOldNum,nNewNum);
1319 }
1320 }
1321}
1322
1323OUString SdrUndoPage::ImpGetDescriptionStr(const char* pStrCacheID)
1324{
1325 return SvxResId(pStrCacheID);
1326}
1327
1328
1329SdrUndoPageList::SdrUndoPageList(SdrPage& rNewPg)
1330 : SdrUndoPage(rNewPg)
1331 , bItsMine(false)
1332{
1333 nPageNum=rNewPg.GetPageNum();
1334}
1335
1336SdrUndoPageList::~SdrUndoPageList()
1337{
1338 if(bItsMine)
1339 {
1340 delete &mrPage;
1341 }
1342}
1343
1344
1345SdrUndoDelPage::SdrUndoDelPage(SdrPage& rNewPg)
1346 : SdrUndoPageList(rNewPg)
1347 , mbHasFillBitmap(false)
1348{
1349 bItsMine = true;
1350
1351 // keep fill bitmap separately to remove it from pool if not used elsewhere
1352 if (mrPage.IsMasterPage())
1353 {
1354 SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
1355 if (pStyleSheet)
1356 queryFillBitmap(pStyleSheet->GetItemSet());
1357 }
1358 else
1359 {
1360 queryFillBitmap(mrPage.getSdrPageProperties().GetItemSet());
1361 }
1362 if (bool(mpFillBitmapItem))
1363 clearFillBitmap();
1364
1365 // now remember the master page relationships
1366 if(!mrPage.IsMasterPage())
1367 return;
1368
1369 sal_uInt16 nPageCnt(rMod.GetPageCount());
1370
1371 for(sal_uInt16 nPageNum2(0); nPageNum2 < nPageCnt; nPageNum2++)
1372 {
1373 SdrPage* pDrawPage = rMod.GetPage(nPageNum2);
1374
1375 if(pDrawPage->TRG_HasMasterPage())
1376 {
1377 SdrPage& rMasterPage = pDrawPage->TRG_GetMasterPage();
1378
1379 if(&mrPage == &rMasterPage)
1380 {
1381 if(!pUndoGroup)
1382 {
1383 pUndoGroup.reset( new SdrUndoGroup(rMod) );
1384 }
1385
1386 pUndoGroup->AddAction(rMod.GetSdrUndoFactory().CreateUndoPageRemoveMasterPage(*pDrawPage));
1387 }
1388 }
1389 }
1390}
1391
1392SdrUndoDelPage::~SdrUndoDelPage()
1393{
1394}
1395
1396void SdrUndoDelPage::Undo()
1397{
1398 if (bool(mpFillBitmapItem))
1399 restoreFillBitmap();
1400 ImpInsertPage(nPageNum);
1401 if (pUndoGroup!=nullptr)
1402 {
1403 // recover master page relationships
1404 pUndoGroup->Undo();
1405 }
1406 DBG_ASSERT(bItsMine,"UndoDeletePage: mrPage does not belong to UndoAction.")do { if (true && (!(bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1406" ": "), "%s", "UndoDeletePage: mrPage does not belong to UndoAction."
); } } while (false)
;
1407 bItsMine=false;
1408}
1409
1410void SdrUndoDelPage::Redo()
1411{
1412 ImpRemovePage(nPageNum);
1413 if (bool(mpFillBitmapItem))
1414 clearFillBitmap();
1415 // master page relations are dissolved automatically
1416 DBG_ASSERT(!bItsMine,"RedoDeletePage: mrPage already belongs to UndoAction.")do { if (true && (!(!bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1416" ": "), "%s", "RedoDeletePage: mrPage already belongs to UndoAction."
); } } while (false)
;
1417 bItsMine=true;
1418}
1419
1420OUString SdrUndoDelPage::GetComment() const
1421{
1422 return ImpGetDescriptionStr(STR_UndoDelPagereinterpret_cast<char const *>("STR_UndoDelPage" "\004"
u8"Delete page")
);
1423}
1424
1425OUString SdrUndoDelPage::GetSdrRepeatComment() const
1426{
1427 return ImpGetDescriptionStr(STR_UndoDelPagereinterpret_cast<char const *>("STR_UndoDelPage" "\004"
u8"Delete page")
);
1428}
1429
1430void SdrUndoDelPage::SdrRepeat(SdrView& /*rView*/)
1431{
1432}
1433
1434bool SdrUndoDelPage::CanSdrRepeat(SdrView& /*rView*/) const
1435{
1436 return false;
1437}
1438
1439void SdrUndoDelPage::queryFillBitmap(const SfxItemSet& rItemSet)
1440{
1441 const SfxPoolItem *pItem = nullptr;
1442 if (rItemSet.GetItemState(XATTR_FILLBITMAP, false, &pItem) == SfxItemState::SET)
1443 mpFillBitmapItem.reset(pItem->Clone());
1444 if (rItemSet.GetItemState(XATTR_FILLSTYLE, false, &pItem) == SfxItemState::SET)
1445 mbHasFillBitmap = static_cast<const XFillStyleItem*>(pItem)->GetValue() == css::drawing::FillStyle_BITMAP;
1446}
1447
1448void SdrUndoDelPage::clearFillBitmap()
1449{
1450 if (mrPage.IsMasterPage())
1451 {
1452 SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
1453 assert(bool(pStyleSheet))(static_cast <bool> (bool(pStyleSheet)) ? void (0) : __assert_fail
("bool(pStyleSheet)", "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
, 1453, __extension__ __PRETTY_FUNCTION__))
; // who took away my stylesheet?
1454 if (pStyleSheet->GetListenerCount() == 1)
1455 {
1456 SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
1457 rItemSet.ClearItem(XATTR_FILLBITMAP);
1458 if (mbHasFillBitmap)
1459 rItemSet.ClearItem(XATTR_FILLSTYLE);
1460 }
1461 }
1462 else
1463 {
1464 SdrPageProperties &rPageProps = mrPage.getSdrPageProperties();
1465 rPageProps.ClearItem(XATTR_FILLBITMAP);
1466 if (mbHasFillBitmap)
1467 rPageProps.ClearItem(XATTR_FILLSTYLE);
1468 }
1469}
1470
1471void SdrUndoDelPage::restoreFillBitmap()
1472{
1473 if (mrPage.IsMasterPage())
1474 {
1475 SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
1476 assert(bool(pStyleSheet))(static_cast <bool> (bool(pStyleSheet)) ? void (0) : __assert_fail
("bool(pStyleSheet)", "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
, 1476, __extension__ __PRETTY_FUNCTION__))
; // who took away my stylesheet?
1477 if (pStyleSheet->GetListenerCount() == 1)
1478 {
1479 SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
1480 rItemSet.Put(*mpFillBitmapItem);
1481 if (mbHasFillBitmap)
1482 rItemSet.Put(XFillStyleItem(css::drawing::FillStyle_BITMAP));
1483 }
1484 }
1485 else
1486 {
1487 SdrPageProperties &rPageProps = mrPage.getSdrPageProperties();
1488 rPageProps.PutItem(*mpFillBitmapItem);
1489 if (mbHasFillBitmap)
1490 rPageProps.PutItem(XFillStyleItem(css::drawing::FillStyle_BITMAP));
1491 }
1492}
1493
1494
1495void SdrUndoNewPage::Undo()
1496{
1497 ImpRemovePage(nPageNum);
1498 DBG_ASSERT(!bItsMine,"UndoNewPage: mrPage already belongs to UndoAction.")do { if (true && (!(!bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1498" ": "), "%s", "UndoNewPage: mrPage already belongs to UndoAction."
); } } while (false)
;
1499 bItsMine=true;
1500}
1501
1502void SdrUndoNewPage::Redo()
1503{
1504 ImpInsertPage(nPageNum);
1505 DBG_ASSERT(bItsMine,"RedoNewPage: mrPage does not belong to UndoAction.")do { if (true && (!(bItsMine))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdundo.cxx"
":" "1505" ": "), "%s", "RedoNewPage: mrPage does not belong to UndoAction."
); } } while (false)
;
1506 bItsMine=false;
1507}
1508
1509OUString SdrUndoNewPage::GetComment() const
1510{
1511 return ImpGetDescriptionStr(STR_UndoNewPagereinterpret_cast<char const *>("STR_UndoNewPage" "\004"
u8"Insert page")
);
1512}
1513
1514
1515OUString SdrUndoCopyPage::GetComment() const
1516{
1517 return ImpGetDescriptionStr(STR_UndoCopPagereinterpret_cast<char const *>("STR_UndoCopPage" "\004"
u8"Copy page")
);
1518}
1519
1520OUString SdrUndoCopyPage::GetSdrRepeatComment() const
1521{
1522 return ImpGetDescriptionStr(STR_UndoCopPagereinterpret_cast<char const *>("STR_UndoCopPage" "\004"
u8"Copy page")
);
1523}
1524
1525void SdrUndoCopyPage::SdrRepeat(SdrView& /*rView*/)
1526{
1527
1528}
1529
1530bool SdrUndoCopyPage::CanSdrRepeat(SdrView& /*rView*/) const
1531{
1532 return false;
1533}
1534
1535
1536void SdrUndoSetPageNum::Undo()
1537{
1538 ImpMovePage(nNewPageNum,nOldPageNum);
1539}
1540
1541void SdrUndoSetPageNum::Redo()
1542{
1543 ImpMovePage(nOldPageNum,nNewPageNum);
1544}
1545
1546OUString SdrUndoSetPageNum::GetComment() const
1547{
1548 return ImpGetDescriptionStr(STR_UndoMovPagereinterpret_cast<char const *>("STR_UndoMovPage" "\004"
u8"Change order of pages")
);
1549}
1550
1551SdrUndoPageMasterPage::SdrUndoPageMasterPage(SdrPage& rChangedPage)
1552 : SdrUndoPage(rChangedPage)
1553 , mbOldHadMasterPage(mrPage.TRG_HasMasterPage())
1554 , maOldMasterPageNumber(0)
1555{
1556 // get current state from page
1557 if(mbOldHadMasterPage)
1558 {
1559 maOldSet = mrPage.TRG_GetMasterPageVisibleLayers();
1560 maOldMasterPageNumber = mrPage.TRG_GetMasterPage().GetPageNum();
1561 }
1562}
1563
1564SdrUndoPageMasterPage::~SdrUndoPageMasterPage()
1565{
1566}
1567
1568SdrUndoPageRemoveMasterPage::SdrUndoPageRemoveMasterPage(SdrPage& rChangedPage)
1569: SdrUndoPageMasterPage(rChangedPage)
1570{
1571}
1572
1573void SdrUndoPageRemoveMasterPage::Undo()
1574{
1575 if(mbOldHadMasterPage)
1576 {
1577 mrPage.TRG_SetMasterPage(*mrPage.getSdrModelFromSdrPage().GetMasterPage(maOldMasterPageNumber));
1578 mrPage.TRG_SetMasterPageVisibleLayers(maOldSet);
1579 }
1580}
1581
1582void SdrUndoPageRemoveMasterPage::Redo()
1583{
1584 mrPage.TRG_ClearMasterPage();
1585}
1586
1587OUString SdrUndoPageRemoveMasterPage::GetComment() const
1588{
1589 return ImpGetDescriptionStr(STR_UndoDelPageMasterDscrreinterpret_cast<char const *>("STR_UndoDelPageMasterDscr"
"\004" u8"Clear background page assignment")
);
1590}
1591
1592SdrUndoPageChangeMasterPage::SdrUndoPageChangeMasterPage(SdrPage& rChangedPage)
1593 : SdrUndoPageMasterPage(rChangedPage)
1594 , mbNewHadMasterPage(false)
1595 , maNewMasterPageNumber(0)
1596{
1597}
1598
1599void SdrUndoPageChangeMasterPage::Undo()
1600{
1601 // remember values from new page
1602 if(mrPage.TRG_HasMasterPage())
1603 {
1604 mbNewHadMasterPage = true;
1605 maNewSet = mrPage.TRG_GetMasterPageVisibleLayers();
1606 maNewMasterPageNumber = mrPage.TRG_GetMasterPage().GetPageNum();
1607 }
1608
1609 // restore old values
1610 if(mbOldHadMasterPage)
1611 {
1612 mrPage.TRG_ClearMasterPage();
1613 mrPage.TRG_SetMasterPage(*mrPage.getSdrModelFromSdrPage().GetMasterPage(maOldMasterPageNumber));
1614 mrPage.TRG_SetMasterPageVisibleLayers(maOldSet);
1615 }
1616}
1617
1618void SdrUndoPageChangeMasterPage::Redo()
1619{
1620 // restore new values
1621 if(mbNewHadMasterPage)
1622 {
1623 mrPage.TRG_ClearMasterPage();
1624 mrPage.TRG_SetMasterPage(*mrPage.getSdrModelFromSdrPage().GetMasterPage(maNewMasterPageNumber));
1625 mrPage.TRG_SetMasterPageVisibleLayers(maNewSet);
1626 }
1627}
1628
1629OUString SdrUndoPageChangeMasterPage::GetComment() const
1630{
1631 return ImpGetDescriptionStr(STR_UndoChgPageMasterDscrreinterpret_cast<char const *>("STR_UndoChgPageMasterDscr"
"\004" u8"Change background page assignment")
);
1632}
1633
1634
1635SdrUndoFactory::~SdrUndoFactory(){}
1636
1637// shapes
1638
1639std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoMoveObject( SdrObject& rObject, const Size& rDist )
1640{
1641 return std::make_unique<SdrUndoMoveObj>( rObject, rDist );
1642}
1643
1644std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoGeoObject( SdrObject& rObject )
1645{
1646 return std::make_unique<SdrUndoGeoObj>( rObject );
1647}
1648
1649std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoAttrObject( SdrObject& rObject, bool bStyleSheet1, bool bSaveText )
1650{
1651 return std::make_unique<SdrUndoAttrObj>( rObject, bStyleSheet1, bSaveText );
1
Calling 'make_unique<SdrUndoAttrObj, SdrObject &, bool &, bool &>'
1652}
1653
1654std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoRemoveObject(SdrObject& rObject)
1655{
1656 return std::make_unique<SdrUndoRemoveObj>(rObject);
1657}
1658
1659std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoInsertObject( SdrObject& rObject, bool bOrdNumDirect )
1660{
1661 return std::make_unique<SdrUndoInsertObj>( rObject, bOrdNumDirect );
1662}
1663
1664std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoDeleteObject( SdrObject& rObject, bool bOrdNumDirect )
1665{
1666 return std::make_unique<SdrUndoDelObj>( rObject, bOrdNumDirect );
1667}
1668
1669std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoNewObject( SdrObject& rObject, bool bOrdNumDirect )
1670{
1671 return std::make_unique<SdrUndoNewObj>( rObject, bOrdNumDirect );
1672}
1673
1674std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoCopyObject( SdrObject& rObject, bool bOrdNumDirect )
1675{
1676 return std::make_unique<SdrUndoCopyObj>( rObject, bOrdNumDirect );
1677}
1678
1679std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectOrdNum( SdrObject& rObject, sal_uInt32 nOldOrdNum1, sal_uInt32 nNewOrdNum1)
1680{
1681 return std::make_unique<SdrUndoObjOrdNum>( rObject, nOldOrdNum1, nNewOrdNum1 );
1682}
1683
1684std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoReplaceObject( SdrObject& rOldObject, SdrObject& rNewObject )
1685{
1686 return std::make_unique<SdrUndoReplaceObj>( rOldObject, rNewObject );
1687}
1688
1689std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectLayerChange( SdrObject& rObject, SdrLayerID aOldLayer, SdrLayerID aNewLayer )
1690{
1691 return std::make_unique<SdrUndoObjectLayerChange>( rObject, aOldLayer, aNewLayer );
1692}
1693
1694std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectSetText( SdrObject& rNewObj, sal_Int32 nText )
1695{
1696 return std::make_unique<SdrUndoObjSetText>( rNewObj, nText );
1697}
1698
1699std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectStrAttr( SdrObject& rObject,
1700 SdrUndoObjStrAttr::ObjStrAttrType eObjStrAttrType,
1701 const OUString& sOldStr,
1702 const OUString& sNewStr )
1703{
1704 return std::make_unique<SdrUndoObjStrAttr>( rObject, eObjStrAttrType, sOldStr, sNewStr );
1705}
1706
1707
1708// layer
1709std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoNewLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
1710{
1711 return std::make_unique<SdrUndoNewLayer>( nLayerNum, rNewLayerAdmin, rNewModel );
1712}
1713
1714std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoDeleteLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
1715{
1716 return std::make_unique<SdrUndoDelLayer>( nLayerNum, rNewLayerAdmin, rNewModel );
1717}
1718
1719// page
1720std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoDeletePage(SdrPage& rPage)
1721{
1722 return std::make_unique<SdrUndoDelPage>(rPage);
1723}
1724
1725std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoNewPage(SdrPage& rPage)
1726{
1727 return std::make_unique<SdrUndoNewPage>( rPage );
1728}
1729
1730std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoCopyPage(SdrPage& rPage)
1731{
1732 return std::make_unique<SdrUndoCopyPage>( rPage );
1733}
1734
1735std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoSetPageNum(SdrPage& rNewPg, sal_uInt16 nOldPageNum1, sal_uInt16 nNewPageNum1)
1736{
1737 return std::make_unique<SdrUndoSetPageNum>( rNewPg, nOldPageNum1, nNewPageNum1 );
1738}
1739 // master page
1740std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoPageRemoveMasterPage(SdrPage& rChangedPage)
1741{
1742 return std::make_unique<SdrUndoPageRemoveMasterPage>( rChangedPage );
1743}
1744
1745std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoPageChangeMasterPage(SdrPage& rChangedPage)
1746{
1747 return std::make_unique<SdrUndoPageChangeMasterPage>(rChangedPage);
1748}
1749
1750
1751/* 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;
6
Calling default constructor for 'tuple<SdrUndoGroup *, std::default_delete<SdrUndoGroup>>'
14
Returning from default constructor for 'tuple<SdrUndoGroup *, std::default_delete<SdrUndoGroup>>'
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()
4
Calling default constructor for '__uniq_ptr_data<SdrUndoGroup, std::default_delete<SdrUndoGroup>, true, true>'
5
Calling defaulted default constructor for '__uniq_ptr_impl<SdrUndoGroup, std::default_delete<SdrUndoGroup>>'
15
Returning from default constructor for '__uniq_ptr_impl<SdrUndoGroup, std::default_delete<SdrUndoGroup>>'
16
Returning from default constructor for '__uniq_ptr_data<SdrUndoGroup, std::default_delete<SdrUndoGroup>, true, true>'
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; }
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)...)); }
2
Calling constructor for 'SdrUndoAttrObj'
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 */

/usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/tuple

1// <tuple> -*- C++ -*-
2
3// Copyright (C) 2007-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 include/tuple
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TUPLE1
30#define _GLIBCXX_TUPLE1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201703L < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <utility>
39#include <array>
40#include <bits/uses_allocator.h>
41#include <bits/invoke.h>
42#if __cplusplus201703L > 201703L
43# include <compare>
44# define __cpp_lib_constexpr_tuple 201811L
45#endif
46
47namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
50
51 /**
52 * @addtogroup utilities
53 * @{
54 */
55
56 template<typename... _Elements>
57 class tuple;
58
59 template<typename _Tp>
60 struct __is_empty_non_tuple : is_empty<_Tp> { };
61
62 // Using EBO for elements that are tuples causes ambiguous base errors.
63 template<typename _El0, typename... _El>
64 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
65
66 // Use the Empty Base-class Optimization for empty, non-final types.
67 template<typename _Tp>
68 using __empty_not_final
69 = typename conditional<__is_final(_Tp), false_type,
70 __is_empty_non_tuple<_Tp>>::type;
71
72 template<std::size_t _Idx, typename _Head,
73 bool = __empty_not_final<_Head>::value>
74 struct _Head_base;
75
76 template<std::size_t _Idx, typename _Head>
77 struct _Head_base<_Idx, _Head, true>
78 : public _Head
79 {
80 constexpr _Head_base()
81 : _Head() { }
10
Value assigned to field 'pObj'
82
83 constexpr _Head_base(const _Head& __h)
84 : _Head(__h) { }
85
86 constexpr _Head_base(const _Head_base&) = default;
87 constexpr _Head_base(_Head_base&&) = default;
88
89 template<typename _UHead>
90 constexpr _Head_base(_UHead&& __h)
91 : _Head(std::forward<_UHead>(__h)) { }
92
93 _Head_base(allocator_arg_t, __uses_alloc0)
94 : _Head() { }
95
96 template<typename _Alloc>
97 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
98 : _Head(allocator_arg, *__a._M_a) { }
99
100 template<typename _Alloc>
101 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
102 : _Head(*__a._M_a) { }
103
104 template<typename _UHead>
105 _Head_base(__uses_alloc0, _UHead&& __uhead)
106 : _Head(std::forward<_UHead>(__uhead)) { }
107
108 template<typename _Alloc, typename _UHead>
109 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
110 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
111
112 template<typename _Alloc, typename _UHead>
113 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
114 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
115
116 static constexpr _Head&
117 _M_head(_Head_base& __b) noexcept { return __b; }
118
119 static constexpr const _Head&
120 _M_head(const _Head_base& __b) noexcept { return __b; }
121 };
122
123 template<std::size_t _Idx, typename _Head>
124 struct _Head_base<_Idx, _Head, false>
125 {
126 constexpr _Head_base()
127 : _M_head_impl() { }
128
129 constexpr _Head_base(const _Head& __h)
130 : _M_head_impl(__h) { }
131
132 constexpr _Head_base(const _Head_base&) = default;
133 constexpr _Head_base(_Head_base&&) = default;
134
135 template<typename _UHead>
136 constexpr _Head_base(_UHead&& __h)
137 : _M_head_impl(std::forward<_UHead>(__h)) { }
138
139 _GLIBCXX20_CONSTEXPR
140 _Head_base(allocator_arg_t, __uses_alloc0)
141 : _M_head_impl() { }
142
143 template<typename _Alloc>
144 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
145 : _M_head_impl(allocator_arg, *__a._M_a) { }
146
147 template<typename _Alloc>
148 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
149 : _M_head_impl(*__a._M_a) { }
150
151 template<typename _UHead>
152 _GLIBCXX20_CONSTEXPR
153 _Head_base(__uses_alloc0, _UHead&& __uhead)
154 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
155
156 template<typename _Alloc, typename _UHead>
157 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
158 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
159 { }
160
161 template<typename _Alloc, typename _UHead>
162 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
163 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
164
165 static constexpr _Head&
166 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
167
168 static constexpr const _Head&
169 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
170
171 _Head _M_head_impl;
172 };
173
174 /**
175 * Contains the actual implementation of the @c tuple template, stored
176 * as a recursive inheritance hierarchy from the first element (most
177 * derived class) to the last (least derived class). The @c Idx
178 * parameter gives the 0-based index of the element stored at this
179 * point in the hierarchy; we use it to implement a constant-time
180 * get() operation.
181 */
182 template<std::size_t _Idx, typename... _Elements>
183 struct _Tuple_impl;
184
185 /**
186 * Recursive tuple implementation. Here we store the @c Head element
187 * and derive from a @c Tuple_impl containing the remaining elements
188 * (which contains the @c Tail).
189 */
190 template<std::size_t _Idx, typename _Head, typename... _Tail>
191 struct _Tuple_impl<_Idx, _Head, _Tail...>
192 : public _Tuple_impl<_Idx + 1, _Tail...>,
193 private _Head_base<_Idx, _Head>
194 {
195 template<std::size_t, typename...> friend class _Tuple_impl;
196
197 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
198 typedef _Head_base<_Idx, _Head> _Base;
199
200 static constexpr _Head&
201 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
202
203 static constexpr const _Head&
204 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
205
206 static constexpr _Inherited&
207 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
208
209 static constexpr const _Inherited&
210 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
211
212 constexpr _Tuple_impl()
213 : _Inherited(), _Base() { }
8
Calling default constructor for '_Tuple_impl<1, std::default_delete<SdrUndoGroup>>'
12
Returning from default constructor for '_Tuple_impl<1, std::default_delete<SdrUndoGroup>>'
214
215 explicit
216 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
217 : _Inherited(__tail...), _Base(__head) { }
218
219 template<typename _UHead, typename... _UTail, typename = typename
220 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
221 explicit
222 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
223 : _Inherited(std::forward<_UTail>(__tail)...),
224 _Base(std::forward<_UHead>(__head)) { }
225
226 constexpr _Tuple_impl(const _Tuple_impl&) = default;
227
228 // _GLIBCXX_RESOLVE_LIB_DEFECTS
229 // 2729. Missing SFINAE on std::pair::operator=
230 _Tuple_impl& operator=(const _Tuple_impl&) = delete;
231
232 constexpr
233 _Tuple_impl(_Tuple_impl&& __in)
234 noexcept(__and_<is_nothrow_move_constructible<_Head>,
235 is_nothrow_move_constructible<_Inherited>>::value)
236 : _Inherited(std::move(_M_tail(__in))),
237 _Base(std::forward<_Head>(_M_head(__in))) { }
238
239 template<typename... _UElements>
240 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
241 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
242 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
243
244 template<typename _UHead, typename... _UTails>
245 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
246 : _Inherited(std::move
247 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
248 _Base(std::forward<_UHead>
249 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
250
251 template<typename _Alloc>
252 _GLIBCXX20_CONSTEXPR
253 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
254 : _Inherited(__tag, __a),
255 _Base(__tag, __use_alloc<_Head>(__a)) { }
256
257 template<typename _Alloc>
258 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
259 const _Head& __head, const _Tail&... __tail)
260 : _Inherited(__tag, __a, __tail...),
261 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
262
263 template<typename _Alloc, typename _UHead, typename... _UTail,
264 typename = typename enable_if<sizeof...(_Tail)
265 == sizeof...(_UTail)>::type>
266 _GLIBCXX20_CONSTEXPR
267 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
268 _UHead&& __head, _UTail&&... __tail)
269 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
270 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
271 std::forward<_UHead>(__head)) { }
272
273 template<typename _Alloc>
274 _GLIBCXX20_CONSTEXPR
275 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
276 const _Tuple_impl& __in)
277 : _Inherited(__tag, __a, _M_tail(__in)),
278 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
279
280 template<typename _Alloc>
281 _GLIBCXX20_CONSTEXPR
282 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
283 _Tuple_impl&& __in)
284 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
285 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
286 std::forward<_Head>(_M_head(__in))) { }
287
288 template<typename _Alloc, typename... _UElements>
289 _GLIBCXX20_CONSTEXPR
290 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
291 const _Tuple_impl<_Idx, _UElements...>& __in)
292 : _Inherited(__tag, __a,
293 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
294 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
295 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
296
297 template<typename _Alloc, typename _UHead, typename... _UTails>
298 _GLIBCXX20_CONSTEXPR
299 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
300 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
301 : _Inherited(__tag, __a, std::move
302 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
303 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
304 std::forward<_UHead>
305 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
306
307 template<typename... _UElements>
308 _GLIBCXX20_CONSTEXPR
309 void
310 _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
311 {
312 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
313 _M_tail(*this)._M_assign(
314 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
315 }
316
317 template<typename _UHead, typename... _UTails>
318 _GLIBCXX20_CONSTEXPR
319 void
320 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
321 {
322 _M_head(*this) = std::forward<_UHead>
323 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
324 _M_tail(*this)._M_assign(
325 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
326 }
327
328 protected:
329 _GLIBCXX20_CONSTEXPR
330 void
331 _M_swap(_Tuple_impl& __in)
332 {
333 using std::swap;
334 swap(_M_head(*this), _M_head(__in));
335 _Inherited::_M_swap(_M_tail(__in));
336 }
337 };
338
339 // Basis case of inheritance recursion.
340 template<std::size_t _Idx, typename _Head>
341 struct _Tuple_impl<_Idx, _Head>
342 : private _Head_base<_Idx, _Head>
343 {
344 template<std::size_t, typename...> friend class _Tuple_impl;
345
346 typedef _Head_base<_Idx, _Head> _Base;
347
348 static constexpr _Head&
349 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
350
351 static constexpr const _Head&
352 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
353
354 constexpr _Tuple_impl()
355 : _Base() { }
9
Calling default constructor for '_Head_base<1, std::default_delete<SdrUndoGroup>, true>'
11
Returning from default constructor for '_Head_base<1, std::default_delete<SdrUndoGroup>, true>'
356
357 explicit
358 constexpr _Tuple_impl(const _Head& __head)
359 : _Base(__head) { }
360
361 template<typename _UHead>
362 explicit
363 constexpr _Tuple_impl(_UHead&& __head)
364 : _Base(std::forward<_UHead>(__head)) { }
365
366 constexpr _Tuple_impl(const _Tuple_impl&) = default;
367
368 // _GLIBCXX_RESOLVE_LIB_DEFECTS
369 // 2729. Missing SFINAE on std::pair::operator=
370 _Tuple_impl& operator=(const _Tuple_impl&) = delete;
371
372 constexpr
373 _Tuple_impl(_Tuple_impl&& __in)
374 noexcept(is_nothrow_move_constructible<_Head>::value)
375 : _Base(std::forward<_Head>(_M_head(__in))) { }
376
377 template<typename _UHead>
378 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
379 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
380
381 template<typename _UHead>
382 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
383 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
384 { }
385
386 template<typename _Alloc>
387 _GLIBCXX20_CONSTEXPR
388 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
389 : _Base(__tag, __use_alloc<_Head>(__a)) { }
390
391 template<typename _Alloc>
392 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
393 const _Head& __head)
394 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
395
396 template<typename _Alloc, typename _UHead>
397 _GLIBCXX20_CONSTEXPR
398 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
399 _UHead&& __head)
400 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
401 std::forward<_UHead>(__head)) { }
402
403 template<typename _Alloc>
404 _GLIBCXX20_CONSTEXPR
405 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
406 const _Tuple_impl& __in)
407 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
408
409 template<typename _Alloc>
410 _GLIBCXX20_CONSTEXPR
411 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
412 _Tuple_impl&& __in)
413 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
414 std::forward<_Head>(_M_head(__in))) { }
415
416 template<typename _Alloc, typename _UHead>
417 _GLIBCXX20_CONSTEXPR
418 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
419 const _Tuple_impl<_Idx, _UHead>& __in)
420 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
421 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
422
423 template<typename _Alloc, typename _UHead>
424 _GLIBCXX20_CONSTEXPR
425 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
426 _Tuple_impl<_Idx, _UHead>&& __in)
427 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
428 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
429 { }
430
431 template<typename _UHead>
432 _GLIBCXX20_CONSTEXPR
433 void
434 _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
435 {
436 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
437 }
438
439 template<typename _UHead>
440 _GLIBCXX20_CONSTEXPR
441 void
442 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
443 {
444 _M_head(*this)
445 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
446 }
447
448 protected:
449 _GLIBCXX20_CONSTEXPR
450 void
451 _M_swap(_Tuple_impl& __in)
452 {
453 using std::swap;
454 swap(_M_head(*this), _M_head(__in));
455 }
456 };
457
458 // Concept utility functions, reused in conditionally-explicit
459 // constructors.
460 template<bool, typename... _Types>
461 struct _TupleConstraints
462 {
463 // Constraint for a non-explicit constructor.
464 // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
465 // and every Ui is implicitly convertible to Ti.
466 template<typename... _UTypes>
467 static constexpr bool __is_implicitly_constructible()
468 {
469 return __and_<is_constructible<_Types, _UTypes>...,
470 is_convertible<_UTypes, _Types>...
471 >::value;
472 }
473
474 // Constraint for a non-explicit constructor.
475 // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
476 // but not every Ui is implicitly convertible to Ti.
477 template<typename... _UTypes>
478 static constexpr bool __is_explicitly_constructible()
479 {
480 return __and_<is_constructible<_Types, _UTypes>...,
481 __not_<__and_<is_convertible<_UTypes, _Types>...>>
482 >::value;
483 }
484
485 static constexpr bool __is_implicitly_default_constructible()
486 {
487 return __and_<std::__is_implicitly_default_constructible<_Types>...
488 >::value;
489 }
490
491 static constexpr bool __is_explicitly_default_constructible()
492 {
493 return __and_<is_default_constructible<_Types>...,
494 __not_<__and_<
495 std::__is_implicitly_default_constructible<_Types>...>
496 >>::value;
497 }
498 };
499
500 // Partial specialization used when a required precondition isn't met,
501 // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
502 template<typename... _Types>
503 struct _TupleConstraints<false, _Types...>
504 {
505 template<typename... _UTypes>
506 static constexpr bool __is_implicitly_constructible()
507 { return false; }
508
509 template<typename... _UTypes>
510 static constexpr bool __is_explicitly_constructible()
511 { return false; }
512 };
513
514 /// Primary class template, tuple
515 template<typename... _Elements>
516 class tuple : public _Tuple_impl<0, _Elements...>
517 {
518 typedef _Tuple_impl<0, _Elements...> _Inherited;
519
520 template<bool _Cond>
521 using _TCC = _TupleConstraints<_Cond, _Elements...>;
522
523 // Constraint for non-explicit default constructor
524 template<bool _Dummy>
525 using _ImplicitDefaultCtor = __enable_if_t<
526 _TCC<_Dummy>::__is_implicitly_default_constructible(),
527 bool>;
528
529 // Constraint for explicit default constructor
530 template<bool _Dummy>
531 using _ExplicitDefaultCtor = __enable_if_t<
532 _TCC<_Dummy>::__is_explicitly_default_constructible(),
533 bool>;
534
535 // Constraint for non-explicit constructors
536 template<bool _Cond, typename... _Args>
537 using _ImplicitCtor = __enable_if_t<
538 _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
539 bool>;
540
541 // Constraint for non-explicit constructors
542 template<bool _Cond, typename... _Args>
543 using _ExplicitCtor = __enable_if_t<
544 _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
545 bool>;
546
547 template<typename... _UElements>
548 static constexpr
549 __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
550 __assignable()
551 { return __and_<is_assignable<_Elements&, _UElements>...>::value; }
552
553 // Condition for noexcept-specifier of an assignment operator.
554 template<typename... _UElements>
555 static constexpr bool __nothrow_assignable()
556 {
557 return
558 __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
559 }
560
561 // Condition for noexcept-specifier of a constructor.
562 template<typename... _UElements>
563 static constexpr bool __nothrow_constructible()
564 {
565 return
566 __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
567 }
568
569 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
570 template<typename _Up>
571 static constexpr bool __valid_args()
572 {
573 return sizeof...(_Elements) == 1
574 && !is_same<tuple, __remove_cvref_t<_Up>>::value;
575 }
576
577 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
578 template<typename, typename, typename... _Tail>
579 static constexpr bool __valid_args()
580 { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
581
582 /* Constraint for constructors with a tuple<UTypes...> parameter ensures
583 * that the constructor is only viable when it would not interfere with
584 * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
585 * Such constructors are only viable if:
586 * either sizeof...(Types) != 1,
587 * or (when Types... expands to T and UTypes... expands to U)
588 * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
589 * and is_same_v<T, U> are all false.
590 */
591 template<typename _Tuple, typename = tuple,
592 typename = __remove_cvref_t<_Tuple>>
593 struct _UseOtherCtor
594 : false_type
595 { };
596 // If TUPLE is convertible to the single element in *this,
597 // then TUPLE should match tuple(UTypes&&...) instead.
598 template<typename _Tuple, typename _Tp, typename _Up>
599 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
600 : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>
601 { };
602 // If TUPLE and *this each have a single element of the same type,
603 // then TUPLE should match a copy/move constructor instead.
604 template<typename _Tuple, typename _Tp>
605 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
606 : true_type
607 { };
608
609 // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
610 // and the single element in Types can be initialized from TUPLE,
611 // or is the same type as tuple_element_t<0, TUPLE>.
612 template<typename _Tuple>
613 static constexpr bool __use_other_ctor()
614 { return _UseOtherCtor<_Tuple>::value; }
615
616 public:
617 template<typename _Dummy = void,
618 _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
619 constexpr
620 tuple()
621 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
622 : _Inherited() { }
623
624 template<typename _Dummy = void,
625 _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
626 explicit constexpr
627 tuple()
628 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
629 : _Inherited() { }
630
631 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
632 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
633 constexpr
634 tuple(const _Elements&... __elements)
635 noexcept(__nothrow_constructible<const _Elements&...>())
636 : _Inherited(__elements...) { }
637
638 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
639 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
640 explicit constexpr
641 tuple(const _Elements&... __elements)
642 noexcept(__nothrow_constructible<const _Elements&...>())
643 : _Inherited(__elements...) { }
644
645 template<typename... _UElements,
646 bool _Valid = __valid_args<_UElements...>(),
647 _ImplicitCtor<_Valid, _UElements...> = true>
648 constexpr
649 tuple(_UElements&&... __elements)
650 noexcept(__nothrow_constructible<_UElements...>())
651 : _Inherited(std::forward<_UElements>(__elements)...) { }
652
653 template<typename... _UElements,
654 bool _Valid = __valid_args<_UElements...>(),
655 _ExplicitCtor<_Valid, _UElements...> = false>
656 explicit constexpr
657 tuple(_UElements&&... __elements)
658 noexcept(__nothrow_constructible<_UElements...>())
659 : _Inherited(std::forward<_UElements>(__elements)...) { }
660
661 constexpr tuple(const tuple&) = default;
662
663 constexpr tuple(tuple&&) = default;
664
665 template<typename... _UElements,
666 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
667 && !__use_other_ctor<const tuple<_UElements...>&>(),
668 _ImplicitCtor<_Valid, const _UElements&...> = true>
669 constexpr
670 tuple(const tuple<_UElements...>& __in)
671 noexcept(__nothrow_constructible<const _UElements&...>())
672 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
673 { }
674
675 template<typename... _UElements,
676 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
677 && !__use_other_ctor<const tuple<_UElements...>&>(),
678 _ExplicitCtor<_Valid, const _UElements&...> = false>
679 explicit constexpr
680 tuple(const tuple<_UElements...>& __in)
681 noexcept(__nothrow_constructible<const _UElements&...>())
682 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
683 { }
684
685 template<typename... _UElements,
686 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
687 && !__use_other_ctor<tuple<_UElements...>&&>(),
688 _ImplicitCtor<_Valid, _UElements...> = true>
689 constexpr
690 tuple(tuple<_UElements...>&& __in)
691 noexcept(__nothrow_constructible<_UElements...>())
692 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
693
694 template<typename... _UElements,
695 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
696 && !__use_other_ctor<tuple<_UElements...>&&>(),
697 _ExplicitCtor<_Valid, _UElements...> = false>
698 explicit constexpr
699 tuple(tuple<_UElements...>&& __in)
700 noexcept(__nothrow_constructible<_UElements...>())
701 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
702
703 // Allocator-extended constructors.
704
705 template<typename _Alloc,
706 _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
707 _GLIBCXX20_CONSTEXPR
708 tuple(allocator_arg_t __tag, const _Alloc& __a)
709 : _Inherited(__tag, __a) { }
710
711 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
712 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
713 _GLIBCXX20_CONSTEXPR
714 tuple(allocator_arg_t __tag, const _Alloc& __a,
715 const _Elements&... __elements)
716 : _Inherited(__tag, __a, __elements...) { }
717
718 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
719 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
720 _GLIBCXX20_CONSTEXPR
721 explicit
722 tuple(allocator_arg_t __tag, const _Alloc& __a,
723 const _Elements&... __elements)
724 : _Inherited(__tag, __a, __elements...) { }
725
726 template<typename _Alloc, typename... _UElements,
727 bool _Valid = __valid_args<_UElements...>(),
728 _ImplicitCtor<_Valid, _UElements...> = true>
729 _GLIBCXX20_CONSTEXPR
730 tuple(allocator_arg_t __tag, const _Alloc& __a,
731 _UElements&&... __elements)
732 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
733 { }
734
735 template<typename _Alloc, typename... _UElements,
736 bool _Valid = __valid_args<_UElements...>(),
737 _ExplicitCtor<_Valid, _UElements...> = false>
738 _GLIBCXX20_CONSTEXPR
739 explicit
740 tuple(allocator_arg_t __tag, const _Alloc& __a,
741 _UElements&&... __elements)
742 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
743 { }
744
745 template<typename _Alloc>
746 _GLIBCXX20_CONSTEXPR
747 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
748 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
749
750 template<typename _Alloc>
751 _GLIBCXX20_CONSTEXPR
752 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
753 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
754
755 template<typename _Alloc, typename... _UElements,
756 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
757 && !__use_other_ctor<const tuple<_UElements...>&>(),
758 _ImplicitCtor<_Valid, const _UElements&...> = true>
759 _GLIBCXX20_CONSTEXPR
760 tuple(allocator_arg_t __tag, const _Alloc& __a,
761 const tuple<_UElements...>& __in)
762 : _Inherited(__tag, __a,
763 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
764 { }
765
766 template<typename _Alloc, typename... _UElements,
767 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
768 && !__use_other_ctor<const tuple<_UElements...>&>(),
769 _ExplicitCtor<_Valid, const _UElements&...> = false>
770 _GLIBCXX20_CONSTEXPR
771 explicit
772 tuple(allocator_arg_t __tag, const _Alloc& __a,
773 const tuple<_UElements...>& __in)
774 : _Inherited(__tag, __a,
775 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
776 { }
777
778 template<typename _Alloc, typename... _UElements,
779 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
780 && !__use_other_ctor<tuple<_UElements...>&&>(),
781 _ImplicitCtor<_Valid, _UElements...> = true>
782 _GLIBCXX20_CONSTEXPR
783 tuple(allocator_arg_t __tag, const _Alloc& __a,
784 tuple<_UElements...>&& __in)
785 : _Inherited(__tag, __a,
786 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
787 { }
788
789 template<typename _Alloc, typename... _UElements,
790 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
791 && !__use_other_ctor<tuple<_UElements...>&&>(),
792 _ExplicitCtor<_Valid, _UElements...> = false>
793 _GLIBCXX20_CONSTEXPR
794 explicit
795 tuple(allocator_arg_t __tag, const _Alloc& __a,
796 tuple<_UElements...>&& __in)
797 : _Inherited(__tag, __a,
798 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
799 { }
800
801 // tuple assignment
802
803 _GLIBCXX20_CONSTEXPR
804 tuple&
805 operator=(typename conditional<__assignable<const _Elements&...>(),
806 const tuple&,
807 const __nonesuch&>::type __in)
808 noexcept(__nothrow_assignable<const _Elements&...>())
809 {
810 this->_M_assign(__in);
811 return *this;
812 }
813
814 _GLIBCXX20_CONSTEXPR
815 tuple&
816 operator=(typename conditional<__assignable<_Elements...>(),
817 tuple&&,
818 __nonesuch&&>::type __in)
819 noexcept(__nothrow_assignable<_Elements...>())
820 {
821 this->_M_assign(std::move(__in));
822 return *this;
823 }
824
825 template<typename... _UElements>
826 _GLIBCXX20_CONSTEXPR
827 __enable_if_t<__assignable<const _UElements&...>(), tuple&>
828 operator=(const tuple<_UElements...>& __in)
829 noexcept(__nothrow_assignable<const _UElements&...>())
830 {
831 this->_M_assign(__in);
832 return *this;
833 }
834
835 template<typename... _UElements>
836 _GLIBCXX20_CONSTEXPR
837 __enable_if_t<__assignable<_UElements...>(), tuple&>
838 operator=(tuple<_UElements...>&& __in)
839 noexcept(__nothrow_assignable<_UElements...>())
840 {
841 this->_M_assign(std::move(__in));
842 return *this;
843 }
844
845 // tuple swap
846 _GLIBCXX20_CONSTEXPR
847 void
848 swap(tuple& __in)
849 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
850 { _Inherited::_M_swap(__in); }
851 };
852
853#if __cpp_deduction_guides201703L >= 201606
854 template<typename... _UTypes>
855 tuple(_UTypes...) -> tuple<_UTypes...>;
856 template<typename _T1, typename _T2>
857 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
858 template<typename _Alloc, typename... _UTypes>
859 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
860 template<typename _Alloc, typename _T1, typename _T2>
861 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
862 template<typename _Alloc, typename... _UTypes>
863 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
864#endif
865
866 // Explicit specialization, zero-element tuple.
867 template<>
868 class tuple<>
869 {
870 public:
871 void swap(tuple&) noexcept { /* no-op */ }
872 // We need the default since we're going to define no-op
873 // allocator constructors.
874 tuple() = default;
875 // No-op allocator constructors.
876 template<typename _Alloc>
877 _GLIBCXX20_CONSTEXPR
878 tuple(allocator_arg_t, const _Alloc&) noexcept { }
879 template<typename _Alloc>
880 _GLIBCXX20_CONSTEXPR
881 tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
882 };
883
884 /// Partial specialization, 2-element tuple.
885 /// Includes construction and assignment from a pair.
886 template<typename _T1, typename _T2>
887 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
888 {
889 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
890
891 // Constraint for non-explicit default constructor
892 template<bool _Dummy, typename _U1, typename _U2>
893 using _ImplicitDefaultCtor = __enable_if_t<
894 _TupleConstraints<_Dummy, _U1, _U2>::
895 __is_implicitly_default_constructible(),
896 bool>;
897
898 // Constraint for explicit default constructor
899 template<bool _Dummy, typename _U1, typename _U2>
900 using _ExplicitDefaultCtor = __enable_if_t<
901 _TupleConstraints<_Dummy, _U1, _U2>::
902 __is_explicitly_default_constructible(),
903 bool>;
904
905 template<bool _Dummy>
906 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
907
908 // Constraint for non-explicit constructors
909 template<bool _Cond, typename _U1, typename _U2>
910 using _ImplicitCtor = __enable_if_t<
911 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
912 bool>;
913
914 // Constraint for non-explicit constructors
915 template<bool _Cond, typename _U1, typename _U2>
916 using _ExplicitCtor = __enable_if_t<
917 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
918 bool>;
919
920 template<typename _U1, typename _U2>
921 static constexpr bool __assignable()
922 {
923 return __and_<is_assignable<_T1&, _U1>,
924 is_assignable<_T2&, _U2>>::value;
925 }
926
927 template<typename _U1, typename _U2>
928 static constexpr bool __nothrow_assignable()
929 {
930 return __and_<is_nothrow_assignable<_T1&, _U1>,
931 is_nothrow_assignable<_T2&, _U2>>::value;
932 }
933
934 template<typename _U1, typename _U2>
935 static constexpr bool __nothrow_constructible()
936 {
937 return __and_<is_nothrow_constructible<_T1, _U1>,
938 is_nothrow_constructible<_T2, _U2>>::value;
939 }
940
941 static constexpr bool __nothrow_default_constructible()
942 {
943 return __and_<is_nothrow_default_constructible<_T1>,
944 is_nothrow_default_constructible<_T2>>::value;
945 }
946
947 template<typename _U1>
948 static constexpr bool __is_alloc_arg()
949 { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
950
951 public:
952 template<bool _Dummy = true,
953 _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
954 constexpr
955 tuple()
956 noexcept(__nothrow_default_constructible())
957 : _Inherited() { }
7
Calling default constructor for '_Tuple_impl<0, SdrUndoGroup *, std::default_delete<SdrUndoGroup>>'
13
Returning from default constructor for '_Tuple_impl<0, SdrUndoGroup *, std::default_delete<SdrUndoGroup>>'
958
959 template<bool _Dummy = true,
960 _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
961 explicit constexpr
962 tuple()
963 noexcept(__nothrow_default_constructible())
964 : _Inherited() { }
965
966 template<bool _Dummy = true,
967 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
968 constexpr
969 tuple(const _T1& __a1, const _T2& __a2)
970 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
971 : _Inherited(__a1, __a2) { }
972
973 template<bool _Dummy = true,
974 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
975 explicit constexpr
976 tuple(const _T1& __a1, const _T2& __a2)
977 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
978 : _Inherited(__a1, __a2) { }
979
980 template<typename _U1, typename _U2,
981 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
982 constexpr
983 tuple(_U1&& __a1, _U2&& __a2)
984 noexcept(__nothrow_constructible<_U1, _U2>())
985 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
986
987 template<typename _U1, typename _U2,
988 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
989 explicit constexpr
990 tuple(_U1&& __a1, _U2&& __a2)
991 noexcept(__nothrow_constructible<_U1, _U2>())
992 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
993
994 constexpr tuple(const tuple&) = default;
995
996 constexpr tuple(tuple&&) = default;
997
998 template<typename _U1, typename _U2,
999 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1000 constexpr
1001 tuple(const tuple<_U1, _U2>& __in)
1002 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1003 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1004
1005 template<typename _U1, typename _U2,
1006 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1007 explicit constexpr
1008 tuple(const tuple<_U1, _U2>& __in)
1009 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1010 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1011
1012 template<typename _U1, typename _U2,
1013 _ImplicitCtor<true, _U1, _U2> = true>
1014 constexpr
1015 tuple(tuple<_U1, _U2>&& __in)
1016 noexcept(__nothrow_constructible<_U1, _U2>())
1017 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1018
1019 template<typename _U1, typename _U2,
1020 _ExplicitCtor<true, _U1, _U2> = false>
1021 explicit constexpr
1022 tuple(tuple<_U1, _U2>&& __in)
1023 noexcept(__nothrow_constructible<_U1, _U2>())
1024 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1025
1026 template<typename _U1, typename _U2,
1027 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1028 constexpr
1029 tuple(const pair<_U1, _U2>& __in)
1030 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1031 : _Inherited(__in.first, __in.second) { }
1032
1033 template<typename _U1, typename _U2,
1034 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1035 explicit constexpr
1036 tuple(const pair<_U1, _U2>& __in)
1037 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1038 : _Inherited(__in.first, __in.second) { }
1039
1040 template<typename _U1, typename _U2,
1041 _ImplicitCtor<true, _U1, _U2> = true>
1042 constexpr
1043 tuple(pair<_U1, _U2>&& __in)
1044 noexcept(__nothrow_constructible<_U1, _U2>())
1045 : _Inherited(std::forward<_U1>(__in.first),
1046 std::forward<_U2>(__in.second)) { }
1047
1048 template<typename _U1, typename _U2,
1049 _ExplicitCtor<true, _U1, _U2> = false>
1050 explicit constexpr
1051 tuple(pair<_U1, _U2>&& __in)
1052 noexcept(__nothrow_constructible<_U1, _U2>())
1053 : _Inherited(std::forward<_U1>(__in.first),
1054 std::forward<_U2>(__in.second)) { }
1055
1056 // Allocator-extended constructors.
1057
1058 template<typename _Alloc,
1059 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
1060 _GLIBCXX20_CONSTEXPR
1061 tuple(allocator_arg_t __tag, const _Alloc& __a)
1062 : _Inherited(__tag, __a) { }
1063
1064 template<typename _Alloc, bool _Dummy = true,
1065 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1066 _GLIBCXX20_CONSTEXPR
1067 tuple(allocator_arg_t __tag, const _Alloc& __a,
1068 const _T1& __a1, const _T2& __a2)
1069 : _Inherited(__tag, __a, __a1, __a2) { }
1070
1071 template<typename _Alloc, bool _Dummy = true,
1072 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1073 explicit
1074 _GLIBCXX20_CONSTEXPR
1075 tuple(allocator_arg_t __tag, const _Alloc& __a,
1076 const _T1& __a1, const _T2& __a2)
1077 : _Inherited(__tag, __a, __a1, __a2) { }
1078
1079 template<typename _Alloc, typename _U1, typename _U2,
1080 _ImplicitCtor<true, _U1, _U2> = true>
1081 _GLIBCXX20_CONSTEXPR
1082 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1083 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1084 std::forward<_U2>(__a2)) { }
1085
1086 template<typename _Alloc, typename _U1, typename _U2,
1087 _ExplicitCtor<true, _U1, _U2> = false>
1088 explicit
1089 _GLIBCXX20_CONSTEXPR
1090 tuple(allocator_arg_t __tag, const _Alloc& __a,
1091 _U1&& __a1, _U2&& __a2)
1092 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1093 std::forward<_U2>(__a2)) { }
1094
1095 template<typename _Alloc>
1096 _GLIBCXX20_CONSTEXPR
1097 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1098 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1099
1100 template<typename _Alloc>
1101 _GLIBCXX20_CONSTEXPR
1102 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1103 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1104
1105 template<typename _Alloc, typename _U1, typename _U2,
1106 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1107 _GLIBCXX20_CONSTEXPR
1108 tuple(allocator_arg_t __tag, const _Alloc& __a,
1109 const tuple<_U1, _U2>& __in)
1110 : _Inherited(__tag, __a,
1111 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1112 { }
1113
1114 template<typename _Alloc, typename _U1, typename _U2,
1115 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1116 explicit
1117 _GLIBCXX20_CONSTEXPR
1118 tuple(allocator_arg_t __tag, const _Alloc& __a,
1119 const tuple<_U1, _U2>& __in)
1120 : _Inherited(__tag, __a,
1121 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1122 { }
1123
1124 template<typename _Alloc, typename _U1, typename _U2,
1125 _ImplicitCtor<true, _U1, _U2> = true>
1126 _GLIBCXX20_CONSTEXPR
1127 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1128 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1129 { }
1130
1131 template<typename _Alloc, typename _U1, typename _U2,
1132 _ExplicitCtor<true, _U1, _U2> = false>
1133 explicit
1134 _GLIBCXX20_CONSTEXPR
1135 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1136 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1137 { }
1138
1139 template<typename _Alloc, typename _U1, typename _U2,
1140 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1141 _GLIBCXX20_CONSTEXPR
1142 tuple(allocator_arg_t __tag, const _Alloc& __a,
1143 const pair<_U1, _U2>& __in)
1144 : _Inherited(__tag, __a, __in.first, __in.second) { }
1145
1146 template<typename _Alloc, typename _U1, typename _U2,
1147 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1148 explicit
1149 _GLIBCXX20_CONSTEXPR
1150 tuple(allocator_arg_t __tag, const _Alloc& __a,
1151 const pair<_U1, _U2>& __in)
1152 : _Inherited(__tag, __a, __in.first, __in.second) { }
1153
1154 template<typename _Alloc, typename _U1, typename _U2,
1155 _ImplicitCtor<true, _U1, _U2> = true>
1156 _GLIBCXX20_CONSTEXPR
1157 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1158 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1159 std::forward<_U2>(__in.second)) { }
1160
1161 template<typename _Alloc, typename _U1, typename _U2,
1162 _ExplicitCtor<true, _U1, _U2> = false>
1163 explicit
1164 _GLIBCXX20_CONSTEXPR
1165 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1166 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1167 std::forward<_U2>(__in.second)) { }
1168
1169 // Tuple assignment.
1170
1171 _GLIBCXX20_CONSTEXPR
1172 tuple&
1173 operator=(typename conditional<__assignable<const _T1&, const _T2&>(),
1174 const tuple&,
1175 const __nonesuch&>::type __in)
1176 noexcept(__nothrow_assignable<const _T1&, const _T2&>())
1177 {
1178 this->_M_assign(__in);
1179 return *this;
1180 }
1181
1182 _GLIBCXX20_CONSTEXPR
1183 tuple&
1184 operator=(typename conditional<__assignable<_T1, _T2>(),
1185 tuple&&,
1186 __nonesuch&&>::type __in)
1187 noexcept(__nothrow_assignable<_T1, _T2>())
1188 {
1189 this->_M_assign(std::move(__in));
1190 return *this;
1191 }
1192
1193 template<typename _U1, typename _U2>
1194 _GLIBCXX20_CONSTEXPR
1195 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1196 operator=(const tuple<_U1, _U2>& __in)
1197 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1198 {
1199 this->_M_assign(__in);
1200 return *this;
1201 }
1202
1203 template<typename _U1, typename _U2>
1204 _GLIBCXX20_CONSTEXPR
1205 __enable_if_t<__assignable<_U1, _U2>(), tuple&>
1206 operator=(tuple<_U1, _U2>&& __in)
1207 noexcept(__nothrow_assignable<_U1, _U2>())
1208 {
1209 this->_M_assign(std::move(__in));
1210 return *this;
1211 }
1212
1213 template<typename _U1, typename _U2>
1214 _GLIBCXX20_CONSTEXPR
1215 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1216 operator=(const pair<_U1, _U2>& __in)
1217 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1218 {
1219 this->_M_head(*this) = __in.first;
1220 this->_M_tail(*this)._M_head(*this) = __in.second;
1221 return *this;
1222 }
1223
1224 template<typename _U1, typename _U2>
1225 _GLIBCXX20_CONSTEXPR
1226 __enable_if_t<__assignable<_U1, _U2>(), tuple&>
1227 operator=(pair<_U1, _U2>&& __in)
1228 noexcept(__nothrow_assignable<_U1, _U2>())
1229 {
1230 this->_M_head(*this) = std::forward<_U1>(__in.first);
1231 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1232 return *this;
1233 }
1234
1235 _GLIBCXX20_CONSTEXPR
1236 void
1237 swap(tuple& __in)
1238 noexcept(__and_<__is_nothrow_swappable<_T1>,
1239 __is_nothrow_swappable<_T2>>::value)
1240 { _Inherited::_M_swap(__in); }
1241 };
1242
1243
1244 /// class tuple_size
1245 template<typename... _Elements>
1246 struct tuple_size<tuple<_Elements...>>
1247 : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1248
1249#if __cplusplus201703L > 201402L
1250 template <typename _Tp>
1251 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1252#endif
1253
1254 /**
1255 * Recursive case for tuple_element: strip off the first element in
1256 * the tuple and retrieve the (i-1)th element of the remaining tuple.
1257 */
1258 template<std::size_t __i, typename _Head, typename... _Tail>
1259 struct tuple_element<__i, tuple<_Head, _Tail...> >
1260 : tuple_element<__i - 1, tuple<_Tail...> > { };
1261
1262 /**
1263 * Basis case for tuple_element: The first element is the one we're seeking.
1264 */
1265 template<typename _Head, typename... _Tail>
1266 struct tuple_element<0, tuple<_Head, _Tail...> >
1267 {
1268 typedef _Head type;
1269 };
1270
1271 /**
1272 * Error case for tuple_element: invalid index.
1273 */
1274 template<size_t __i>
1275 struct tuple_element<__i, tuple<>>
1276 {
1277 static_assert(__i < tuple_size<tuple<>>::value,
1278 "tuple index is in range");
1279 };
1280
1281 template<std::size_t __i, typename _Head, typename... _Tail>
1282 constexpr _Head&
1283 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1284 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1285
1286 template<std::size_t __i, typename _Head, typename... _Tail>
1287 constexpr const _Head&
1288 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1289 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1290
1291 /// Return a reference to the ith element of a tuple.
1292 template<std::size_t __i, typename... _Elements>
1293 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1294 get(tuple<_Elements...>& __t) noexcept
1295 { return std::__get_helper<__i>(__t); }
1296
1297 /// Return a const reference to the ith element of a const tuple.
1298 template<std::size_t __i, typename... _Elements>
1299 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1300 get(const tuple<_Elements...>& __t) noexcept
1301 { return std::__get_helper<__i>(__t); }
1302
1303 /// Return an rvalue reference to the ith element of a tuple rvalue.
1304 template<std::size_t __i, typename... _Elements>
1305 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1306 get(tuple<_Elements...>&& __t) noexcept
1307 {
1308 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1309 return std::forward<__element_type&&>(std::get<__i>(__t));
1310 }
1311
1312 /// Return a const rvalue reference to the ith element of a const tuple rvalue.
1313 template<std::size_t __i, typename... _Elements>
1314 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
1315 get(const tuple<_Elements...>&& __t) noexcept
1316 {
1317 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1318 return std::forward<const __element_type&&>(std::get<__i>(__t));
1319 }
1320
1321#if __cplusplus201703L >= 201402L
1322
1323#define __cpp_lib_tuples_by_type201304 201304
1324
1325 template<typename _Head, size_t __i, typename... _Tail>
1326 constexpr _Head&
1327 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1328 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1329
1330 template<typename _Head, size_t __i, typename... _Tail>
1331 constexpr const _Head&
1332 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1333 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1334
1335 /// Return a reference to the unique element of type _Tp of a tuple.
1336 template <typename _Tp, typename... _Types>
1337 constexpr _Tp&
1338 get(tuple<_Types...>& __t) noexcept
1339 { return std::__get_helper2<_Tp>(__t); }
1340
1341 /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1342 template <typename _Tp, typename... _Types>
1343 constexpr _Tp&&
1344 get(tuple<_Types...>&& __t) noexcept
1345 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1346
1347 /// Return a const reference to the unique element of type _Tp of a tuple.
1348 template <typename _Tp, typename... _Types>
1349 constexpr const _Tp&
1350 get(const tuple<_Types...>& __t) noexcept
1351 { return std::__get_helper2<_Tp>(__t); }
1352
1353 /// Return a const reference to the unique element of type _Tp of
1354 /// a const tuple rvalue.
1355 template <typename _Tp, typename... _Types>
1356 constexpr const _Tp&&
1357 get(const tuple<_Types...>&& __t) noexcept
1358 { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); }
1359#endif
1360
1361 // This class performs the comparison operations on tuples
1362 template<typename _Tp, typename _Up, size_t __i, size_t __size>
1363 struct __tuple_compare
1364 {
1365 static constexpr bool
1366 __eq(const _Tp& __t, const _Up& __u)
1367 {
1368 return bool(std::get<__i>(__t) == std::get<__i>(__u))
1369 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1370 }
1371
1372 static constexpr bool
1373 __less(const _Tp& __t, const _Up& __u)
1374 {
1375 return bool(std::get<__i>(__t) < std::get<__i>(__u))
1376 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1377 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1378 }
1379 };
1380
1381 template<typename _Tp, typename _Up, size_t __size>
1382 struct __tuple_compare<_Tp, _Up, __size, __size>
1383 {
1384 static constexpr bool
1385 __eq(const _Tp&, const _Up&) { return true; }
1386
1387 static constexpr bool
1388 __less(const _Tp&, const _Up&) { return false; }
1389 };
1390
1391 template<typename... _TElements, typename... _UElements>
1392 constexpr bool
1393 operator==(const tuple<_TElements...>& __t,
1394 const tuple<_UElements...>& __u)
1395 {
1396 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1397 "tuple objects can only be compared if they have equal sizes.");
1398 using __compare = __tuple_compare<tuple<_TElements...>,
1399 tuple<_UElements...>,
1400 0, sizeof...(_TElements)>;
1401 return __compare::__eq(__t, __u);
1402 }
1403
1404#if __cpp_lib_three_way_comparison
1405 template<typename _Cat, typename _Tp, typename _Up>
1406 constexpr _Cat
1407 __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
1408 { return _Cat::equivalent; }
1409
1410 template<typename _Cat, typename _Tp, typename _Up,
1411 size_t _Idx0, size_t... _Idxs>
1412 constexpr _Cat
1413 __tuple_cmp(const _Tp& __t, const _Up& __u,
1414 index_sequence<_Idx0, _Idxs...>)
1415 {
1416 auto __c
1417 = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
1418 if (__c != 0)
1419 return __c;
1420 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
1421 }
1422
1423 template<typename... _Tps, typename... _Ups>
1424 constexpr
1425 common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
1426 operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
1427 {
1428 using _Cat
1429 = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
1430 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
1431 }
1432#else
1433 template<typename... _TElements, typename... _UElements>
1434 constexpr bool
1435 operator<(const tuple<_TElements...>& __t,
1436 const tuple<_UElements...>& __u)
1437 {
1438 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1439 "tuple objects can only be compared if they have equal sizes.");
1440 using __compare = __tuple_compare<tuple<_TElements...>,
1441 tuple<_UElements...>,
1442 0, sizeof...(_TElements)>;
1443 return __compare::__less(__t, __u);
1444 }
1445
1446 template<typename... _TElements, typename... _UElements>
1447 constexpr bool
1448 operator!=(const tuple<_TElements...>& __t,
1449 const tuple<_UElements...>& __u)
1450 { return !(__t == __u); }
1451
1452 template<typename... _TElements, typename... _UElements>
1453 constexpr bool
1454 operator>(const tuple<_TElements...>& __t,
1455 const tuple<_UElements...>& __u)
1456 { return __u < __t; }
1457
1458 template<typename... _TElements, typename... _UElements>
1459 constexpr bool
1460 operator<=(const tuple<_TElements...>& __t,
1461 const tuple<_UElements...>& __u)
1462 { return !(__u < __t); }
1463
1464 template<typename... _TElements, typename... _UElements>
1465 constexpr bool
1466 operator>=(const tuple<_TElements...>& __t,
1467 const tuple<_UElements...>& __u)
1468 { return !(__t < __u); }
1469#endif // three_way_comparison
1470
1471 // NB: DR 705.
1472 template<typename... _Elements>
1473 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1474 make_tuple(_Elements&&... __args)
1475 {
1476 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1477 __result_type;
1478 return __result_type(std::forward<_Elements>(__args)...);
1479 }
1480
1481 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1482 // 2275. Why is forward_as_tuple not constexpr?
1483 /// std::forward_as_tuple
1484 template<typename... _Elements>
1485 constexpr tuple<_Elements&&...>
1486 forward_as_tuple(_Elements&&... __args) noexcept
1487 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1488
1489 template<size_t, typename, typename, size_t>
1490 struct __make_tuple_impl;
1491
1492 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1493 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1494 : __make_tuple_impl<_Idx + 1,
1495 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1496 _Tuple, _Nm>
1497 { };
1498
1499 template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1500 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1501 {
1502 typedef tuple<_Tp...> __type;
1503 };
1504
1505 template<typename _Tuple>
1506 struct __do_make_tuple
1507 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1508 { };
1509
1510 // Returns the std::tuple equivalent of a tuple-like type.
1511 template<typename _Tuple>
1512 struct __make_tuple
1513 : public __do_make_tuple<__remove_cvref_t<_Tuple>>
1514 { };
1515
1516 // Combines several std::tuple's into a single one.
1517 template<typename...>
1518 struct __combine_tuples;
1519
1520 template<>
1521 struct __combine_tuples<>
1522 {
1523 typedef tuple<> __type;
1524 };
1525
1526 template<typename... _Ts>
1527 struct __combine_tuples<tuple<_Ts...>>
1528 {
1529 typedef tuple<_Ts...> __type;
1530 };
1531
1532 template<typename... _T1s, typename... _T2s, typename... _Rem>
1533 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1534 {
1535 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1536 _Rem...>::__type __type;
1537 };
1538
1539 // Computes the result type of tuple_cat given a set of tuple-like types.
1540 template<typename... _Tpls>
1541 struct __tuple_cat_result
1542 {
1543 typedef typename __combine_tuples
1544 <typename __make_tuple<_Tpls>::__type...>::__type __type;
1545 };
1546
1547 // Helper to determine the index set for the first tuple-like
1548 // type of a given set.
1549 template<typename...>
1550 struct __make_1st_indices;
1551
1552 template<>
1553 struct __make_1st_indices<>
1554 {
1555 typedef std::_Index_tuple<> __type;
1556 };
1557
1558 template<typename _Tp, typename... _Tpls>
1559 struct __make_1st_indices<_Tp, _Tpls...>
1560 {
1561 typedef typename std::_Build_index_tuple<std::tuple_size<
1562 typename std::remove_reference<_Tp>::type>::value>::__type __type;
1563 };
1564
1565 // Performs the actual concatenation by step-wise expanding tuple-like
1566 // objects into the elements, which are finally forwarded into the
1567 // result tuple.
1568 template<typename _Ret, typename _Indices, typename... _Tpls>
1569 struct __tuple_concater;
1570
1571 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1572 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1573 {
1574 template<typename... _Us>
1575 static constexpr _Ret
1576 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1577 {
1578 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1579 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1580 return __next::_S_do(std::forward<_Tpls>(__tps)...,
1581 std::forward<_Us>(__us)...,
1582 std::get<_Is>(std::forward<_Tp>(__tp))...);
1583 }
1584 };
1585
1586 template<typename _Ret>
1587 struct __tuple_concater<_Ret, std::_Index_tuple<>>
1588 {
1589 template<typename... _Us>
1590 static constexpr _Ret
1591 _S_do(_Us&&... __us)
1592 {
1593 return _Ret(std::forward<_Us>(__us)...);
1594 }
1595 };
1596
1597 /// tuple_cat
1598 template<typename... _Tpls, typename = typename
1599 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1600 constexpr auto
1601 tuple_cat(_Tpls&&... __tpls)
1602 -> typename __tuple_cat_result<_Tpls...>::__type
1603 {
1604 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1605 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1606 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1607 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1608 }
1609
1610 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1611 // 2301. Why is tie not constexpr?
1612 /// tie
1613 template<typename... _Elements>
1614 constexpr tuple<_Elements&...>
1615 tie(_Elements&... __args) noexcept
1616 { return tuple<_Elements&...>(__args...); }
1617
1618 /// swap
1619 template<typename... _Elements>
1620 _GLIBCXX20_CONSTEXPR
1621 inline
1622#if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1623 // Constrained free swap overload, see p0185r1
1624 typename enable_if<__and_<__is_swappable<_Elements>...>::value
1625 >::type
1626#else
1627 void
1628#endif
1629 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1630 noexcept(noexcept(__x.swap(__y)))
1631 { __x.swap(__y); }
1632
1633#if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1634 template<typename... _Elements>
1635 _GLIBCXX20_CONSTEXPR
1636 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1637 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1638#endif
1639
1640 // A class (and instance) which can be used in 'tie' when an element
1641 // of a tuple is not required.
1642 // _GLIBCXX14_CONSTEXPR
1643 // 2933. PR for LWG 2773 could be clearer
1644 struct _Swallow_assign
1645 {
1646 template<class _Tp>
1647 _GLIBCXX14_CONSTEXPRconstexpr const _Swallow_assign&
1648 operator=(const _Tp&) const
1649 { return *this; }
1650 };
1651
1652 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1653 // 2773. Making std::ignore constexpr
1654 _GLIBCXX17_INLINEinline constexpr _Swallow_assign ignore{};
1655
1656 /// Partial specialization for tuples
1657 template<typename... _Types, typename _Alloc>
1658 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1659
1660 // See stl_pair.h...
1661 /** "piecewise construction" using a tuple of arguments for each member.
1662 *
1663 * @param __first Arguments for the first member of the pair.
1664 * @param __second Arguments for the second member of the pair.
1665 *
1666 * The elements of each tuple will be used as the constructor arguments
1667 * for the data members of the pair.
1668 */
1669 template<class _T1, class _T2>
1670 template<typename... _Args1, typename... _Args2>
1671 _GLIBCXX20_CONSTEXPR
1672 inline
1673 pair<_T1, _T2>::
1674 pair(piecewise_construct_t,
1675 tuple<_Args1...> __first, tuple<_Args2...> __second)
1676 : pair(__first, __second,
1677 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1678 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1679 { }
1680
1681 template<class _T1, class _T2>
1682 template<typename... _Args1, std::size_t... _Indexes1,
1683 typename... _Args2, std::size_t... _Indexes2>
1684 _GLIBCXX20_CONSTEXPR inline
1685 pair<_T1, _T2>::
1686 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1687 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1688 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1689 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1690 { }
1691
1692#if __cplusplus201703L >= 201703L
1693
1694 // Unpack a std::tuple into a type trait and use its value.
1695 // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
1696 // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
1697 // Otherwise the result is false (because we don't know if std::get throws).
1698 template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
1699 inline constexpr bool __unpack_std_tuple = false;
1700
1701 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1702 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
1703 = _Trait<_Tp, _Up...>::value;
1704
1705 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1706 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
1707 = _Trait<_Tp, _Up&...>::value;
1708
1709 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1710 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
1711 = _Trait<_Tp, const _Up...>::value;
1712
1713 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1714 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
1715 = _Trait<_Tp, const _Up&...>::value;
1716
1717# define __cpp_lib_apply201603 201603
1718
1719 template <typename _Fn, typename _Tuple, size_t... _Idx>
1720 constexpr decltype(auto)
1721 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1722 {
1723 return std::__invoke(std::forward<_Fn>(__f),
1724 std::get<_Idx>(std::forward<_Tuple>(__t))...);
1725 }
1726
1727 template <typename _Fn, typename _Tuple>
1728 constexpr decltype(auto)
1729 apply(_Fn&& __f, _Tuple&& __t)
1730 noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
1731 {
1732 using _Indices
1733 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
1734 return std::__apply_impl(std::forward<_Fn>(__f),
1735 std::forward<_Tuple>(__t),
1736 _Indices{});
1737 }
1738
1739#define __cpp_lib_make_from_tuple201606 201606
1740
1741 template <typename _Tp, typename _Tuple, size_t... _Idx>
1742 constexpr _Tp
1743 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1744 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1745
1746 template <typename _Tp, typename _Tuple>
1747 constexpr _Tp
1748 make_from_tuple(_Tuple&& __t)
1749 noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
1750 {
1751 return __make_from_tuple_impl<_Tp>(
1752 std::forward<_Tuple>(__t),
1753 make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{});
1754 }
1755#endif // C++17
1756
1757 /// @}
1758
1759_GLIBCXX_END_NAMESPACE_VERSION
1760} // namespace std
1761
1762#endif // C++11
1763
1764#endif // _GLIBCXX_TUPLE