summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorNoel Grandin <noelgrandin@gmail.com>2021-07-10 10:19:28 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-07-15 14:41:13 +0200
commit5d0a231b29dfd4d587c7a4d1bbda6a511f94ec77 (patch)
treeebc1d470fd891fe0f9e68a002055c4d3a8dd4884 /svx
parentdf9ca514d4e9ea87bbf0a96d99181ed8965cd45a (diff)
WhichRangesContainer, reduce malloc in SfxItemSet
SfxItemSet shows up in perf profiles frequently, and the hottest part is the malloc of the two arrays we need. But most of the time, one of those arrays is a compile-time constant. So this change introduces (*) WhichRangesContainer, which manages whether the SfxItemSet owns the array it points at or not. (*) a static const member in svl::Items (idea from mkaganski) to store the data. Change-Id: Icb8cdbc4d54fd76739565c575e16a744515e5355 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118703 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'svx')
-rw-r--r--svx/qa/unit/removewhichrange.cxx107
-rw-r--r--svx/source/dialog/hdft.cxx8
-rw-r--r--svx/source/dialog/srchdlg.cxx25
-rw-r--r--svx/source/svdraw/svdedxv.cxx61
-rw-r--r--svx/source/svdraw/svdetc.cxx30
5 files changed, 92 insertions, 139 deletions
diff --git a/svx/qa/unit/removewhichrange.cxx b/svx/qa/unit/removewhichrange.cxx
index fc2b0a038931..1c45e2d7874e 100644
--- a/svx/qa/unit/removewhichrange.cxx
+++ b/svx/qa/unit/removewhichrange.cxx
@@ -16,6 +16,7 @@
#include <sal/types.h>
#include <svx/svdetc.hxx>
+#include <svl/itemset.hxx>
namespace
{
@@ -28,98 +29,88 @@ class TestRemoveWhichRange : public CppUnit::TestFixture
void testRemoveWhichRange()
{
{
- sal_uInt16 const in[] = { 0 };
+ WhichRangesContainer in;
auto const out = RemoveWhichRange(in, 10, 20);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[0]);
+ CPPUNIT_ASSERT(out.empty());
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 0, 20);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[2]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[0].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 10, 20);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[2]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[0].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 15, 20);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(14), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[2]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[3]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[4]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(14), out[0].second);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[1].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[1].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 30, 40);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[2]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[0].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 30, 50);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[2]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[0].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 30, 35);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(36), out[2]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[3]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[4]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[0].second);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(36), out[1].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[1].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 15, 35);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(14), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(36), out[2]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[3]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[4]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(14), out[0].second);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(36), out[1].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[1].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 12, 15);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(11), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(16), out[2]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[3]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[4]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[5]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[6]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(11), out[0].second);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(16), out[1].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[1].second);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), out[2].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[2].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 30, 40, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 30, 40>::value);
auto const out = RemoveWhichRange(in, 0, 100);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[0]);
+ CPPUNIT_ASSERT(out.empty());
}
{
- sal_uInt16 const in[] = { 10, 20, 40, 50, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 40, 50>::value);
auto const out = RemoveWhichRange(in, 25, 35);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[2]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(50), out[3]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[4]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[0].second);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[1].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(50), out[1].second);
}
{
- sal_uInt16 const in[] = { 10, 20, 40, 50, 0 };
+ WhichRangesContainer in(svl::Items<10, 20, 40, 50>::value);
auto const out = RemoveWhichRange(in, 50, 100);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[1]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[2]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(49), out[3]);
- CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), out[4]);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(10), out[0].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(20), out[0].second);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(40), out[1].first);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(49), out[1].second);
}
}
};
diff --git a/svx/source/dialog/hdft.cxx b/svx/source/dialog/hdft.cxx
index 0cd7e9102abd..0fa7b35a4a3f 100644
--- a/svx/source/dialog/hdft.cxx
+++ b/svx/source/dialog/hdft.cxx
@@ -54,8 +54,7 @@ const tools::Long MINBODY = 56; // 1mm in twips rounded
const tools::Long DEF_DIST_WRITER = 500; // 5mm (Writer)
const tools::Long DEF_DIST_CALC = 250; // 2.5mm (Calc)
-const sal_uInt16 SvxHFPage::pRanges[] =
-{
+const WhichRangesContainer SvxHFPage::pRanges(svl::Items<
SID_ATTR_BRUSH, SID_ATTR_BRUSH,
// Support DrawingLayer FillStyles (no real call to below GetRanges()
@@ -74,9 +73,8 @@ const sal_uInt16 SvxHFPage::pRanges[] =
SID_ATTR_PAGE_DYNAMIC, SID_ATTR_PAGE_DYNAMIC,
SID_ATTR_PAGE_SHARED, SID_ATTR_PAGE_SHARED,
SID_ATTR_PAGE_SHARED_FIRST, SID_ATTR_PAGE_SHARED_FIRST,
- SID_ATTR_HDFT_DYNAMIC_SPACING, SID_ATTR_HDFT_DYNAMIC_SPACING,
- 0
-};
+ SID_ATTR_HDFT_DYNAMIC_SPACING, SID_ATTR_HDFT_DYNAMIC_SPACING
+>::value);
namespace svx {
diff --git a/svx/source/dialog/srchdlg.cxx b/svx/source/dialog/srchdlg.cxx
index 76ccbd333599..28fa49e0ba8a 100644
--- a/svx/source/dialog/srchdlg.cxx
+++ b/svx/source/dialog/srchdlg.cxx
@@ -127,7 +127,7 @@ struct SearchDlg_Impl
{
bool bSaveToModule : 1,
bFocusOnSearch : 1;
- std::unique_ptr<sal_uInt16[]> pRanges;
+ WhichRangesContainer pRanges;
Timer aSelectionTimer;
uno::Reference< frame::XDispatch > xCommand1Dispatch;
@@ -1053,19 +1053,8 @@ void SvxSearchDialog::InitAttrList_Impl( const SfxItemSet* pSSet,
if ( !pSSet && !pRSet )
return;
- if ( !pImpl->pRanges && pSSet )
- {
- const sal_uInt16* pPtr = pSSet->GetRanges();
- const sal_uInt16* pTmp = pPtr;
-
- while( *pPtr )
- {
- pPtr += 2;
- }
- sal_sSize nCnt = pPtr - pTmp + 1;
- pImpl->pRanges.reset( new sal_uInt16[nCnt] );
- memcpy( pImpl->pRanges.get(), pTmp, sizeof(sal_uInt16) * nCnt );
- }
+ if ( pImpl->pRanges.empty() && pSSet )
+ pImpl->pRanges = pSSet->GetRanges();
bool bSetOptimalLayoutSize = false;
@@ -1945,11 +1934,11 @@ IMPL_LINK_NOARG(SvxSearchDialog, FormatHdl_Impl, weld::Button&, void)
DBG_ASSERT( pSh, "no DocShell" );
- if ( !pSh || !pImpl->pRanges )
+ if ( !pSh || pImpl->pRanges.empty() )
return;
SfxItemPool& rPool = pSh->GetPool();
- SfxItemSet aSet(rPool, pImpl->pRanges.get());
+ SfxItemSet aSet(rPool, pImpl->pRanges);
aSet.MergeRange(SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL);
@@ -2066,11 +2055,11 @@ IMPL_LINK_NOARG(SvxSearchDialog, NoFormatHdl_Impl, weld::Button&, void)
IMPL_LINK_NOARG(SvxSearchDialog, AttributeHdl_Impl, weld::Button&, void)
{
- if ( !pSearchList || !pImpl->pRanges )
+ if ( !pSearchList || pImpl->pRanges.empty() )
return;
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
- ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSvxSearchAttributeDialog(m_xDialog.get(), *pSearchList, pImpl->pRanges.get()));
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSvxSearchAttributeDialog(m_xDialog.get(), *pSearchList, pImpl->pRanges));
executeSubDialog(pDlg.get());
PaintAttrText_Impl();
}
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index be08b46b1f2e..5f4c4529bef0 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -2218,10 +2218,9 @@ bool SdrObjEditView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
// Otherwise split Set, if necessary.
// Now we build an ItemSet aSet that doesn't contain EE_Items from
// *pSet (otherwise it would be a copy).
- std::unique_ptr<sal_uInt16[]> pNewWhichTable
+ WhichRangesContainer pNewWhichTable
= RemoveWhichRange(pSet->GetRanges(), EE_ITEMS_START, EE_ITEMS_END);
- SfxItemSet aSet(mpModel->GetItemPool(), pNewWhichTable.get());
- pNewWhichTable.reset();
+ SfxItemSet aSet(mpModel->GetItemPool(), std::move(pNewWhichTable));
SfxWhichIter aIter(aSet);
sal_uInt16 nWhich = aIter.FirstWhich();
while (nWhich != 0)
@@ -2626,35 +2625,18 @@ bool SdrObjEditView::SupportsFormatPaintbrush(SdrInventor nObjectInventor,
}
}
-static const sal_uInt16* GetFormatRangeImpl(bool bTextOnly)
-{
- static const sal_uInt16 gFull[] = { XATTR_LINE_FIRST,
- XATTR_LINE_LAST,
- XATTR_FILL_FIRST,
- XATTRSET_FILL,
- SDRATTR_SHADOW_FIRST,
- SDRATTR_SHADOW_LAST,
- SDRATTR_MISC_FIRST,
- SDRATTR_MISC_LAST, // table cell formats
- SDRATTR_GRAF_FIRST,
- SDRATTR_GRAF_LAST,
- SDRATTR_TABLE_FIRST,
- SDRATTR_TABLE_LAST,
- EE_PARA_START,
- EE_PARA_END,
- EE_CHAR_START,
- EE_CHAR_END,
- 0,
- 0 };
-
- static const sal_uInt16 gTextOnly[] = { SDRATTR_MISC_FIRST,
- SDRATTR_MISC_LAST,
- EE_PARA_START,
- EE_PARA_END,
- EE_CHAR_START,
- EE_CHAR_END,
- 0,
- 0 };
+static WhichRangesContainer GetFormatRangeImpl(bool bTextOnly)
+{
+ static const WhichRangesContainer gFull(
+ svl::Items<XATTR_LINE_FIRST, XATTR_LINE_LAST, XATTR_FILL_FIRST, XATTRSET_FILL,
+ SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST, SDRATTR_MISC_FIRST,
+ SDRATTR_MISC_LAST, // table cell formats
+ SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST, SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
+ EE_PARA_START, EE_PARA_END, EE_CHAR_START, EE_CHAR_END>::value);
+
+ static const WhichRangesContainer gTextOnly(
+ svl::Items<SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, EE_PARA_START, EE_PARA_END, EE_CHAR_START,
+ EE_CHAR_END>::value);
return bTextOnly ? gTextOnly : gFull;
}
@@ -2692,16 +2674,16 @@ void SdrObjEditView::TakeFormatPaintBrush(std::shared_ptr<SfxItemSet>& rFormatSe
}
}
-static SfxItemSet CreatePaintSet(const sal_uInt16* pRanges, SfxItemPool& rPool,
+static SfxItemSet CreatePaintSet(const WhichRangesContainer& pRanges, SfxItemPool& rPool,
const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet,
bool bNoCharacterFormats, bool bNoParagraphFormats)
{
SfxItemSet aPaintSet(rPool, pRanges);
- while (*pRanges)
+ for (const auto& pRange : pRanges)
{
- sal_uInt16 nWhich = *pRanges++;
- const sal_uInt16 nLastWhich = *pRanges++;
+ sal_uInt16 nWhich = pRange.first;
+ const sal_uInt16 nLastWhich = pRange.second;
if (bNoCharacterFormats && (nWhich == EE_CHAR_START))
continue;
@@ -2779,17 +2761,16 @@ void SdrObjEditView::ApplyFormatPaintBrush(SfxItemSet& rFormatSet, bool bNoChara
// All formatting items (see ranges above) that are unequal in selected shape and
// the format paintbrush are hard set on the selected shape.
- const sal_uInt16* pRanges = rFormatSet.GetRanges();
+ const WhichRangesContainer& pRanges = rFormatSet.GetRanges();
bool bTextOnly = true;
- while (*pRanges)
+ for (const auto& pRange : pRanges)
{
- if ((*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START))
+ if ((pRange.first != EE_PARA_START) && (pRange.first != EE_CHAR_START))
{
bTextOnly = false;
break;
}
- pRanges += 2;
}
if (!bTextOnly)
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
index 9967376bf078..aa8ef44ee845 100644
--- a/svx/source/svdraw/svdetc.cxx
+++ b/svx/source/svdraw/svdetc.cxx
@@ -367,39 +367,33 @@ bool SearchOutlinerItems(const SfxItemSet& rSet, bool bInklDefaults, bool* pbOnl
return bHas;
}
-std::unique_ptr<sal_uInt16[]> RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
+WhichRangesContainer RemoveWhichRange(const WhichRangesContainer& pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
{
// Six possible cases (per range):
// [Beg..End] [nRangeBeg, nRangeEnd], to delete
// [b..e] [b..e] [b..e] Cases 1,3,2: doesn't matter, delete, doesn't matter + Ranges
// [b........e] [b........e] Cases 4,5 : shrink range | in
// [b......................e] Case 6 : splitting + pOldWhichTable
- std::vector<sal_uInt16> buf;
- for (auto p = pOldWhichTable; *p != 0; p += 2) {
- auto const begin = p[0];
- auto const end = p[1];
+ std::vector<WhichPair> buf;
+ for (const auto & rPair : pOldWhichTable) {
+ auto const begin = rPair.first;
+ auto const end = rPair.second;
if (end < nRangeBeg || begin > nRangeEnd) { // cases 1, 2
- buf.push_back(begin);
- buf.push_back(end);
+ buf.push_back({begin, end});
} else if (begin >= nRangeBeg && end <= nRangeEnd) { // case 3
// drop
} else if (end <= nRangeEnd) { // case 4
- buf.push_back(begin);
- buf.push_back(nRangeBeg - 1);
+ buf.push_back({begin, nRangeBeg - 1});
} else if (begin >= nRangeBeg) { // case 5
- buf.push_back(nRangeEnd + 1);
- buf.push_back(end);
+ buf.push_back({nRangeEnd + 1, end});
} else { // case 6
- buf.push_back(begin);
- buf.push_back(nRangeBeg - 1);
- buf.push_back(nRangeEnd + 1);
- buf.push_back(end);
+ buf.push_back({begin, nRangeBeg - 1});
+ buf.push_back({nRangeEnd + 1, end});
}
}
- std::unique_ptr<sal_uInt16[]> pNewWhichTable(new sal_uInt16[buf.size() + 1]);
+ std::unique_ptr<WhichPair[]> pNewWhichTable(new WhichPair[buf.size()]);
std::copy(buf.begin(), buf.end(), pNewWhichTable.get());
- pNewWhichTable[buf.size()] = 0;
- return pNewWhichTable;
+ return WhichRangesContainer(std::move(pNewWhichTable), buf.size());
}