Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

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 cell.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/table/cell.cxx

/home/maarten/src/libreoffice/core/svx/source/table/cell.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
21#include <com/sun/star/drawing/BitmapMode.hpp>
22#include <com/sun/star/style/XStyle.hpp>
23#include <com/sun/star/text/WritingMode.hpp>
24#include <com/sun/star/table/TableBorder.hpp>
25#include <com/sun/star/table/BorderLine2.hpp>
26#include <com/sun/star/lang/Locale.hpp>
27
28#include <comphelper/sequence.hxx>
29#include <o3tl/any.hxx>
30#include <svl/style.hxx>
31#include <svl/itemset.hxx>
32
33#include <vcl/svapp.hxx>
34#include <libxml/xmlwriter.h>
35
36#include <sdr/properties/textproperties.hxx>
37#include <editeng/outlobj.hxx>
38#include <editeng/writingmodeitem.hxx>
39#include <svx/svdotable.hxx>
40#include <svx/svdoutl.hxx>
41#include <svx/unoshtxt.hxx>
42#include <svx/svdmodel.hxx>
43#include <svx/sdooitm.hxx>
44#include <svx/sdtagitm.hxx>
45#include <svx/sdmetitm.hxx>
46#include <svx/xit.hxx>
47#include <getallcharpropids.hxx>
48#include "tableundo.hxx"
49#include <cell.hxx>
50#include <svx/unoshprp.hxx>
51#include <svx/unoshape.hxx>
52#include <editeng/editobj.hxx>
53#include <editeng/borderline.hxx>
54#include <editeng/boxitem.hxx>
55#include <editeng/charrotateitem.hxx>
56#include <svx/xflbstit.hxx>
57#include <svx/xflbmtit.hxx>
58#include <svx/svdpool.hxx>
59#include <tools/diagnose_ex.h>
60
61
62using ::editeng::SvxBorderLine;
63using namespace ::com::sun::star::uno;
64using namespace ::com::sun::star::beans;
65using namespace ::com::sun::star::lang;
66using namespace ::com::sun::star::text;
67using namespace ::com::sun::star::table;
68using namespace ::com::sun::star::drawing;
69using namespace ::com::sun::star::style;
70using namespace ::com::sun::star::container;
71
72
73static const SvxItemPropertySet* ImplGetSvxCellPropertySet()
74{
75 // property map for an outliner text
76 static const SfxItemPropertyMapEntry aSvxCellPropertyMap[] =
77 {
78 FILL_PROPERTIES{ u"" "FillBitmapLogicalSize", XATTR_FILLBMP_SIZELOG, cppu::UnoType
<bool>::get() , 0, 0}, { u"" "FillBitmapOffsetX", XATTR_FILLBMP_TILEOFFSETX
, ::cppu::UnoType<sal_Int32>::get() , 0, 0}, { u"" "FillBitmapOffsetY"
, XATTR_FILLBMP_TILEOFFSETY, ::cppu::UnoType<sal_Int32>
::get() , 0, 0}, { u"" "FillBitmapPositionOffsetX", XATTR_FILLBMP_POSOFFSETX
, ::cppu::UnoType<sal_Int32>::get() , 0, 0}, { u"" "FillBitmapPositionOffsetY"
, XATTR_FILLBMP_POSOFFSETY, ::cppu::UnoType<sal_Int32>::
get() , 0, 0}, { u"" "FillBitmapRectanglePoint", XATTR_FILLBMP_POS
, ::cppu::UnoType<css::drawing::RectanglePoint>::get() ,
0, 0}, { u"" "FillBitmapSizeX", XATTR_FILLBMP_SIZEX, ::cppu::
UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM
}, { u"" "FillBitmapSizeY", XATTR_FILLBMP_SIZEY, ::cppu::UnoType
<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM
}, { u"" "FillBitmapStretch", XATTR_FILLBMP_STRETCH, cppu::UnoType
<bool>::get() , 0, 0}, { u"" "FillBitmapTile", XATTR_FILLBMP_TILE
, cppu::UnoType<bool>::get() , 0, 0}, { u"" "FillBitmapMode"
, (3900 +45), ::cppu::UnoType<css::drawing::BitmapMode>
::get(), 0, 0}, { u"" "FillColor", XATTR_FILLCOLOR, ::cppu::UnoType
<sal_Int32>::get(), 0, 0}, { u"" "FillBackground", XATTR_FILLBACKGROUND
, cppu::UnoType<bool>::get(), 0, 0}, { u"" "FillBitmap"
, XATTR_FILLBITMAP , cppu::UnoType<css::awt::XBitmap>::
get() , 0, 8}, { u"" "FillBitmapURL", XATTR_FILLBITMAP , cppu
::UnoType<OUString>::get(), 0, 8 }, { u"" "FillBitmapName"
, XATTR_FILLBITMAP , ::cppu::UnoType<OUString>::get(), 0
, 16 }, { u"" "FillGradientStepCount", XATTR_GRADIENTSTEPCOUNT
, ::cppu::UnoType<sal_Int16>::get(), 0, 0}, { u"" "FillGradient"
, XATTR_FILLGRADIENT , ::cppu::UnoType<css::awt::Gradient>
::get(), 0, 1}, { u"" "FillGradientName", XATTR_FILLGRADIENT ,
::cppu::UnoType<OUString>::get(), 0, 16 }, { u"" "FillHatch"
, XATTR_FILLHATCH , ::cppu::UnoType<css::drawing::Hatch>
::get(), 0, 1}, { u"" "FillHatchName", XATTR_FILLHATCH , ::cppu
::UnoType<OUString>::get(), 0, 16 }, { u"" "FillStyle",
XATTR_FILLSTYLE , ::cppu::UnoType<css::drawing::FillStyle
>::get() , 0, 0}, { u"" "FillTransparence", XATTR_FILLTRANSPARENCE
, ::cppu::UnoType<sal_Int16>::get() , 0, 0}, { u"" "FillTransparenceGradient"
, XATTR_FILLFLOATTRANSPARENCE, ::cppu::UnoType<css::awt::Gradient
>::get(), 0, 1}, { u"" "FillTransparenceGradientName", XATTR_FILLFLOATTRANSPARENCE
, ::cppu::UnoType<OUString>::get(), 0, 16 }, { u"" "FillColor2"
, XATTR_SECONDARYFILLCOLOR, ::cppu::UnoType<sal_Int32>::
get(), 0, 0}, { u"" "GraphicCrop", SDRATTR_GRAFCROP , ::cppu::
UnoType<css::text::GraphicCrop>::get(), 0, 0 },
79// { "HasLevels", OWN_ATTR_HASLEVELS, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::READONLY, 0},
80 { u"Style", OWN_ATTR_STYLE(3900 +87), cppu::UnoType< css::style::XStyle >::get(), css::beans::PropertyAttribute::MAYBEVOID, 0},
81 { u"" UNO_NAME_TEXT_WRITINGMODE"TextWritingMode", SDRATTR_TEXTDIRECTION, cppu::UnoType<css::text::WritingMode>::get(), 0, 0},
82 { u"" UNO_NAME_TEXT_HORZADJUST"TextHorizontalAdjust", SDRATTR_TEXT_HORZADJUST, cppu::UnoType<css::drawing::TextHorizontalAdjust>::get(), 0, 0},
83 { u"" UNO_NAME_TEXT_LEFTDIST"TextLeftDistance", SDRATTR_TEXT_LEFTDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
84 { u"" UNO_NAME_TEXT_LOWERDIST"TextLowerDistance", SDRATTR_TEXT_LOWERDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
85 { u"" UNO_NAME_TEXT_RIGHTDIST"TextRightDistance", SDRATTR_TEXT_RIGHTDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
86 { u"" UNO_NAME_TEXT_UPPERDIST"TextUpperDistance", SDRATTR_TEXT_UPPERDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
87 { u"" UNO_NAME_TEXT_VERTADJUST"TextVerticalAdjust", SDRATTR_TEXT_VERTADJUST, cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), 0, 0},
88 { u"" UNO_NAME_TEXT_WORDWRAP"TextWordWrap", SDRATTR_TEXT_WORDWRAP, cppu::UnoType<bool>::get(), 0, 0},
89
90 { u"TableBorder", OWN_ATTR_TABLEBORDER(3900 +55), cppu::UnoType<TableBorder>::get(), 0, 0 },
91 { u"TopBorder", SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, TOP_BORDER3 },
92 { u"BottomBorder", SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, BOTTOM_BORDER4 },
93 { u"LeftBorder", SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, LEFT_BORDER1 },
94 { u"RightBorder", SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, RIGHT_BORDER2 },
95 { u"RotateAngle", SDRATTR_TABLE_TEXT_ROTATION, cppu::UnoType<sal_Int32>::get(), 0, 0 },
96
97 SVX_UNOEDIT_OUTLINER_PROPERTIES{u"" "NumberingRules", EE_PARA_NUMBULLET, cppu::UnoType<css
::container::XIndexReplace>::get(), 0, 0 }, {u"" "NumberingIsNumber"
, EE_PARA_BULLETSTATE,cppu::UnoType<bool>::get(), 0, 0 }
, {u"" "NumberingLevel", 3900 +1, ::cppu::UnoType<sal_Int16
>::get(), 0, 0 }, {u"NumberingStartValue", 3900 +3, ::cppu
::UnoType<sal_Int16>::get(), 0, 0 }, {u"ParaIsNumberingRestart"
, 3900 +4, cppu::UnoType<bool>::get(), 0, 0 }
,
98 SVX_UNOEDIT_CHAR_PROPERTIES{ u"" "CharHeight", EE_CHAR_FONTHEIGHT, cppu::UnoType<float
>::get(), 0, 1|0x80 }, { u"CharScaleWidth", EE_CHAR_FONTWIDTH
, ::cppu::UnoType<sal_Int16>::get(), 0, 0 }, { u"" "CharFontName"
, EE_CHAR_FONTINFO, ::cppu::UnoType<OUString>::get(), 0
, 1 }, { u"" "CharFontStyleName",EE_CHAR_FONTINFO, ::cppu::UnoType
<OUString>::get(), 0, 2 }, { u"" "CharFontFamily", EE_CHAR_FONTINFO
, ::cppu::UnoType<sal_Int16>::get(), 0, 3 }, { u"" "CharFontCharSet"
, EE_CHAR_FONTINFO, ::cppu::UnoType<sal_Int16>::get(), 0
, 4 }, { u"" "CharFontPitch", EE_CHAR_FONTINFO, ::cppu::UnoType
<sal_Int16>::get(), 0, 5 }, { u"" "CharPosture", EE_CHAR_ITALIC
, ::cppu::UnoType<css::awt::FontSlant>::get(),0, 1 }, {
u"" "CharWeight", EE_CHAR_WEIGHT, cppu::UnoType<float>
::get(), 0, 1 }, { u"" "CharLocale", EE_CHAR_LANGUAGE, ::cppu
::UnoType<css::lang::Locale>::get(),0, 1 }, { u"" "CharColor"
, EE_CHAR_COLOR, ::cppu::UnoType<sal_Int32>::get(), 0, 0
}, { u"" "CharTransparence",EE_CHAR_COLOR, ::cppu::UnoType<
sal_Int16>::get(), 0, 1 }, { u"CharBackColor", EE_CHAR_BKGCOLOR
, ::cppu::UnoType<sal_Int32>::get(), 0, 0 }, { u"CharBackTransparent"
, EE_CHAR_BKGCOLOR, ::cppu::UnoType<bool>::get(), 0, 3 }
, { u"" "CharEscapement", EE_CHAR_ESCAPEMENT, ::cppu::UnoType
<sal_Int16>::get(), 0, 0 }, { u"" "CharUnderline", EE_CHAR_UNDERLINE
, ::cppu::UnoType<sal_Int16>::get(), 0, 1 }, { u"CharUnderlineColor"
, EE_CHAR_UNDERLINE, ::cppu::UnoType<sal_Int32>::get(),
0, 2 }, { u"CharUnderlineHasColor", EE_CHAR_UNDERLINE, cppu::
UnoType<bool>::get(), 0, 3 } , { u"" "CharOverline", EE_CHAR_OVERLINE
, ::cppu::UnoType<sal_Int16>::get(), 0, 1 }, { u"CharOverlineColor"
, EE_CHAR_OVERLINE, ::cppu::UnoType<sal_Int32>::get(), 0
, 2 }, { u"CharOverlineHasColor", EE_CHAR_OVERLINE, cppu::UnoType
<bool>::get(), 0, 3 } , { u"" "CharCrossedOut", EE_CHAR_STRIKEOUT
, cppu::UnoType<bool>::get(), 0, 0 }, { u"" "CharStrikeout"
, EE_CHAR_STRIKEOUT, ::cppu::UnoType<sal_Int16>::get(),
0, 1}, { u"" "CharCaseMap", EE_CHAR_CASEMAP, ::cppu::UnoType
<sal_Int16>::get(), 0, 0 }, { u"" "CharShadowed", EE_CHAR_SHADOW
, cppu::UnoType<bool>::get(), 0, 0 }, { u"CharContoured"
, EE_CHAR_OUTLINE, cppu::UnoType<bool>::get(), 0, 0 }, {
u"CharEscapementHeight", EE_CHAR_ESCAPEMENT, cppu::UnoType<
sal_Int8>::get(), 0, 1 }, { u"CharAutoKerning", EE_CHAR_PAIRKERNING
,cppu::UnoType<bool>::get(), 0, 0 } , { u"CharKerning",
EE_CHAR_KERNING, ::cppu::UnoType<sal_Int16>::get() , 0
, 0 }, { u"CharWordMode", EE_CHAR_WLM, cppu::UnoType<bool>
::get(), 0, 0 }, { u"CharEmphasis", EE_CHAR_EMPHASISMARK, ::cppu
::UnoType<sal_Int16>::get(), 0, 0}, { u"" "CharHeightAsian"
, EE_CHAR_FONTHEIGHT_CJK, cppu::UnoType<float>::get(), 0
, 1|0x80 }, { u"" "CharFontNameAsian", EE_CHAR_FONTINFO_CJK, ::
cppu::UnoType<OUString>::get(), 0, 1 }, { u"" "CharFontStyleNameAsian"
, EE_CHAR_FONTINFO_CJK, ::cppu::UnoType<OUString>::get(
), 0, 2 }, { u"" "CharFontFamilyAsian", EE_CHAR_FONTINFO_CJK,
::cppu::UnoType<sal_Int16>::get(), 0, 3 }, { u"" "CharFontCharSetAsian"
, EE_CHAR_FONTINFO_CJK, ::cppu::UnoType<sal_Int16>::get
(), 0, 4 }, { u"" "CharFontPitchAsian", EE_CHAR_FONTINFO_CJK,
::cppu::UnoType<sal_Int16>::get(), 0, 5 }, { u"" "CharPostureAsian"
, EE_CHAR_ITALIC_CJK, ::cppu::UnoType<css::awt::FontSlant>
::get(),0, 1 }, { u"" "CharWeightAsian", EE_CHAR_WEIGHT_CJK, cppu
::UnoType<float>::get(), 0, 1 }, { u"" "CharLocaleAsian"
, EE_CHAR_LANGUAGE_CJK, ::cppu::UnoType<css::lang::Locale>
::get(),0, 1 }, { u"" "CharHeightComplex", EE_CHAR_FONTHEIGHT_CTL
, cppu::UnoType<float>::get(), 0, 1|0x80 }, { u"" "CharFontNameComplex"
, EE_CHAR_FONTINFO_CTL, ::cppu::UnoType<OUString>::get(
), 0, 1 }, { u"" "CharFontStyleNameComplex",EE_CHAR_FONTINFO_CTL
, ::cppu::UnoType<OUString>::get(), 0, 2 }, { u"" "CharFontFamilyComplex"
, EE_CHAR_FONTINFO_CTL, ::cppu::UnoType<sal_Int16>::get
(), 0, 3 }, { u"" "CharFontCharSetComplex", EE_CHAR_FONTINFO_CTL
, ::cppu::UnoType<sal_Int16>::get(), 0, 4 }, { u"" "CharFontPitchComplex"
, EE_CHAR_FONTINFO_CTL, ::cppu::UnoType<sal_Int16>::get
(), 0, 5 }, { u"" "CharPostureComplex", EE_CHAR_ITALIC_CTL, ::
cppu::UnoType<css::awt::FontSlant>::get(),0, 1 }, { u""
"CharWeightComplex", EE_CHAR_WEIGHT_CTL, cppu::UnoType<float
>::get(), 0, 1 }, { u"" "CharLocaleComplex", EE_CHAR_LANGUAGE_CTL
, ::cppu::UnoType<css::lang::Locale>::get(),0, 1 }, { u"CharRelief"
, EE_CHAR_RELIEF, ::cppu::UnoType<sal_Int16>::get(), 0,
0 }, { u"CharInteropGrabBag", EE_CHAR_GRABBAG, cppu::UnoType
<css::uno::Sequence<css::beans::PropertyValue >>::
get(), 0, 0}
,
99 SVX_UNOEDIT_PARA_PROPERTIES{u"" "ParaAdjust", EE_PARA_JUST, ::cppu::UnoType<sal_Int16
>::get(), 0, 0 }, {u"" "ParaBottomMargin", EE_PARA_ULSPACE
, ::cppu::UnoType<sal_Int32>::get(), 0, 4, PropertyMoreFlags
::METRIC_ITEM }, {u"" "ParaIsHyphenation", EE_PARA_HYPHENATE,
::cppu::UnoType<bool>::get(), 0, 0 }, {u"ParaHyphenationNoCaps"
, EE_PARA_HYPHENATE_NO_CAPS, ::cppu::UnoType<bool>::get
(), 0, 0 }, {u"" "ParaLastLineAdjust", EE_PARA_JUST, ::cppu::
UnoType<sal_Int16>::get(), 0, 1 }, {u"" "ParaLeftMargin"
, EE_PARA_LRSPACE, ::cppu::UnoType<sal_Int32>::get(), 0
, 11, PropertyMoreFlags::METRIC_ITEM }, {u"" "ParaLineSpacing"
, EE_PARA_SBL, cppu::UnoType<css::style::LineSpacing>::
get(), 0, 0x80}, {u"" "ParaRightMargin", EE_PARA_LRSPACE, ::cppu
::UnoType<sal_Int32>::get(), 0, 5, PropertyMoreFlags::METRIC_ITEM
}, {u"" "ParaTabStops", EE_PARA_TABS, cppu::UnoType<css::
uno::Sequence< css::style::TabStop >>::get(), 0, 0 }
, {u"" "ParaTopMargin", EE_PARA_ULSPACE, ::cppu::UnoType<sal_Int32
>::get(), 0, 3, PropertyMoreFlags::METRIC_ITEM }, {u"" "ParaFirstLineIndent"
, EE_PARA_LRSPACE, ::cppu::UnoType<sal_Int32>::get(), 0
, 8, PropertyMoreFlags::METRIC_ITEM}, {u"" "ParaIsHangingPunctuation"
,EE_PARA_HANGINGPUNCTUATION, cppu::UnoType<bool>::get()
, 0 ,0 }, {u"" "ParaIsCharacterDistance", EE_PARA_ASIANCJKSPACING
, cppu::UnoType<bool>::get(), 0 ,0 }, {u"" "ParaIsForbiddenRules"
, EE_PARA_FORBIDDENRULES, cppu::UnoType<bool>::get(), 0
,0 }, {u"WritingMode", EE_PARA_WRITINGDIR, ::cppu::UnoType<
sal_Int16>::get(), 0, 0 }
,
100 { u"", 0, css::uno::Type(), 0, 0 }
101 };
102
103 static SvxItemPropertySet aSvxCellPropertySet( aSvxCellPropertyMap, SdrObject::GetGlobalDrawObjectItemPool() );
104 return &aSvxCellPropertySet;
105}
106
107namespace
108{
109
110class CellTextProvider : public svx::ITextProvider
111{
112public:
113 explicit CellTextProvider(const sdr::table::CellRef& rCell);
114 virtual ~CellTextProvider();
115
116private:
117 virtual sal_Int32 getTextCount() const override;
118 virtual SdrText* getText(sal_Int32 nIndex) const override;
119
120private:
121 const sdr::table::CellRef m_xCell;
122};
123
124CellTextProvider::CellTextProvider(const sdr::table::CellRef& rCell)
125 : m_xCell(rCell)
126{
127}
128
129CellTextProvider::~CellTextProvider()
130{
131}
132
133sal_Int32 CellTextProvider::getTextCount() const
134{
135 return 1;
136}
137
138SdrText* CellTextProvider::getText(sal_Int32 nIndex) const
139{
140 (void) nIndex;
141 assert(nIndex == 0)(static_cast <bool> (nIndex == 0) ? void (0) : __assert_fail
("nIndex == 0", "/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
, 141, __extension__ __PRETTY_FUNCTION__))
;
142 return m_xCell.get();
143}
144
145}
146
147namespace sdr::properties
148{
149 class CellProperties : public TextProperties
150 {
151 protected:
152 // create a new itemset
153 std::unique_ptr<SfxItemSet> CreateObjectSpecificItemSet(SfxItemPool& rPool) override;
154
155 const svx::ITextProvider& getTextProvider() const override;
156
157 public:
158 // basic constructor
159 CellProperties(SdrObject& rObj, sdr::table::Cell* pCell );
160
161 // constructor for copying, but using new object
162 CellProperties(const CellProperties& rProps, SdrObject& rObj, sdr::table::Cell* pCell);
163
164 // Clone() operator, normally just calls the local copy constructor
165 std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
166
167 void ForceDefaultAttributes() override;
168
169 void ItemSetChanged(const SfxItemSet& rSet) override;
170
171 void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem = nullptr) override;
172
173 sdr::table::CellRef mxCell;
174
175 private:
176 const CellTextProvider maTextProvider;
177 };
178
179 // create a new itemset
180 std::unique_ptr<SfxItemSet> CellProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
181 {
182 return std::make_unique<SfxItemSet>(rPool,
183
184 // range from SdrAttrObj
185 svl::Items<SDRATTR_START, SDRATTR_SHADOW_LAST,
186 SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
187 SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION,
188
189 // range for SdrTableObj
190 SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
191
192 // range from SdrTextObj
193 EE_ITEMS_START, EE_ITEMS_END>{});
194 }
195
196 const svx::ITextProvider& CellProperties::getTextProvider() const
197 {
198 return maTextProvider;
199 }
200
201 CellProperties::CellProperties(SdrObject& rObj, sdr::table::Cell* pCell)
202 : TextProperties(rObj)
203 , mxCell(pCell)
204 , maTextProvider(mxCell)
205 {
206 }
207
208 CellProperties::CellProperties(const CellProperties& rProps, SdrObject& rObj, sdr::table::Cell* pCell)
209 : TextProperties(rProps, rObj)
210 , mxCell( pCell )
211 , maTextProvider(mxCell)
212 {
213 }
214
215 std::unique_ptr<BaseProperties> CellProperties::Clone(SdrObject& rObj) const
216 {
217 OSL_FAIL("CellProperties::Clone(), does not work yet!")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "217" ": "), "%s", "CellProperties::Clone(), does not work yet!"
); } } while (false)
;
218 return std::unique_ptr<BaseProperties>(new CellProperties(*this, rObj,nullptr));
219 }
220
221 void CellProperties::ForceDefaultAttributes()
222 {
223 }
224
225 void CellProperties::ItemSetChanged(const SfxItemSet& rSet )
226 {
227 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
228
229 if( mxCell.is() )
230 {
231 OutlinerParaObject* pParaObj = mxCell->CreateEditOutlinerParaObject().release();
232
233 const bool bOwnParaObj = pParaObj != nullptr;
234
235 if( pParaObj == nullptr )
236 pParaObj = mxCell->GetOutlinerParaObject();
237
238 if(pParaObj)
239 {
240 // handle outliner attributes
241 Outliner* pOutliner = nullptr;
242
243 if(mxCell->IsTextEditActive())
244 {
245 pOutliner = rObj.GetTextEditOutliner();
246 }
247 else
248 {
249 pOutliner = &rObj.ImpGetDrawOutliner();
250 pOutliner->SetText(*pParaObj);
251 }
252
253 sal_Int32 nParaCount(pOutliner->GetParagraphCount());
254
255 // if the user sets character attributes to the complete
256 // cell we want to remove all hard set character attributes
257 // with same which ids from the text
258 std::vector<sal_uInt16> aCharWhichIds(GetAllCharPropIds(rSet));
259
260 for(sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
261 {
262 SfxItemSet aSet(pOutliner->GetParaAttribs(nPara));
263 aSet.Put(rSet);
264
265 for (const auto& rWhichId : aCharWhichIds)
266 {
267 pOutliner->RemoveCharAttribs(nPara, rWhichId);
268 }
269
270 pOutliner->SetParaAttribs(nPara, aSet);
271 }
272
273 if(!mxCell->IsTextEditActive())
274 {
275 if(nParaCount)
276 {
277 // force ItemSet
278 GetObjectItemSet();
279
280 SfxItemSet aNewSet(pOutliner->GetParaAttribs(0));
281 mpItemSet->Put(aNewSet);
282 }
283
284 std::unique_ptr<OutlinerParaObject> pTemp = pOutliner->CreateParaObject(0, nParaCount);
285 pOutliner->Clear();
286 mxCell->SetOutlinerParaObject(std::move(pTemp));
287 }
288
289 if( bOwnParaObj )
290 delete pParaObj;
291 }
292 }
293
294 // call parent
295 AttributeProperties::ItemSetChanged(rSet);
296
297 if( mxCell.is() )
298 mxCell->notifyModified();
299 }
300
301 void CellProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
302 {
303 if(pNewItem && (SDRATTR_TEXTDIRECTION == nWhich))
304 {
305 bool bVertical(css::text::WritingMode_TB_RL == static_cast<const SvxWritingModeItem*>(pNewItem)->GetValue());
306
307 sdr::table::SdrTableObj& rObj = static_cast<sdr::table::SdrTableObj&>(GetSdrObject());
308 rObj.SetVerticalWriting(bVertical);
309
310 // Set a cell vertical property
311 OutlinerParaObject* pParaObj = mxCell->CreateEditOutlinerParaObject().release();
312
313 const bool bOwnParaObj = pParaObj != nullptr;
314
315 if( pParaObj == nullptr )
316 pParaObj = mxCell->GetOutlinerParaObject();
317
318 if(pParaObj)
319 {
320 pParaObj->SetVertical(bVertical);
321
322 if( bOwnParaObj )
323 delete pParaObj;
324 }
325 }
326
327 if (pNewItem && (SDRATTR_TABLE_TEXT_ROTATION == nWhich))
328 {
329 const SvxTextRotateItem* pRotateItem = static_cast<const SvxTextRotateItem*>(pNewItem);
330
331 // Set a cell vertical property
332 OutlinerParaObject* pParaObj = mxCell->CreateEditOutlinerParaObject().release();
333
334 const bool bOwnParaObj = pParaObj != nullptr;
335
336 if (pParaObj == nullptr)
337 pParaObj = mxCell->GetOutlinerParaObject();
338
339 if (pParaObj)
340 {
341 if(pRotateItem->IsVertical() && pRotateItem->IsTopToBottom())
342 pParaObj->SetRotation(TextRotation::TOPTOBOTTOM);
343 else if (pRotateItem->IsVertical())
344 pParaObj->SetRotation(TextRotation::BOTTOMTOTOP);
345 else
346 pParaObj->SetRotation(TextRotation::NONE);
347
348 if (bOwnParaObj)
349 delete pParaObj;
350 }
351
352 // Change autogrow direction
353 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
354
355 // rescue object size
356 tools::Rectangle aObjectRect = rObj.GetSnapRect();
357
358 const SfxItemSet& rSet = rObj.GetObjectItemSet();
359 bool bAutoGrowWidth = rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH).GetValue();
360 bool bAutoGrowHeight = rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue();
361
362 // prepare ItemSet to set exchanged width and height items
363 SfxItemSet aNewSet(*rSet.GetPool(),
364 svl::Items<SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT>{});
365
366 aNewSet.Put(rSet);
367 aNewSet.Put(makeSdrTextAutoGrowWidthItem(bAutoGrowHeight));
368 aNewSet.Put(makeSdrTextAutoGrowHeightItem(bAutoGrowWidth));
369 rObj.SetObjectItemSet(aNewSet);
370
371 // restore object size
372 rObj.SetSnapRect(aObjectRect);
373 }
374
375 // call parent
376 AttributeProperties::ItemChange( nWhich, pNewItem );
377 }
378
379} // end of namespace sdr::properties
380
381namespace sdr::table {
382
383
384// Cell
385
386
387rtl::Reference< Cell > Cell::create( SdrTableObj& rTableObj )
388{
389 rtl::Reference< Cell > xCell( new Cell( rTableObj ) );
390 if( xCell->mxTable.is() )
391 {
392 Reference< XEventListener > xListener( xCell.get() );
393 xCell->mxTable->addEventListener( xListener );
394 }
395 return xCell;
396}
397
398
399Cell::Cell(
400 SdrTableObj& rTableObj)
401: SdrText(rTableObj)
402 ,SvxUnoTextBase( ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() )
403 ,mpPropSet( ImplGetSvxCellPropertySet() )
404 ,mpProperties( new sdr::properties::CellProperties( rTableObj, this ) )
405 ,mnCellContentType( CellContentType_EMPTY )
406 ,mfValue( 0.0 )
407 ,mnError( 0 )
408 ,mbMerged( false )
409 ,mnRowSpan( 1 )
410 ,mnColSpan( 1 )
411 ,mxTable( rTableObj.getTable() )
412{
413 // Caution: Old SetModel() indirectly did a very necessary thing here,
414 // it created a valid SvxTextEditSource which is needed to bind contained
415 // Text to the UNO API and thus to save/load and more. Added version without
416 // model change.
417 // Also done was (not needed, for reference):
418 // SetStyleSheet( nullptr, true );
419 // ForceOutlinerParaObject( OutlinerMode::TextObject );
420 if(nullptr == GetEditSource())
421 {
422 SetEditSource(new SvxTextEditSource(&GetObject(), this));
423 }
424}
425
426
427Cell::~Cell() throw()
428{
429 dispose();
430}
431
432
433void Cell::dispose()
434{
435 if( mxTable.is() )
436 {
437 try
438 {
439 Reference< XEventListener > xThis( this );
440 mxTable->removeEventListener( xThis );
441 }
442 catch( Exception& )
443 {
444 TOOLS_WARN_EXCEPTION("svx.table", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx.table")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "444" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "444" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "444" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "444" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
445 }
446 mxTable.clear();
447 }
448
449 // tdf#118199 avoid double dispose, detect by using mpProperties
450 // as indicator. Only use SetOutlinerParaObject once
451 if( mpProperties )
452 {
453 mpProperties.reset();
454 SetOutlinerParaObject( nullptr );
455 }
456}
457
458void Cell::merge( sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
459{
460 if ((mnColSpan != nColumnSpan) || (mnRowSpan != nRowSpan) || mbMerged)
461 {
462 mnColSpan = nColumnSpan;
463 mnRowSpan = nRowSpan;
464 mbMerged = false;
465 notifyModified();
466 }
467}
468
469
470void Cell::mergeContent( const CellRef& xSourceCell )
471{
472 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
473
474 if( !xSourceCell->hasText() )
475 return;
476
477 SdrOutliner& rOutliner=rTableObj.ImpGetDrawOutliner();
478 rOutliner.SetUpdateMode(true);
479
480 if( hasText() )
481 {
482 rOutliner.SetText(*GetOutlinerParaObject());
483 rOutliner.AddText(*xSourceCell->GetOutlinerParaObject());
484 }
485 else
486 {
487 rOutliner.SetText(*xSourceCell->GetOutlinerParaObject());
488 }
489
490 SetOutlinerParaObject( rOutliner.CreateParaObject() );
491 rOutliner.Clear();
492 xSourceCell->SetOutlinerParaObject(rOutliner.CreateParaObject());
493 rOutliner.Clear();
494 SetStyleSheet( GetStyleSheet(), true );
495}
496
497
498void Cell::cloneFrom( const CellRef& xCell )
499{
500 if( xCell.is() )
501 {
502 replaceContentAndFormating( xCell );
503
504 mnCellContentType = xCell->mnCellContentType;
505
506 msFormula = xCell->msFormula;
507 mfValue = xCell->mfValue;
508 mnError = xCell->mnError;
509
510 mbMerged = xCell->mbMerged;
511 mnRowSpan = xCell->mnRowSpan;
512 mnColSpan = xCell->mnColSpan;
513
514 }
515 notifyModified();
516}
517
518void Cell::replaceContentAndFormating( const CellRef& xSourceCell )
519{
520 if( !(xSourceCell.is() && mpProperties) )
521 return;
522
523 mpProperties->SetMergedItemSet( xSourceCell->GetObjectItemSet() );
524
525 // tdf#118354 OutlinerParaObject may be nullptr, do not dereference when
526 // not set (!)
527 if(nullptr != xSourceCell->GetOutlinerParaObject())
528 {
529 SetOutlinerParaObject( std::make_unique<OutlinerParaObject>(*xSourceCell->GetOutlinerParaObject()) );
530 }
531
532 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
533 SdrTableObj& rSourceTableObj = dynamic_cast< SdrTableObj& >( xSourceCell->GetObject() );
534
535 if(&rSourceTableObj.getSdrModelFromSdrObject() != &rTableObj.getSdrModelFromSdrObject())
536 {
537 // TTTT should not happen - if, then a clone may be needed
538 // Maybe add an assertion here later
539 SetStyleSheet( nullptr, true );
540 }
541}
542
543
544void Cell::setMerged()
545{
546 if( !mbMerged )
547 {
548 mbMerged = true;
549 notifyModified();
550 }
551}
552
553
554void Cell::copyFormatFrom( const CellRef& xSourceCell )
555{
556 if( !(xSourceCell.is() && mpProperties) )
557 return;
558
559 mpProperties->SetMergedItemSet( xSourceCell->GetObjectItemSet() );
560 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
561 SdrTableObj& rSourceTableObj = dynamic_cast< SdrTableObj& >( xSourceCell->GetObject() );
562
563 if(&rSourceTableObj.getSdrModelFromSdrObject() != &rTableObj.getSdrModelFromSdrObject())
564 {
565 // TTTT should not happen - if, then a clone may be needed
566 // Maybe add an assertion here later
567 SetStyleSheet( nullptr, true );
568 }
569
570 notifyModified();
571}
572
573
574void Cell::notifyModified()
575{
576 if( mxTable.is() )
577 mxTable->setModified( true );
578}
579
580
581// SdrTextShape proxy
582
583
584bool Cell::IsActiveCell() const
585{
586 bool isActive = false;
587 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
588 if( rTableObj.getActiveCell().get() == this )
589 isActive = true;
590
591 return isActive;
592}
593
594bool Cell::IsTextEditActive() const
595{
596 bool isActive = false;
597 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
598 if(rTableObj.getActiveCell().get() == this )
599 {
600 if( rTableObj.CanCreateEditOutlinerParaObject() )
601 {
602 isActive = true;
603 }
604 }
605 return isActive;
606}
607
608
609bool Cell::hasText() const
610{
611 OutlinerParaObject* pParaObj = GetOutlinerParaObject();
612 if( pParaObj )
613 {
614 const EditTextObject& rTextObj = pParaObj->GetTextObject();
615 if( rTextObj.GetParagraphCount() >= 1 )
616 {
617 if( rTextObj.GetParagraphCount() == 1 )
618 {
619 if( rTextObj.GetText(0).isEmpty() )
620 return false;
621 }
622 return true;
623 }
624 }
625
626 return false;
627}
628
629bool Cell::CanCreateEditOutlinerParaObject() const
630{
631 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
632 if( rTableObj.getActiveCell().get() == this )
633 return rTableObj.CanCreateEditOutlinerParaObject();
634 return false;
635}
636
637std::unique_ptr<OutlinerParaObject> Cell::CreateEditOutlinerParaObject() const
638{
639 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
640 if( rTableObj.getActiveCell().get() == this )
641 return rTableObj.CreateEditOutlinerParaObject();
642 return nullptr;
643}
644
645
646void Cell::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr )
647{
648 // only allow cell styles for cells
649 if( pStyleSheet && pStyleSheet->GetFamily() != SfxStyleFamily::Frame )
650 return;
651
652 if( mpProperties && (mpProperties->GetStyleSheet() != pStyleSheet) )
653 {
654 mpProperties->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr );
655 }
656}
657
658
659const SfxItemSet& Cell::GetObjectItemSet()
660{
661 if( mpProperties )
662 {
663 return mpProperties->GetObjectItemSet();
664 }
665 else
666 {
667 OSL_FAIL("Cell::GetObjectItemSet(), called without properties!")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "667" ": "), "%s", "Cell::GetObjectItemSet(), called without properties!"
); } } while (false)
;
668 return GetObject().GetObjectItemSet();
669 }
670}
671
672void Cell::SetObjectItem(const SfxPoolItem& rItem)
673{
674 if( mpProperties )
675 {
676 mpProperties->SetObjectItem( rItem );
677 notifyModified();
678 }
679}
680
681void Cell::SetMergedItem(const SfxPoolItem& rItem)
682{
683 SetObjectItem(rItem);
684}
685
686SfxStyleSheet* Cell::GetStyleSheet() const
687{
688 if( mpProperties )
689 return mpProperties->GetStyleSheet();
690 else
691 return nullptr;
692}
693
694void Cell::TakeTextAnchorRect(tools::Rectangle& rAnchorRect) const
695{
696 rAnchorRect.SetLeft( maCellRect.Left() + GetTextLeftDistance() );
697 rAnchorRect.SetRight( maCellRect.Right() - GetTextRightDistance() );
698 rAnchorRect.SetTop( maCellRect.Top() + GetTextUpperDistance() );
699 rAnchorRect.SetBottom( maCellRect.Bottom() - GetTextLowerDistance() );
700}
701
702
703void Cell::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, bool bClearAllItems)
704{
705 if( mpProperties )
706 {
707 mpProperties->SetMergedItemSetAndBroadcast(rSet, bClearAllItems);
708 notifyModified();
709 }
710}
711
712
713sal_Int32 Cell::calcPreferredWidth( const Size aSize )
714{
715 if ( !hasText() )
716 return getMinimumWidth();
717
718 Outliner& rOutliner=static_cast< SdrTableObj& >( GetObject() ).ImpGetDrawOutliner();
719 rOutliner.SetPaperSize(aSize);
720 rOutliner.SetUpdateMode(true);
721 ForceOutlinerParaObject( OutlinerMode::TextObject );
722
723 if( GetOutlinerParaObject() )
724 rOutliner.SetText(*GetOutlinerParaObject());
725
726 sal_Int32 nPreferredWidth = const_cast<EditEngine&>(rOutliner.GetEditEngine()).CalcTextWidth();
727 rOutliner.Clear();
728
729 return GetTextLeftDistance() + GetTextRightDistance() + nPreferredWidth;
730}
731
732sal_Int32 Cell::getMinimumWidth() const
733{
734 return GetTextLeftDistance() + GetTextRightDistance() + 100;
735}
736
737
738sal_Int32 Cell::getMinimumHeight()
739{
740 if( !mpProperties )
741 return 0;
742
743 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
744 sal_Int32 nMinimumHeight = 0;
745
746 tools::Rectangle aTextRect;
747 TakeTextAnchorRect( aTextRect );
748 Size aSize( aTextRect.GetSize() );
749 aSize.setHeight(0x0FFFFFFF );
750
751 SdrOutliner* pEditOutliner = rTableObj.GetCellTextEditOutliner( *this );
752 if(pEditOutliner)
753 {
754 pEditOutliner->SetMaxAutoPaperSize(aSize);
755 nMinimumHeight = pEditOutliner->GetTextHeight()+1;
756 }
757 else
758 {
759 Outliner& rOutliner=rTableObj.ImpGetDrawOutliner();
760 rOutliner.SetPaperSize(aSize);
761 rOutliner.SetUpdateMode(true);
762 ForceOutlinerParaObject( OutlinerMode::TextObject );
763
764 if( GetOutlinerParaObject() )
765 {
766 rOutliner.SetText(*GetOutlinerParaObject());
767 }
768 nMinimumHeight=rOutliner.GetTextHeight()+1;
769 rOutliner.Clear();
770 }
771
772 nMinimumHeight += GetTextUpperDistance() + GetTextLowerDistance();
773 return nMinimumHeight;
774}
775
776
777long Cell::GetTextLeftDistance() const
778{
779 return GetItemSet().Get(SDRATTR_TEXT_LEFTDIST).GetValue();
780}
781
782
783long Cell::GetTextRightDistance() const
784{
785 return GetItemSet().Get(SDRATTR_TEXT_RIGHTDIST).GetValue();
786}
787
788
789long Cell::GetTextUpperDistance() const
790{
791 return GetItemSet().Get(SDRATTR_TEXT_UPPERDIST).GetValue();
792}
793
794
795long Cell::GetTextLowerDistance() const
796{
797 return GetItemSet().Get(SDRATTR_TEXT_LOWERDIST).GetValue();
798}
799
800
801SdrTextVertAdjust Cell::GetTextVerticalAdjust() const
802{
803 return GetItemSet().Get(SDRATTR_TEXT_VERTADJUST).GetValue();
804}
805
806
807SdrTextHorzAdjust Cell::GetTextHorizontalAdjust() const
808{
809 return GetItemSet().Get(SDRATTR_TEXT_HORZADJUST).GetValue();
810}
811
812
813void Cell::SetOutlinerParaObject( std::unique_ptr<OutlinerParaObject> pTextObject )
814{
815 bool bNullTextObject = pTextObject == nullptr;
816 SdrText::SetOutlinerParaObject( std::move(pTextObject) );
817 maSelection.nStartPara = EE_PARA_MAX_COUNT((sal_Int32) 0x7FFFFFFF);
818
819 if( bNullTextObject )
820 ForceOutlinerParaObject( OutlinerMode::TextObject );
821}
822
823
824void Cell::AddUndo()
825{
826 SdrObject& rObj = GetObject();
827
828 if( rObj.IsInserted() && rObj.getSdrModelFromSdrObject().IsUndoEnabled() )
1
Assuming the condition is true
2
Taking true branch
829 {
830 CellRef xCell( this );
831 rObj.getSdrModelFromSdrObject().AddUndo( std::make_unique<CellUndo>( &rObj, xCell ) );
3
Calling 'make_unique<sdr::table::CellUndo, SdrObject *, rtl::Reference<sdr::table::Cell> &>'
14
Returning; memory was released
832
833 // Undo action for the after-text-edit-ended stack.
834 SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(&rObj);
835 if (pTableObj
14.1
'pTableObj' is non-null
14.1
'pTableObj' is non-null
14.1
'pTableObj' is non-null
14.1
'pTableObj' is non-null
14.1
'pTableObj' is non-null
&& pTableObj->IsTextEditActive())
15
Taking true branch
836 pTableObj->AddUndo(new CellUndo(pTableObj, xCell));
16
Calling constructor for 'WeakReference<SdrObject>'
837 }
838}
839
840
841sdr::properties::TextProperties* Cell::CloneProperties( sdr::properties::TextProperties const * pProperties, SdrObject& rNewObj, Cell& rNewCell )
842{
843 if( pProperties )
844 return new sdr::properties::CellProperties( *static_cast<sdr::properties::CellProperties const *>(pProperties), rNewObj, &rNewCell );
845 else
846 return nullptr;
847}
848
849
850sdr::properties::TextProperties* Cell::CloneProperties( SdrObject& rNewObj, Cell& rNewCell )
851{
852 return CloneProperties(mpProperties.get(),rNewObj,rNewCell);
853}
854
855
856// XInterface
857
858
859Any SAL_CALL Cell::queryInterface( const Type & rType )
860{
861 if( rType == cppu::UnoType<XMergeableCell>::get() )
862 return Any( Reference< XMergeableCell >( this ) );
863
864 if( rType == cppu::UnoType<XCell>::get() )
865 return Any( Reference< XCell >( this ) );
866
867 if( rType == cppu::UnoType<XLayoutConstrains>::get() )
868 return Any( Reference< XLayoutConstrains >( this ) );
869
870 if( rType == cppu::UnoType<XEventListener>::get() )
871 return Any( Reference< XEventListener >( this ) );
872
873 Any aRet( SvxUnoTextBase::queryAggregation( rType ) );
874 if( aRet.hasValue() )
875 return aRet;
876
877 return ::cppu::OWeakObject::queryInterface( rType );
878}
879
880
881void SAL_CALL Cell::acquire() throw ()
882{
883 ::cppu::OWeakObject::acquire();
884}
885
886
887void SAL_CALL Cell::release() throw ()
888{
889 ::cppu::OWeakObject::release();
890}
891
892
893// XTypeProvider
894
895
896Sequence< Type > SAL_CALL Cell::getTypes( )
897{
898 return comphelper::concatSequences( SvxUnoTextBase::getTypes(),
899 Sequence {
900 cppu::UnoType<XMergeableCell>::get(),
901 cppu::UnoType<XLayoutConstrains>::get() });
902}
903
904
905Sequence< sal_Int8 > SAL_CALL Cell::getImplementationId( )
906{
907 return css::uno::Sequence<sal_Int8>();
908}
909
910// XLayoutConstrains
911css::awt::Size SAL_CALL Cell::getMinimumSize()
912{
913 return css::awt::Size( getMinimumWidth(), getMinimumHeight() );
914}
915
916
917css::awt::Size SAL_CALL Cell::getPreferredSize()
918{
919 return getMinimumSize();
920}
921
922
923css::awt::Size SAL_CALL Cell::calcAdjustedSize( const css::awt::Size& aNewSize )
924{
925 return aNewSize;
926}
927
928
929// XMergeableCell
930
931
932sal_Int32 SAL_CALL Cell::getRowSpan()
933{
934 return mnRowSpan;
935}
936
937
938sal_Int32 SAL_CALL Cell::getColumnSpan()
939{
940 return mnColSpan;
941}
942
943
944sal_Bool SAL_CALL Cell::isMerged()
945{
946 return mbMerged;
947}
948
949
950// XCell
951
952
953OUString SAL_CALL Cell::getFormula( )
954{
955 return msFormula;
956}
957
958
959void SAL_CALL Cell::setFormula( const OUString& aFormula )
960{
961 if( msFormula != aFormula )
962 {
963 msFormula = aFormula;
964 }
965}
966
967
968double SAL_CALL Cell::getValue( )
969{
970 return mfValue;
971}
972
973
974void SAL_CALL Cell::setValue( double nValue )
975{
976 if( mfValue != nValue )
977 {
978 mfValue = nValue;
979 mnCellContentType = CellContentType_VALUE;
980 }
981}
982
983
984CellContentType SAL_CALL Cell::getType()
985{
986 return mnCellContentType;
987}
988
989
990sal_Int32 SAL_CALL Cell::getError( )
991{
992 return mnError;
993}
994
995
996// XPropertySet
997
998
999Any Cell::GetAnyForItem( SfxItemSet const & aSet, const SfxItemPropertySimpleEntry* pMap )
1000{
1001 Any aAny( SvxItemPropertySet_getPropertyValue( pMap, aSet ) );
1002
1003 if( pMap->aType != aAny.getValueType() )
1004 {
1005 // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
1006 if( ( pMap->aType == ::cppu::UnoType<sal_Int16>::get()) && aAny.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
1007 {
1008 sal_Int32 nValue = 0;
1009 aAny >>= nValue;
1010 aAny <<= static_cast<sal_Int16>(nValue);
1011 }
1012 else
1013 {
1014 OSL_FAIL("GetAnyForItem() Returnvalue has wrong Type!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1014" ": "), "%s", "GetAnyForItem() Returnvalue has wrong Type!"
); } } while (false)
;
1015 }
1016 }
1017
1018 return aAny;
1019}
1020
1021Reference< XPropertySetInfo > SAL_CALL Cell::getPropertySetInfo()
1022{
1023 return mpPropSet->getPropertySetInfo();
1024}
1025
1026
1027void SAL_CALL Cell::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
1028{
1029 ::SolarMutexGuard aGuard;
1030
1031 if(mpProperties == nullptr)
1032 throw DisposedException();
1033
1034 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(rPropertyName);
1035 if( pMap )
1036 {
1037 if( (pMap->nFlags & PropertyAttribute::READONLY ) != 0 )
1038 throw PropertyVetoException();
1039
1040 switch( pMap->nWID )
1041 {
1042 case OWN_ATTR_STYLE(3900 +87):
1043 {
1044 Reference< XStyle > xStyle;
1045 if( !( rValue >>= xStyle ) )
1046 throw IllegalArgumentException();
1047
1048 SfxUnoStyleSheet* pStyle = SfxUnoStyleSheet::getUnoStyleSheet(xStyle);
1049 SetStyleSheet( pStyle, true );
1050 return;
1051 }
1052 case OWN_ATTR_TABLEBORDER(3900 +55):
1053 {
1054 auto pBorder = o3tl::tryAccess<TableBorder>(rValue);
1055 if(!pBorder)
1056 break;
1057
1058 SvxBoxItem aBox( SDRATTR_TABLE_BORDER );
1059 SvxBoxInfoItem aBoxInfo( SDRATTR_TABLE_BORDER_INNER );
1060 SvxBorderLine aLine;
1061
1062 bool bSet = SvxBoxItem::LineToSvxLine(pBorder->TopLine, aLine, false);
1063 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::TOP);
1064 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::TOP, pBorder->IsTopLineValid);
1065
1066 bSet = SvxBoxItem::LineToSvxLine(pBorder->BottomLine, aLine, false);
1067 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::BOTTOM);
1068 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::BOTTOM, pBorder->IsBottomLineValid);
1069
1070 bSet = SvxBoxItem::LineToSvxLine(pBorder->LeftLine, aLine, false);
1071 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::LEFT);
1072 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::LEFT, pBorder->IsLeftLineValid);
1073
1074 bSet = SvxBoxItem::LineToSvxLine(pBorder->RightLine, aLine, false);
1075 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::RIGHT);
1076 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::RIGHT, pBorder->IsRightLineValid);
1077
1078 bSet = SvxBoxItem::LineToSvxLine(pBorder->HorizontalLine, aLine, false);
1079 aBoxInfo.SetLine(bSet ? &aLine : nullptr, SvxBoxInfoItemLine::HORI);
1080 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::HORI, pBorder->IsHorizontalLineValid);
1081
1082 bSet = SvxBoxItem::LineToSvxLine(pBorder->VerticalLine, aLine, false);
1083 aBoxInfo.SetLine(bSet ? &aLine : nullptr, SvxBoxInfoItemLine::VERT);
1084 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::VERT, pBorder->IsVerticalLineValid);
1085
1086 aBox.SetAllDistances(pBorder->Distance); //TODO
1087 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::DISTANCE, pBorder->IsDistanceValid);
1088
1089 mpProperties->SetObjectItem(aBox);
1090 mpProperties->SetObjectItem(aBoxInfo);
1091 return;
1092 }
1093 case OWN_ATTR_FILLBMP_MODE(3900 +45):
1094 {
1095 BitmapMode eMode;
1096 if(!(rValue >>= eMode) )
1097 {
1098 sal_Int32 nMode = 0;
1099 if(!(rValue >>= nMode))
1100 throw IllegalArgumentException();
1101
1102 eMode = static_cast<BitmapMode>(nMode);
1103 }
1104
1105 mpProperties->SetObjectItem( XFillBmpStretchItem( eMode == BitmapMode_STRETCH ) );
1106 mpProperties->SetObjectItem( XFillBmpTileItem( eMode == BitmapMode_REPEAT ) );
1107 return;
1108 }
1109 case SDRATTR_TABLE_TEXT_ROTATION:
1110 {
1111 sal_Int32 nRotVal = 0;
1112 if (!(rValue >>= nRotVal))
1113 throw IllegalArgumentException();
1114
1115 if (nRotVal != 27000 && nRotVal != 9000 && nRotVal != 0)
1116 throw IllegalArgumentException();
1117
1118 mpProperties->SetObjectItem(SvxTextRotateItem(nRotVal/10, SDRATTR_TABLE_TEXT_ROTATION));
1119 return;
1120 }
1121 default:
1122 {
1123 SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), {{pMap->nWID, pMap->nWID}});
1124 aSet.Put(mpProperties->GetItem(pMap->nWID));
1125
1126 bool bSpecial = false;
1127
1128 switch( pMap->nWID )
1129 {
1130 case XATTR_FILLBITMAP:
1131 case XATTR_FILLGRADIENT:
1132 case XATTR_FILLHATCH:
1133 case XATTR_FILLFLOATTRANSPARENCE:
1134 case XATTR_LINEEND:
1135 case XATTR_LINESTART:
1136 case XATTR_LINEDASH:
1137 {
1138 if( pMap->nMemberId == MID_NAME16 )
1139 {
1140 OUString aApiName;
1141 if( rValue >>= aApiName )
1142 {
1143 if(SvxShape::SetFillAttribute(pMap->nWID, aApiName, aSet, &GetObject().getSdrModelFromSdrObject()))
1144 bSpecial = true;
1145 }
1146 }
1147 }
1148 break;
1149 }
1150
1151 if( !bSpecial )
1152 {
1153
1154 if( !SvxUnoTextRangeBase::SetPropertyValueHelper( pMap, rValue, aSet ))
1155 {
1156 if( aSet.GetItemState( pMap->nWID ) != SfxItemState::SET )
1157 {
1158 // fetch the default from ItemPool
1159 if(SfxItemPool::IsWhich(pMap->nWID))
1160 aSet.Put(GetObject().getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1161 }
1162
1163 if( aSet.GetItemState( pMap->nWID ) == SfxItemState::SET )
1164 {
1165 SvxItemPropertySet_setPropertyValue( pMap, rValue, aSet );
1166 }
1167 }
1168 }
1169
1170 GetObject().getSdrModelFromSdrObject().SetChanged();
1171 mpProperties->SetMergedItemSetAndBroadcast( aSet );
1172 return;
1173 }
1174 }
1175 }
1176 throw UnknownPropertyException( rPropertyName, static_cast<cppu::OWeakObject*>(this));
1177}
1178
1179
1180Any SAL_CALL Cell::getPropertyValue( const OUString& PropertyName )
1181{
1182 ::SolarMutexGuard aGuard;
1183
1184 if(mpProperties == nullptr)
1185 throw DisposedException();
1186
1187 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1188 if( pMap )
1189 {
1190 switch( pMap->nWID )
1191 {
1192 case OWN_ATTR_STYLE(3900 +87):
1193 {
1194 return Any( Reference< XStyle >( dynamic_cast< SfxUnoStyleSheet* >( GetStyleSheet() ) ) );
1195 }
1196 case OWN_ATTR_TABLEBORDER(3900 +55):
1197 {
1198 const SvxBoxInfoItem& rBoxInfoItem = mpProperties->GetItem(SDRATTR_TABLE_BORDER_INNER);
1199 const SvxBoxItem& rBox = mpProperties->GetItem(SDRATTR_TABLE_BORDER);
1200
1201 TableBorder aTableBorder;
1202 aTableBorder.TopLine = SvxBoxItem::SvxLineToLine(rBox.GetTop(), false);
1203 aTableBorder.IsTopLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::TOP);
1204 aTableBorder.BottomLine = SvxBoxItem::SvxLineToLine(rBox.GetBottom(), false);
1205 aTableBorder.IsBottomLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::BOTTOM);
1206 aTableBorder.LeftLine = SvxBoxItem::SvxLineToLine(rBox.GetLeft(), false);
1207 aTableBorder.IsLeftLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::LEFT);
1208 aTableBorder.RightLine = SvxBoxItem::SvxLineToLine(rBox.GetRight(), false);
1209 aTableBorder.IsRightLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::RIGHT );
1210 aTableBorder.HorizontalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetHori(), false);
1211 aTableBorder.IsHorizontalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::HORI);
1212 aTableBorder.VerticalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetVert(), false);
1213 aTableBorder.IsVerticalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::VERT);
1214 aTableBorder.Distance = rBox.GetSmallestDistance();
1215 aTableBorder.IsDistanceValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::DISTANCE);
1216
1217 return Any( aTableBorder );
1218 }
1219 case OWN_ATTR_FILLBMP_MODE(3900 +45):
1220 {
1221 const XFillBmpStretchItem& rStretchItem = mpProperties->GetItem(XATTR_FILLBMP_STRETCH);
1222 const XFillBmpTileItem& rTileItem = mpProperties->GetItem(XATTR_FILLBMP_TILE);
1223 if( rTileItem.GetValue() )
1224 {
1225 return Any( BitmapMode_REPEAT );
1226 }
1227 else if( rStretchItem.GetValue() )
1228 {
1229 return Any( BitmapMode_STRETCH );
1230 }
1231 else
1232 {
1233 return Any( BitmapMode_NO_REPEAT );
1234 }
1235 }
1236 case SDRATTR_TABLE_TEXT_ROTATION:
1237 {
1238 const SvxTextRotateItem& rTextRotate = mpProperties->GetItem(SDRATTR_TABLE_TEXT_ROTATION);
1239 return Any(sal_Int32(rTextRotate.GetValue() * 10));
1240 }
1241 default:
1242 {
1243 SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), {{pMap->nWID, pMap->nWID}});
1244 aSet.Put(mpProperties->GetItem(pMap->nWID));
1245
1246 Any aAny;
1247 if(!SvxUnoTextRangeBase::GetPropertyValueHelper( aSet, pMap, aAny ))
1248 {
1249 if(!aSet.Count())
1250 {
1251 // fetch the default from ItemPool
1252 if(SfxItemPool::IsWhich(pMap->nWID))
1253 aSet.Put(GetObject().getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1254 }
1255
1256 if( aSet.Count() )
1257 aAny = GetAnyForItem( aSet, pMap );
1258 }
1259
1260 return aAny;
1261 }
1262 }
1263 }
1264 throw UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
1265}
1266
1267
1268void SAL_CALL Cell::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ )
1269{
1270}
1271
1272
1273void SAL_CALL Cell::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ )
1274{
1275}
1276
1277
1278void SAL_CALL Cell::addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
1279{
1280}
1281
1282
1283void SAL_CALL Cell::removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
1284{
1285}
1286
1287
1288// XMultiPropertySet
1289
1290
1291void SAL_CALL Cell::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues )
1292{
1293 ::SolarMutexGuard aSolarGuard;
1294
1295 if(mpProperties == nullptr)
1296 throw DisposedException();
1297
1298 const sal_Int32 nCount = aPropertyNames.getLength();
1299
1300 const OUString* pNames = aPropertyNames.getConstArray();
1301 const Any* pValues = aValues.getConstArray();
1302
1303 for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
1304 {
1305 try
1306 {
1307 setPropertyValue( *pNames, *pValues );
1308 }
1309 catch( UnknownPropertyException& )
1310 {
1311 TOOLS_WARN_EXCEPTION("svx.table", "unknown property!")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx.table")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unknown property!" <<
" " << exceptionToString(tools_warn_exception)) == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.table"
), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1311" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unknown property!" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown property!" << " " << exceptionToString(
tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1311" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unknown property!" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1311" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unknown property!" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown property!" << " " << exceptionToString(
tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1311" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1312 }
1313 catch( Exception& )
1314 {
1315 TOOLS_WARN_EXCEPTION("svx.table", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx.table")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1315" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1315" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1315" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1315" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1316 }
1317 }
1318}
1319
1320
1321Sequence< Any > SAL_CALL Cell::getPropertyValues( const Sequence< OUString >& aPropertyNames )
1322{
1323 ::SolarMutexGuard aSolarGuard;
1324
1325 if(mpProperties == nullptr)
1326 throw DisposedException();
1327
1328 const sal_Int32 nCount = aPropertyNames.getLength();
1329 Sequence< Any > aRet( nCount );
1330 Any* pValue = aRet.getArray();
1331
1332 for( const OUString& rName : aPropertyNames )
1333 {
1334 try
1335 {
1336 *pValue = getPropertyValue( rName );
1337 }
1338 catch( UnknownPropertyException& )
1339 {
1340 TOOLS_WARN_EXCEPTION("svx.table", "unknown property!")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx.table")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unknown property!" <<
" " << exceptionToString(tools_warn_exception)) == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.table"
), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1340" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unknown property!" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown property!" << " " << exceptionToString(
tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1340" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unknown property!" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1340" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unknown property!" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown property!" << " " << exceptionToString(
tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1340" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1341 }
1342 catch( Exception& )
1343 {
1344 TOOLS_WARN_EXCEPTION("svx.table", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx.table")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1344" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1344" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1344" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.table"), ("/home/maarten/src/libreoffice/core/svx/source/table/cell.cxx"
":" "1344" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1345 }
1346 pValue++;
1347 }
1348
1349 return aRet;
1350}
1351
1352
1353void SAL_CALL Cell::addPropertiesChangeListener( const Sequence< OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ )
1354{
1355}
1356
1357
1358void SAL_CALL Cell::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& /*xListener*/ )
1359{
1360}
1361
1362
1363void SAL_CALL Cell::firePropertiesChangeEvent( const Sequence< OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ )
1364{
1365}
1366
1367
1368// XPropertyState
1369
1370
1371PropertyState SAL_CALL Cell::getPropertyState( const OUString& PropertyName )
1372{
1373 ::SolarMutexGuard aGuard;
1374
1375 if(mpProperties == nullptr)
1376 throw DisposedException();
1377
1378 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1379
1380 if( pMap )
1381 {
1382 PropertyState eState;
1383 switch( pMap->nWID )
1384 {
1385 case OWN_ATTR_FILLBMP_MODE(3900 +45):
1386 {
1387 const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
1388
1389 const bool bStretch = rSet.GetItemState( XATTR_FILLBMP_STRETCH, false ) == SfxItemState::SET;
1390 const bool bTile = rSet.GetItemState( XATTR_FILLBMP_TILE, false ) == SfxItemState::SET;
1391 if( bStretch || bTile )
1392 {
1393 eState = PropertyState_DIRECT_VALUE;
1394 }
1395 else
1396 {
1397 eState = PropertyState_DEFAULT_VALUE;
1398 }
1399 break;
1400 }
1401 case OWN_ATTR_STYLE(3900 +87):
1402 {
1403 return PropertyState_DIRECT_VALUE;
1404 }
1405 case OWN_ATTR_TABLEBORDER(3900 +55):
1406 {
1407 const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
1408 if( (rSet.GetItemState( SDRATTR_TABLE_BORDER_INNER, false ) == SfxItemState::DEFAULT) && (rSet.GetItemState( SDRATTR_TABLE_BORDER, false ) == SfxItemState::DEFAULT) )
1409 return PropertyState_DEFAULT_VALUE;
1410
1411 return PropertyState_DIRECT_VALUE;
1412 }
1413 default:
1414 {
1415 const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
1416
1417 switch( rSet.GetItemState( pMap->nWID, false ) )
1418 {
1419 case SfxItemState::READONLY:
1420 case SfxItemState::SET:
1421 eState = PropertyState_DIRECT_VALUE;
1422 break;
1423 case SfxItemState::DEFAULT:
1424 eState = PropertyState_DEFAULT_VALUE;
1425 break;
1426 default:
1427 eState = PropertyState_AMBIGUOUS_VALUE;
1428 break;
1429 }
1430
1431 // if an item is set, this doesn't mean we want it :)
1432 if( PropertyState_DIRECT_VALUE == eState )
1433 {
1434 switch( pMap->nWID )
1435 {
1436 // the following items are disabled by changing the
1437 // fill style or the line style. so there is no need
1438 // to export items without names which should be empty
1439 case XATTR_FILLBITMAP:
1440 case XATTR_FILLGRADIENT:
1441 case XATTR_FILLHATCH:
1442 case XATTR_LINEDASH:
1443 {
1444 const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1445 if( ( pItem == nullptr ) || pItem->GetName().isEmpty() )
1446 eState = PropertyState_DEFAULT_VALUE;
1447 }
1448 break;
1449
1450 // #i36115#
1451 // If e.g. the LineStart is on NONE and thus the string has length 0, it still
1452 // may be a hard attribute covering the set LineStart of the parent (Style).
1453 // #i37644#
1454 // same is for fill float transparency
1455 case XATTR_LINEEND:
1456 case XATTR_LINESTART:
1457 case XATTR_FILLFLOATTRANSPARENCE:
1458 {
1459 const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1460 if( pItem == nullptr )
1461 eState = PropertyState_DEFAULT_VALUE;
1462 }
1463 break;
1464 }
1465 }
1466 }
1467 }
1468 return eState;
1469 }
1470 throw UnknownPropertyException(PropertyName);
1471}
1472
1473
1474Sequence< PropertyState > SAL_CALL Cell::getPropertyStates( const Sequence< OUString >& aPropertyName )
1475{
1476 ::SolarMutexGuard aGuard;
1477
1478 if(mpProperties == nullptr)
1479 throw DisposedException();
1480
1481 const sal_Int32 nCount = aPropertyName.getLength();
1482 Sequence< PropertyState > aRet( nCount );
1483
1484 std::transform(aPropertyName.begin(), aPropertyName.end(), aRet.begin(),
1485 [this](const OUString& rName) -> PropertyState {
1486 try
1487 {
1488 return getPropertyState( rName );
1489 }
1490 catch( Exception& )
1491 {
1492 return PropertyState_AMBIGUOUS_VALUE;
1493 }
1494 });
1495
1496 return aRet;
1497}
1498
1499
1500void SAL_CALL Cell::setPropertyToDefault( const OUString& PropertyName )
1501{
1502 ::SolarMutexGuard aGuard;
1503
1504 if(mpProperties == nullptr)
1505 throw DisposedException();
1506
1507 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1508 if( pMap )
1509 {
1510 switch( pMap->nWID )
1511 {
1512 case OWN_ATTR_FILLBMP_MODE(3900 +45):
1513 {
1514 mpProperties->ClearObjectItem( XATTR_FILLBMP_STRETCH );
1515 mpProperties->ClearObjectItem( XATTR_FILLBMP_TILE );
1516 break;
1517 }
1518 case OWN_ATTR_STYLE(3900 +87):
1519 break;
1520
1521 case OWN_ATTR_TABLEBORDER(3900 +55):
1522 {
1523 mpProperties->ClearObjectItem( SDRATTR_TABLE_BORDER_INNER );
1524 mpProperties->ClearObjectItem( SDRATTR_TABLE_BORDER );
1525 break;
1526 }
1527
1528 default:
1529 {
1530 mpProperties->ClearObjectItem( pMap->nWID );
1531 }
1532 }
1533
1534 GetObject().getSdrModelFromSdrObject().SetChanged();
1535 return;
1536 }
1537 throw UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
1538}
1539
1540
1541Any SAL_CALL Cell::getPropertyDefault( const OUString& aPropertyName )
1542{
1543 ::SolarMutexGuard aGuard;
1544
1545 if(mpProperties == nullptr)
1546 throw DisposedException();
1547
1548 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(aPropertyName);
1549 if( pMap )
1550 {
1551 switch( pMap->nWID )
1552 {
1553 case OWN_ATTR_FILLBMP_MODE(3900 +45):
1554 return Any( BitmapMode_NO_REPEAT );
1555
1556 case OWN_ATTR_STYLE(3900 +87):
1557 {
1558 Reference< XStyle > xStyle;
1559 return Any( xStyle );
1560 }
1561
1562 case OWN_ATTR_TABLEBORDER(3900 +55):
1563 {
1564 TableBorder aBorder;
1565 return Any( aBorder );
1566 }
1567
1568 default:
1569 {
1570 if( SfxItemPool::IsWhich(pMap->nWID) )
1571 {
1572 SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), {{pMap->nWID, pMap->nWID}});
1573 aSet.Put(GetObject().getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1574 return GetAnyForItem( aSet, pMap );
1575 }
1576 }
1577 }
1578 }
1579 throw UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
1580}
1581
1582
1583// XMultiPropertyStates
1584
1585
1586void SAL_CALL Cell::setAllPropertiesToDefault()
1587{
1588 mpProperties.reset(new sdr::properties::CellProperties( static_cast< SdrTableObj& >( GetObject() ), this ));
1589
1590 SdrOutliner& rOutliner = GetObject().ImpGetDrawOutliner();
1591
1592 OutlinerParaObject* pParaObj = GetOutlinerParaObject();
1593 if( !pParaObj )
1594 return;
1595
1596 rOutliner.SetText(*pParaObj);
1597 sal_Int32 nParaCount(rOutliner.GetParagraphCount());
1598
1599 if(nParaCount)
1600 {
1601 ESelection aSelection( 0, 0, EE_PARA_ALL((sal_Int32) 0x7FFFFFFF), EE_TEXTPOS_ALL((sal_Int32) 0x7FFFFFFF));
1602 rOutliner.RemoveAttribs(aSelection, true, 0);
1603
1604 std::unique_ptr<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
1605 rOutliner.Clear();
1606
1607 SetOutlinerParaObject(std::move(pTemp));
1608 }
1609}
1610
1611
1612void SAL_CALL Cell::setPropertiesToDefault( const Sequence< OUString >& aPropertyNames )
1613{
1614 for(const OUString& rName : aPropertyNames)
1615 setPropertyToDefault( rName );
1616}
1617
1618
1619Sequence< Any > SAL_CALL Cell::getPropertyDefaults( const Sequence< OUString >& aPropertyNames )
1620{
1621 sal_Int32 nCount = aPropertyNames.getLength();
1622 Sequence< Any > aDefaults( nCount );
1623
1624 std::transform(aPropertyNames.begin(), aPropertyNames.end(), aDefaults.begin(),
1625 [this](const OUString& rName) -> Any { return getPropertyDefault(rName); });
1626
1627 return aDefaults;
1628}
1629
1630
1631// XText
1632
1633
1634void SAL_CALL Cell::insertTextContent( const Reference< XTextRange >& xRange, const Reference< XTextContent >& xContent, sal_Bool bAbsorb )
1635{
1636 SvxUnoTextBase::insertTextContent( xRange, xContent, bAbsorb );
1637 notifyModified();
1638}
1639
1640
1641void SAL_CALL Cell::removeTextContent( const Reference< XTextContent >& xContent )
1642{
1643 SvxUnoTextBase::removeTextContent( xContent );
1644 notifyModified();
1645}
1646
1647
1648// XSimpleText
1649
1650
1651void SAL_CALL Cell::insertString( const Reference< XTextRange >& xRange, const OUString& aString, sal_Bool bAbsorb )
1652{
1653 SvxUnoTextBase::insertString( xRange, aString, bAbsorb );
1654 notifyModified();
1655}
1656
1657
1658void SAL_CALL Cell::insertControlCharacter( const Reference< XTextRange >& xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1659{
1660 SvxUnoTextBase::insertControlCharacter( xRange, nControlCharacter, bAbsorb );
1661 notifyModified();
1662}
1663
1664
1665// XTextRange
1666
1667
1668OUString SAL_CALL Cell::getString( )
1669{
1670 maSelection.nStartPara = EE_PARA_MAX_COUNT((sal_Int32) 0x7FFFFFFF);
1671 return SvxUnoTextBase::getString();
1672}
1673
1674
1675void SAL_CALL Cell::setString( const OUString& aString )
1676{
1677 SvxUnoTextBase::setString( aString );
1678 notifyModified();
1679}
1680
1681// XEventListener
1682void SAL_CALL Cell::disposing( const EventObject& /*Source*/ )
1683{
1684 mxTable.clear();
1685 dispose();
1686}
1687
1688void Cell::dumpAsXml(xmlTextWriterPtr pWriter, sal_Int32 nRow, sal_Int32 nCol) const
1689{
1690 xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("Cell"));
1691 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST(xmlChar *)("row"), "%" SAL_PRIdINT32"d", nRow);
1692 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST(xmlChar *)("col"), "%" SAL_PRIdINT32"d", nCol);
1693 SdrText::dumpAsXml(pWriter);
1694 //SvxUnoTextBase::dumpAsXml(pWriter);
1695 //mpPropSet->dumpAsXml(pWriter);
1696 mpProperties->dumpAsXml(pWriter);
1697 xmlTextWriterEndElement(pWriter);
1698}
1699
1700}
1701
1702/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

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

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38#include <bits/stl_function.h>
39#include <bits/functional_hash.h>
40#if __cplusplus201703L > 201703L
41# include <compare>
42# include <ostream>
43#endif
44
45namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
46{
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
48
49 /**
50 * @addtogroup pointer_abstractions
51 * @{
52 */
53
54#if _GLIBCXX_USE_DEPRECATED1
55#pragma GCC diagnostic push
56#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
57 template<typename> class auto_ptr;
58#pragma GCC diagnostic pop
59#endif
60
61 /// Primary template of default_delete, used by unique_ptr for single objects
62 template<typename _Tp>
63 struct default_delete
64 {
65 /// Default constructor
66 constexpr default_delete() noexcept = default;
67
68 /** @brief Converting constructor.
69 *
70 * Allows conversion from a deleter for objects of another type, `_Up`,
71 * only if `_Up*` is convertible to `_Tp*`.
72 */
73 template<typename _Up,
74 typename = _Require<is_convertible<_Up*, _Tp*>>>
75 default_delete(const default_delete<_Up>&) noexcept { }
76
77 /// Calls `delete __ptr`
78 void
79 operator()(_Tp* __ptr) const
80 {
81 static_assert(!is_void<_Tp>::value,
82 "can't delete pointer to incomplete type");
83 static_assert(sizeof(_Tp)>0,
84 "can't delete pointer to incomplete type");
85 delete __ptr;
86 }
87 };
88
89 // _GLIBCXX_RESOLVE_LIB_DEFECTS
90 // DR 740 - omit specialization for array objects with a compile time length
91
92 /// Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
93 template<typename _Tp>
94 struct default_delete<_Tp[]>
95 {
96 public:
97 /// Default constructor
98 constexpr default_delete() noexcept = default;
99
100 /** @brief Converting constructor.
101 *
102 * Allows conversion from a deleter for arrays of another type, such as
103 * a const-qualified version of `_Tp`.
104 *
105 * Conversions from types derived from `_Tp` are not allowed because
106 * it is undefined to `delete[]` an array of derived types through a
107 * pointer to the base type.
108 */
109 template<typename _Up,
110 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
111 default_delete(const default_delete<_Up[]>&) noexcept { }
112
113 /// Calls `delete[] __ptr`
114 template<typename _Up>
115 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
116 operator()(_Up* __ptr) const
117 {
118 static_assert(sizeof(_Tp)>0,
119 "can't delete pointer to incomplete type");
120 delete [] __ptr;
121 }
122 };
123
124 /// @cond undocumented
125
126 // Manages the pointer and deleter of a unique_ptr
127 template <typename _Tp, typename _Dp>
128 class __uniq_ptr_impl
129 {
130 template <typename _Up, typename _Ep, typename = void>
131 struct _Ptr
132 {
133 using type = _Up*;
134 };
135
136 template <typename _Up, typename _Ep>
137 struct
138 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
139 {
140 using type = typename remove_reference<_Ep>::type::pointer;
141 };
142
143 public:
144 using _DeleterConstraint = enable_if<
145 __and_<__not_<is_pointer<_Dp>>,
146 is_default_constructible<_Dp>>::value>;
147
148 using pointer = typename _Ptr<_Tp, _Dp>::type;
149
150 static_assert( !is_rvalue_reference<_Dp>::value,
151 "unique_ptr's deleter type must be a function object type"
152 " or an lvalue reference type" );
153
154 __uniq_ptr_impl() = default;
155 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
156
157 template<typename _Del>
158 __uniq_ptr_impl(pointer __p, _Del&& __d)
159 : _M_t(__p, std::forward<_Del>(__d)) { }
160
161 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
162 : _M_t(std::move(__u._M_t))
163 { __u._M_ptr() = nullptr; }
164
165 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
166 {
167 reset(__u.release());
168 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
169 return *this;
170 }
171
172 pointer& _M_ptr() { return std::get<0>(_M_t); }
173 pointer _M_ptr() const { return std::get<0>(_M_t); }
174 _Dp& _M_deleter() { return std::get<1>(_M_t); }
175 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
176
177 void reset(pointer __p) noexcept
178 {
179 const pointer __old_p = _M_ptr();
180 _M_ptr() = __p;
181 if (__old_p)
182 _M_deleter()(__old_p);
183 }
184
185 pointer release() noexcept
186 {
187 pointer __p = _M_ptr();
188 _M_ptr() = nullptr;
189 return __p;
190 }
191
192 void
193 swap(__uniq_ptr_impl& __rhs) noexcept
194 {
195 using std::swap;
196 swap(this->_M_ptr(), __rhs._M_ptr());
197 swap(this->_M_deleter(), __rhs._M_deleter());
198 }
199
200 private:
201 tuple<pointer, _Dp> _M_t;
202 };
203
204 // Defines move construction + assignment as either defaulted or deleted.
205 template <typename _Tp, typename _Dp,
206 bool = is_move_constructible<_Dp>::value,
207 bool = is_move_assignable<_Dp>::value>
208 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
209 {
210 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
211 __uniq_ptr_data(__uniq_ptr_data&&) = default;
212 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
213 };
214
215 template <typename _Tp, typename _Dp>
216 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
217 {
218 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
219 __uniq_ptr_data(__uniq_ptr_data&&) = default;
220 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
221 };
222
223 template <typename _Tp, typename _Dp>
224 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
225 {
226 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
227 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
228 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
229 };
230
231 template <typename _Tp, typename _Dp>
232 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
233 {
234 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
235 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
236 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
237 };
238 /// @endcond
239
240 /// 20.7.1.2 unique_ptr for single objects.
241 template <typename _Tp, typename _Dp = default_delete<_Tp>>
242 class unique_ptr
243 {
244 template <typename _Up>
245 using _DeleterConstraint =
246 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
247
248 __uniq_ptr_data<_Tp, _Dp> _M_t;
249
250 public:
251 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
252 using element_type = _Tp;
253 using deleter_type = _Dp;
254
255 private:
256 // helper template for detecting a safe conversion from another
257 // unique_ptr
258 template<typename _Up, typename _Ep>
259 using __safe_conversion_up = __and_<
260 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
261 __not_<is_array<_Up>>
262 >;
263
264 public:
265 // Constructors.
266
267 /// Default constructor, creates a unique_ptr that owns nothing.
268 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
269 constexpr unique_ptr() noexcept
270 : _M_t()
271 { }
272
273 /** Takes ownership of a pointer.
274 *
275 * @param __p A pointer to an object of @c element_type
276 *
277 * The deleter will be value-initialized.
278 */
279 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
280 explicit
281 unique_ptr(pointer __p) noexcept
282 : _M_t(__p)
283 { }
284
285 /** Takes ownership of a pointer.
286 *
287 * @param __p A pointer to an object of @c element_type
288 * @param __d A reference to a deleter.
289 *
290 * The deleter will be initialized with @p __d
291 */
292 template<typename _Del = deleter_type,
293 typename = _Require<is_copy_constructible<_Del>>>
294 unique_ptr(pointer __p, const deleter_type& __d) noexcept
295 : _M_t(__p, __d) { }
296
297 /** Takes ownership of a pointer.
298 *
299 * @param __p A pointer to an object of @c element_type
300 * @param __d An rvalue reference to a (non-reference) deleter.
301 *
302 * The deleter will be initialized with @p std::move(__d)
303 */
304 template<typename _Del = deleter_type,
305 typename = _Require<is_move_constructible<_Del>>>
306 unique_ptr(pointer __p,
307 __enable_if_t<!is_lvalue_reference<_Del>::value,
308 _Del&&> __d) noexcept
309 : _M_t(__p, std::move(__d))
310 { }
311
312 template<typename _Del = deleter_type,
313 typename _DelUnref = typename remove_reference<_Del>::type>
314 unique_ptr(pointer,
315 __enable_if_t<is_lvalue_reference<_Del>::value,
316 _DelUnref&&>) = delete;
317
318 /// Creates a unique_ptr that owns nothing.
319 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
320 constexpr unique_ptr(nullptr_t) noexcept
321 : _M_t()
322 { }
323
324 // Move constructors.
325
326 /// Move constructor.
327 unique_ptr(unique_ptr&&) = default;
328
329 /** @brief Converting constructor from another type
330 *
331 * Requires that the pointer owned by @p __u is convertible to the
332 * type of pointer owned by this object, @p __u does not own an array,
333 * and @p __u has a compatible deleter type.
334 */
335 template<typename _Up, typename _Ep, typename = _Require<
336 __safe_conversion_up<_Up, _Ep>,
337 typename conditional<is_reference<_Dp>::value,
338 is_same<_Ep, _Dp>,
339 is_convertible<_Ep, _Dp>>::type>>
340 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
341 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
342 { }
343
344#if _GLIBCXX_USE_DEPRECATED1
345#pragma GCC diagnostic push
346#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
347 /// Converting constructor from @c auto_ptr
348 template<typename _Up, typename = _Require<
349 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
350 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
351#pragma GCC diagnostic pop
352#endif
353
354 /// Destructor, invokes the deleter if the stored pointer is not null.
355 ~unique_ptr() noexcept
356 {
357 static_assert(__is_invocable<deleter_type&, pointer>::value,
358 "unique_ptr's deleter must be invocable with a pointer");
359 auto& __ptr = _M_t._M_ptr();
360 if (__ptr != nullptr)
361 get_deleter()(std::move(__ptr));
362 __ptr = pointer();
363 }
364
365 // Assignment.
366
367 /** @brief Move assignment operator.
368 *
369 * Invokes the deleter if this object owns a pointer.
370 */
371 unique_ptr& operator=(unique_ptr&&) = default;
372
373 /** @brief Assignment from another type.
374 *
375 * @param __u The object to transfer ownership from, which owns a
376 * convertible pointer to a non-array object.
377 *
378 * Invokes the deleter if this object owns a pointer.
379 */
380 template<typename _Up, typename _Ep>
381 typename enable_if< __and_<
382 __safe_conversion_up<_Up, _Ep>,
383 is_assignable<deleter_type&, _Ep&&>
384 >::value,
385 unique_ptr&>::type
386 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
387 {
388 reset(__u.release());
389 get_deleter() = std::forward<_Ep>(__u.get_deleter());
390 return *this;
391 }
392
393 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
394 unique_ptr&
395 operator=(nullptr_t) noexcept
396 {
397 reset();
398 return *this;
399 }
400
401 // Observers.
402
403 /// Dereference the stored pointer.
404 typename add_lvalue_reference<element_type>::type
405 operator*() const
406 {
407 __glibcxx_assert(get() != pointer());
408 return *get();
409 }
410
411 /// Return the stored pointer.
412 pointer
413 operator->() const noexcept
414 {
415 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
416 return get();
417 }
418
419 /// Return the stored pointer.
420 pointer
421 get() const noexcept
422 { return _M_t._M_ptr(); }
423
424 /// Return a reference to the stored deleter.
425 deleter_type&
426 get_deleter() noexcept
427 { return _M_t._M_deleter(); }
428
429 /// Return a reference to the stored deleter.
430 const deleter_type&
431 get_deleter() const noexcept
432 { return _M_t._M_deleter(); }
433
434 /// Return @c true if the stored pointer is not null.
435 explicit operator bool() const noexcept
436 { return get() == pointer() ? false : true; }
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)...)); }
4
Calling implicit destructor for 'WeakReference<SdrObject>'
5
Calling '~Reference'
12
Returning from '~Reference'
13
Returning from destructor for 'WeakReference<SdrObject>'
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 */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
)
6
Taking true branch
113 m_pBody->release();
7
Calling 'WeakConnection::release'
11
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
22
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/weakbase.h

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#ifndef INCLUDED_TOOLS_WEAKBASE_H
20#define INCLUDED_TOOLS_WEAKBASE_H
21
22#include <sal/types.h>
23#include <rtl/ref.hxx>
24#include <tools/toolsdllapi.h>
25
26/** the template classes in this header are helper to implement weak references
27 to implementation objects that are not refcounted.
28
29 THIS IS NOT THREADSAFE
30
31 Use this only to have 'safe' pointers to implementation objects that you
32 don't own but that you reference with a pointer.
33
34 Example:
35
36 class ImplClass : public tools::WeakBase< ImplClass >
37 {
38 ~ImplClass() { clearWeek(); } // not needed but safer, see method description
39 ...
40 };
41
42 class UserClass
43 {
44 tools::WeakReference< ImplClass > mxWeakRef;
45
46 UserClass( ImplClass* pObject ) : mxWeakRef( pObject ) {}
47
48 DoSomething()
49 {
50 if( mxWeakRef.is() )
51 mxWeakRef->DoSomethingMore();
52 }
53 };
54*/
55namespace tools
56{
57class WeakBase;
58
59/** private connection helper, do not use directly */
60struct WeakConnection
61{
62 sal_Int32 mnRefCount;
63 WeakBase* mpReference;
64
65 WeakConnection() : mnRefCount( 0 ), mpReference( nullptr ) {};
66 WeakConnection( WeakBase* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
67 void acquire() { mnRefCount++; }
68 void release() { mnRefCount--; if( mnRefCount == 0 ) delete this; }
8
Assuming field 'mnRefCount' is equal to 0
9
Taking true branch
10
Memory is released
69};
70
71/** template implementation to hold a weak reference to an instance of type reference_type */
72template <class reference_type>
73class SAL_WARN_UNUSED__attribute__((warn_unused)) WeakReference
74{
75public:
76 /** constructs an empty reference */
77 inline WeakReference();
78
79 /** constructs a reference with a pointer to a class derived from WeakBase */
80 inline WeakReference( reference_type* pReference );
81
82 /** constructs a reference from another reference */
83 inline WeakReference( const WeakReference< reference_type >& rWeakRef );
84
85 /** move a reference from another reference */
86 inline WeakReference( WeakReference< reference_type >&& rWeakRef );
87
88 /** returns true if the reference object is not null and still alive */
89 inline bool is() const;
90
91 /** returns true if the reference object is not null and still alive */
92 operator bool() const { return is(); }
93
94 /** returns the pointer to the reference object or null */
95 inline reference_type * get() const;
96
97 /** sets this reference to the given object or null */
98 inline void reset( reference_type* pReference );
99
100 /** resets this reference to null */
101 inline void reset();
102
103 /** returns the pointer to the reference object or null */
104 inline reference_type * operator->() const;
105
106 /** returns a ref to the reference object */
107 inline reference_type& operator*() const;
108
109 /** returns true if this instance references pReferenceObject */
110 inline bool operator== (const reference_type * pReferenceObject) const;
111
112 /** returns true if this instance and the given weakref reference the same object */
113 inline bool operator== (const WeakReference<reference_type> & handle) const;
114
115 /** only needed for using this class with stl containers */
116 inline bool operator!= (const WeakReference<reference_type> & handle) const;
117
118 /** only needed for using this class with stl containers */
119 inline bool operator< (const WeakReference<reference_type> & handle) const;
120
121 /** only needed for using this class with stl containers */
122 inline bool operator> (const WeakReference<reference_type> & handle) const;
123
124 /** the assignment operator */
125 inline WeakReference<reference_type>& operator= (const WeakReference<reference_type> & handle);
126
127 /** the move assignment operator */
128 inline WeakReference<reference_type>& operator= (WeakReference<reference_type> && handle);
129
130private:
131 rtl::Reference<WeakConnection> mpWeakConnection;
132};
133
134/** derive your implementation classes from this class if you want them to support weak references */
135class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) WeakBase
136{
137 template<typename T> friend class WeakReference;
138
139public:
140 WeakBase() {}
141 virtual ~WeakBase();
142 /** clears the reference pointer in all living weak references for this instance.
143 Further created weak references will also be invalid.
144 You should call this method in the d'tor of your derived classes for an early
145 invalidate of all living weak references while your object is already inside
146 it d'tor.
147 */
148 inline void clearWeak();
149
150private:
151 inline WeakConnection* getWeakConnection();
152 rtl::Reference<WeakConnection> mpWeakConnection;
153};
154
155}
156
157#endif
158
159/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/weakbase.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_TOOLS_WEAKBASE_HXX
21#define INCLUDED_TOOLS_WEAKBASE_HXX
22
23#include <tools/weakbase.h>
24
25/// see weakbase.h for documentation
26
27namespace tools
28{
29
30template< class reference_type >
31inline WeakReference< reference_type >::WeakReference()
32{
33 mpWeakConnection = new WeakConnection;
34}
35
36template< class reference_type >
37inline WeakReference< reference_type >::WeakReference( reference_type* pReference )
38{
39 reset( pReference );
17
Calling 'WeakReference::reset'
40}
41
42template< class reference_type >
43inline WeakReference< reference_type >::WeakReference( const WeakReference< reference_type >& rWeakRef )
44{
45 mpWeakConnection = rWeakRef.mpWeakConnection;
46}
47
48template< class reference_type >
49inline WeakReference< reference_type >::WeakReference( WeakReference< reference_type >&& rWeakRef )
50{
51 mpWeakConnection = std::move(rWeakRef.mpWeakConnection);
52 rWeakRef.reset();
53}
54
55template< class reference_type >
56inline bool WeakReference< reference_type >::is() const
57{
58 return mpWeakConnection->mpReference != nullptr;
59}
60
61template< class reference_type >
62inline reference_type * WeakReference< reference_type >::get() const
63{
64 auto pWeakBase = mpWeakConnection->mpReference;
65 if (!pWeakBase)
66 return nullptr;
67 assert(dynamic_cast<reference_type *>(pWeakBase))(static_cast <bool> (dynamic_cast<reference_type *>
(pWeakBase)) ? void (0) : __assert_fail ("dynamic_cast<reference_type *>(pWeakBase)"
, "/home/maarten/src/libreoffice/core/include/tools/weakbase.hxx"
, 67, __extension__ __PRETTY_FUNCTION__))
;
68 return static_cast<reference_type *>(pWeakBase);
69}
70
71template< class reference_type >
72inline void WeakReference< reference_type >::reset( reference_type* pReference )
73{
74 if( pReference
17.1
'pReference' is non-null
17.1
'pReference' is non-null
17.1
'pReference' is non-null
17.1
'pReference' is non-null
17.1
'pReference' is non-null
)
18
Taking true branch
75 mpWeakConnection = pReference->getWeakConnection();
19
Calling 'WeakBase::getWeakConnection'
76 else
77 reset();
78}
79
80template< class reference_type >
81inline void WeakReference< reference_type >::reset()
82{
83 mpWeakConnection = new WeakConnection;
84}
85
86template< class reference_type >
87inline reference_type * WeakReference< reference_type >::operator->() const
88{
89 return get();
90}
91
92template< class reference_type >
93inline reference_type& WeakReference< reference_type >::operator*() const
94{
95 return *get();
96}
97
98template< class reference_type >
99inline bool WeakReference< reference_type >::operator==(const reference_type * pReferenceObject) const
100{
101 return mpWeakConnection->mpReference == pReferenceObject;
102}
103
104template< class reference_type >
105inline bool WeakReference< reference_type >::operator==(const WeakReference<reference_type> & handle) const
106{
107 return mpWeakConnection == handle.mpWeakConnection;
108}
109
110template< class reference_type >
111inline bool WeakReference< reference_type >::operator!=(const WeakReference<reference_type> & handle) const
112{
113 return mpWeakConnection != handle.mpWeakConnection;
114}
115
116template< class reference_type >
117inline bool WeakReference< reference_type >::operator<(const WeakReference<reference_type> & handle) const
118{
119 return mpWeakConnection->mpReference < handle.mpWeakConnection->mpReference;
120}
121
122template< class reference_type >
123inline bool WeakReference< reference_type >::operator>(const WeakReference<reference_type> & handle) const
124{
125 return mpWeakConnection->mpReference > handle.mpWeakConnection->mpReference;
126}
127
128template< class reference_type >
129inline WeakReference<reference_type>& WeakReference<reference_type>::operator= (
130 const WeakReference<reference_type>& rReference)
131{
132 if (&rReference != this)
133 mpWeakConnection = rReference.mpWeakConnection;
134 return *this;
135}
136
137template< class reference_type >
138inline WeakReference<reference_type>& WeakReference<reference_type>::operator= (
139 WeakReference<reference_type>&& rReference)
140{
141 mpWeakConnection = std::move(rReference.mpWeakConnection);
142 return *this;
143}
144
145inline void WeakBase::clearWeak()
146{
147 if( mpWeakConnection.is() )
148 mpWeakConnection->mpReference = nullptr;
149}
150
151inline WeakConnection* WeakBase::getWeakConnection()
152{
153 if( !mpWeakConnection.is() )
20
Taking false branch
154 mpWeakConnection = new WeakConnection( this );
155 return mpWeakConnection.get();
21
Calling 'Reference::get'
156}
157
158}
159
160#endif
161
162/* vim:set shiftwidth=4 softtabstop=4 expandtab: */