/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice :
*
* Licensed to the Apache Software Foundation ( ASF ) under one or more
* contributor license agreements . See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership . The ASF licenses this file to you under the Apache
* License , Version 2 . 0 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.apache.org/licenses/LICENSE-2.0 .
*/
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
//#define TIMELOG for measuring performance
#include <bparr.hxx>
namespace /* private */
{
const sal_Int32 NUM_ENTRIES = 10 ;
class BigPtrEntryMock : public BigPtrEntry
{
public :
explicit BigPtrEntryMock(sal_Int32 count) : count_(count)
{
}
sal_Int32 getCount() const
{
return count_;
}
sal_Int32 Position() const
{
return GetPos();
}
private :
sal_Int32 count_;
};
void fillBigPtrArray(BigPtrArray& bparr, sal_Int32 numEntries)
{
for (sal_Int32 i = 0 ; i < numEntries; i++)
bparr.Insert(new BigPtrEntryMock(i), bparr.Count());
}
bool checkElementPositions(const BigPtrArray& bparr)
{
for (sal_Int32 i = 0 ; i < bparr.Count(); i++)
{
if (static_cast <BigPtrEntryMock*>(bparr[i])->Position() != i)
return false ;
}
return true ;
}
void releaseBigPtrArrayContent(BigPtrArray const & bparr)
{
for (sal_Int32 i = 0 ; i < bparr.Count(); i++)
delete bparr[i];
}
}
class BigPtrArrayUnittest : public CppUnit::TestFixture
{
public :
BigPtrArrayUnittest()
{
}
/** Test constructor/destructor
The size of the BigPtrArray
aka the ' Count ' should be 0
initially .
*/
void test_ctor()
{
BigPtrArray bparr;
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"BigPtrArray ctor failed" ,
static_cast <sal_Int32>(0 ), bparr.Count()
);
}
void test_insert_entries_at_front()
{
BigPtrArray bparr;
for (sal_Int32 i = 0 ; i < NUM_ENTRIES; i++)
{
sal_Int32 oldCount = bparr.Count();
bparr.Insert(new BigPtrEntryMock(i), 0 );
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_entries_at_front failed" ,
oldCount + 1 , bparr.Count()
);
}
for (sal_Int32 i = 0 , j = NUM_ENTRIES - 1 ; i < NUM_ENTRIES; i++, j--)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_entries_at_front failed" ,
j, static_cast <BigPtrEntryMock*>(bparr[i])->getCount()
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_entries_at_front failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
void test_insert_entries_in_the_middle()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
sal_Int32 oldCount = bparr.Count();
bparr.Insert(new BigPtrEntryMock(NUM_ENTRIES), bparr.Count() / 2 );
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_entries_in_the_middle failed" ,
oldCount + 1 , bparr.Count()
);
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_entries_in_the_middle failed" ,
NUM_ENTRIES, static_cast <BigPtrEntryMock*>(bparr[bparr.Count() / 2 ])->getCount()
);
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_entries_in_the_middle failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
void test_insert_at_already_used_index()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
const sal_Int32 oldCount = bparr.Count();
// insert 5 elements
for (sal_Int32 i = 0 , j = 30 ; i < 5 ; i++, j++)
bparr.Insert(new BigPtrEntryMock(j), i);
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_at_already_used_index failed" ,
oldCount + 5 , bparr.Count()
);
// now, first 5 elements have counts: 30,31,..34
// next 10 elements have counts: 0,1,..9
for (sal_Int32 i = 0 , j = 30 ; i < bparr.Count(); i++, j++)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_at_already_used_index failed" ,
(i < 5 ? j : i - 5 ), static_cast <BigPtrEntryMock*>(bparr[i])->getCount()
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_at_already_used_index failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
void test_insert_at_end()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
sal_Int32 oldCount = bparr.Count();
bparr.Insert(new BigPtrEntryMock(NUM_ENTRIES), bparr.Count());
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_at_end failed" ,
oldCount + 1 , bparr.Count()
);
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_insert_at_end failed" ,
NUM_ENTRIES, static_cast <BigPtrEntryMock*>(bparr[bparr.Count()-1 ])->getCount()
);
CPPUNIT_ASSERT_MESSAGE
(
"test_insert_at_end failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
void test_remove_at_front()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
for (sal_Int32 i = 0 ; i < NUM_ENTRIES; i++)
{
sal_Int32 oldCount = bparr.Count();
auto p = bparr[0 ];
bparr.Remove(0 ); // remove item from container
delete p; // release content
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_remove_at_front failed (wrong count)" ,
oldCount - 1 , bparr.Count()
);
for (sal_Int32 j = 0 , k = i + 1 ; j < bparr.Count(); j++, k++)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_remove_at_front failed" ,
k, static_cast <BigPtrEntryMock*>(bparr[j])->getCount()
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_front failed" ,
checkElementPositions(bparr)
);
}
}
void test_remove_at_back()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
for (int i = NUM_ENTRIES - 1 ; i >= 0 ; i--)
{
sal_Int32 oldCount = bparr.Count();
auto p = bparr[i];
bparr.Remove(i);
delete p;
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_remove_at_back failed (wrong count)" ,
(oldCount - 1 ), bparr.Count()
);
for (sal_Int32 j = 0 ; j < bparr.Count(); j++)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_remove_at_back failed" ,
j, static_cast <BigPtrEntryMock*>(bparr[j])->getCount()
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_at_back failed" ,
checkElementPositions(bparr)
);
}
}
void test_remove_in_the_middle()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
while (bparr.Count())
{
sal_Int32 oldCount = bparr.Count();
sal_Int32 oldElement = static_cast <BigPtrEntryMock*>(bparr[bparr.Count() / 2 ])->getCount();
auto p = bparr[bparr.Count() / 2 ];
bparr.Remove(bparr.Count() / 2 );
delete p;
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_remove_in_the_middle failed (wrong count)" ,
oldCount - 1 , bparr.Count()
);
for (sal_Int32 i = 0 ; i < bparr.Count(); i++)
{
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_in_the_middle failed" ,
static_cast <BigPtrEntryMock*>(bparr[i])->getCount() != oldElement
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_in_the_middle failed" ,
checkElementPositions(bparr)
);
}
}
void test_remove_multiple_elements_at_once()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
while (bparr.Count())
{
sal_Int32 nRemove = std::min<sal_Int32>(bparr.Count(), 3 );
sal_Int32 oldCount = bparr.Count();
std::vector<BigPtrEntry*> vToDelete;
for (sal_Int32 i = 0 ; i < nRemove; i++)
vToDelete.push_back(bparr[i]);
bparr.Remove(0 , nRemove);
for (auto p : vToDelete)
delete p;
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_remove_multiple_elements_at_once failed" ,
oldCount - nRemove, bparr.Count()
);
CPPUNIT_ASSERT_MESSAGE
(
"test_remove_multiple_elements_at_once failed" ,
checkElementPositions(bparr)
);
}
}
void test_remove_all_elements_at_once()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
std::vector<BigPtrEntry*> vToDelete;
for (sal_Int32 i = 0 ; i < bparr.Count(); i++)
vToDelete.push_back(bparr[i]);
bparr.Remove(0 , bparr.Count());
for (auto p : vToDelete)
delete p;
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_remove_all_elements_at_once failed" ,
static_cast <sal_Int32>(0 ), bparr.Count()
);
}
void test_move_elements_from_lower_to_higher_pos()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
for (sal_Int32 i = 0 ; i < NUM_ENTRIES - 1 ; i++)
{
bparr.Move(i, i + 2 );
}
for (sal_Int32 i = 0 ; i < (NUM_ENTRIES - 1 ); i++)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_move_elements_from_lower_to_higher_pos failed" ,
(i + 1 ), static_cast <BigPtrEntryMock*>(bparr[i])->getCount()
);
}
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_move_elements_from_lower_to_higher_pos failed" ,
static_cast <sal_Int32>(0 ), static_cast <BigPtrEntryMock*>(bparr[NUM_ENTRIES -1 ])->getCount()
);
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_lower_to_higher_pos failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
void test_move_elements_from_higher_to_lower_pos()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
for (int i = NUM_ENTRIES - 1 ; i >= 1 ; i--)
{
bparr.Move(i, i - 1 );
}
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_move_elements_from_higher_to_lower_pos failed" ,
(NUM_ENTRIES - 1 ), static_cast <BigPtrEntryMock*>(bparr[0 ])->getCount()
);
for (sal_Int32 i = 1 ; i < NUM_ENTRIES; i++)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_move_elements_from_higher_to_lower_pos failed" ,
(i - 1 ), static_cast <BigPtrEntryMock*>(bparr[i])->getCount()
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_move_elements_from_higher_to_lower_pos failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
void test_move_to_same_position()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
for (sal_Int32 i = 0 ; i < NUM_ENTRIES; i++)
{
bparr.Move(i, i);
}
for (sal_Int32 i = 0 ; i < NUM_ENTRIES; i++)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_move_to_same_position failed" ,
i, static_cast <BigPtrEntryMock*>(bparr[i])->getCount()
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_move_to_same_position failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
void test_replace_elements()
{
BigPtrArray bparr;
fillBigPtrArray(bparr, NUM_ENTRIES);
for (sal_Int32 i = 0 , j = NUM_ENTRIES - 1 ; i < NUM_ENTRIES; i++, j--)
{
auto p = bparr[i];
bparr.Replace(i, new BigPtrEntryMock(j));
delete p;
}
for (sal_Int32 i = 0 ; i < NUM_ENTRIES; i++)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"test_replace_elements failed" ,
(NUM_ENTRIES - i - 1 ), static_cast <BigPtrEntryMock*>(bparr[i])->getCount()
);
}
CPPUNIT_ASSERT_MESSAGE
(
"test_replace_elements failed" ,
checkElementPositions(bparr)
);
releaseBigPtrArrayContent(bparr);
}
CPPUNIT_TEST_SUITE(BigPtrArrayUnittest);
CPPUNIT_TEST(test_ctor);
CPPUNIT_TEST(test_insert_entries_at_front);
CPPUNIT_TEST(test_insert_entries_in_the_middle);
CPPUNIT_TEST(test_insert_at_already_used_index);
CPPUNIT_TEST(test_insert_at_end);
CPPUNIT_TEST(test_remove_at_front);
CPPUNIT_TEST(test_remove_at_back);
CPPUNIT_TEST(test_remove_in_the_middle);
CPPUNIT_TEST(test_remove_multiple_elements_at_once);
CPPUNIT_TEST(test_remove_all_elements_at_once);
CPPUNIT_TEST(test_move_elements_from_lower_to_higher_pos);
CPPUNIT_TEST(test_move_elements_from_higher_to_lower_pos);
CPPUNIT_TEST(test_move_to_same_position);
CPPUNIT_TEST(test_replace_elements);
CPPUNIT_TEST_SUITE_END();
};
#if defined TIMELOG
const char * const START = "START: " ;
const char * const END = "END: " ;
class PerformanceTracer
{
public :
public :
explicit PerformanceTracer(const string& methodName) :
startString_(START),
endString_(END)
{
startString_ += methodName;
endString_ += methodName;
}
~PerformanceTracer()
{
}
private :
string startString_;
string endString_;
};
class BigPtrArrayPerformanceTest : public CppUnit::TestFixture
{
public :
BigPtrArrayPerformanceTest()
{
}
void test_insert_at_end_1000()
{ test_insert_at_end("1000" ); }
void test_insert_at_end_10000()
{ test_insert_at_end("10000" ); }
void test_insert_at_end_100000()
{ test_insert_at_end("100000" ); }
void test_insert_at_end_1000000()
{ test_insert_at_end("1000000" ); }
void test_insert_at_front_1000()
{ test_insert_at_front("1000" ); }
void test_insert_at_front_10000()
{ test_insert_at_front("10000" ); }
void test_insert_at_front_100000()
{ test_insert_at_front("100000" ); }
void test_insert_at_front_1000000()
{ test_insert_at_front("1000000" ); }
CPPUNIT_TEST_SUITE(BigPtrArrayPerformanceTest);
CPPUNIT_TEST(test_insert_at_end_1000);
CPPUNIT_TEST(test_insert_at_end_10000);
CPPUNIT_TEST(test_insert_at_end_100000);
CPPUNIT_TEST(test_insert_at_end_1000000);
CPPUNIT_TEST(test_insert_at_front_1000);
CPPUNIT_TEST(test_insert_at_front_10000);
CPPUNIT_TEST(test_insert_at_front_100000);
CPPUNIT_TEST(test_insert_at_front_1000000);
CPPUNIT_TEST_SUITE_END();
private :
void test_insert_at_end(const char * numElements)
{
OStringBuffer buff("test_insert_at_end " );
buff.append(numElements);
int n = atoi(numElements);
PerformanceTracer tracer(buff.getStr());
BigPtrArray bparr;
for (int i = 0 ; i < n; i++)
bparr.Insert(new BigPtrEntryMock(i), bparr.Count());
releaseBigPtrArrayContent(bparr);
}
void test_insert_at_front(const char * numElements)
{
OStringBuffer buff("test_insert_at_front " );
buff.append(numElements);
int n = atoi(numElements);
PerformanceTracer tracer(buff.getStr());
BigPtrArray bparr;
for (int i = 0 ; i < n; i++)
bparr.Insert(new BigPtrEntryMock(i), 0 );
releaseBigPtrArrayContent(bparr);
}
};
#endif
// register test suites
CPPUNIT_TEST_SUITE_REGISTRATION(BigPtrArrayUnittest);
#ifdef TIMELOG
CPPUNIT_TEST_SUITE_REGISTRATION(BigPtrArrayPerformanceTest);
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=98 H=61 G=81
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland