Arrays - Predicate-based indexOf/contains methods

This commit is contained in:
Emmanuel BENOîT 2018-05-09 14:12:27 +02:00
parent d823721fb2
commit ae2ad1f8b4
7 changed files with 385 additions and 0 deletions

View file

@ -147,9 +147,14 @@ class T_Array final
T& last( ) noexcept;
T const& last( ) const noexcept;
// Find items (requires comparison operator)
int32_t indexOf( T const& item ) const noexcept;
bool contains( T const& item ) const noexcept;
// Find items based on a predicate
int32_t indexOf( std::function< bool( T const& ) > pred ) const noexcept;
bool contains( std::function< bool( T const& ) > pred ) const noexcept;
// ---------------------------------------------------------------------
uint32_t add( T const& item ) noexcept;
@ -286,9 +291,14 @@ class T_StaticArray final
Type& last( ) noexcept;
Type const& last( ) const noexcept;
// Find items (requires comparison operator)
int32_t indexOf( Type const& item ) const noexcept;
bool contains( Type const& item ) const noexcept;
// Find items based on a predicate
int32_t indexOf( std::function< bool( Type const& ) > pred ) const noexcept;
bool contains( std::function< bool( Type const& ) > pred ) const noexcept;
// ---------------------------------------------------------------------
uint32_t add( Type&& item ) noexcept;
@ -488,9 +498,14 @@ template<
T& last( ) noexcept;
T const& last( ) const noexcept;
// Find items (requires comparison operator)
int32_t indexOf( T const& item ) const noexcept;
bool contains( T const& item ) const noexcept;
// Find items based on a predicate
int32_t indexOf( std::function< bool( T const& ) > pred ) const noexcept;
bool contains( std::function< bool( T const& ) > pred ) const noexcept;
// ---------------------------------------------------------------------
uint32_t add( T const& item ) noexcept;

View file

@ -281,6 +281,30 @@ inline bool T_Array< T >::contains(
return indexOf( item ) != -1;
}
template< typename T >
inline int32_t T_Array< T >::indexOf(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( data_[ i ] ) ) {
return i;
}
}
return -1;
}
template< typename T >
inline bool T_Array< T >::contains(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( data_[ i ] ) ) {
return true;
}
}
return false;
}
/*----------------------------------------------------------------------------*/
template< typename T >
@ -1233,6 +1257,30 @@ inline bool T_StaticArray< T , S >::contains(
return indexOf( item ) != -1;
}
template< typename T , uint32_t S >
inline int32_t T_StaticArray< T , S >::indexOf(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( (*this)[ i ] ) ) {
return i;
}
}
return -1;
}
template< typename T , uint32_t S >
inline bool T_StaticArray< T , S >::contains(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( (*this)[ i ] ) ) {
return true;
}
}
return false;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
@ -1883,6 +1931,24 @@ inline bool T_AutoArray< T , S , G >::contains(
return indexOf( item ) != -1;
}
template< typename T , uint32_t S , uint32_t G >
inline int32_t T_AutoArray< T , S , G >::indexOf(
std::function< bool( T const& ) > pred ) const noexcept
{
return isStatic( )
? static_( ).indexOf( std::move( pred ) )
: dynamic_( ).indexOf( std::move( pred ) );
}
template< typename T , uint32_t S , uint32_t G >
inline bool T_AutoArray< T , S , G >::contains(
std::function< bool( T const& ) > pred ) const noexcept
{
return isStatic( )
? static_( ).contains( std::move( pred ) )
: dynamic_( ).contains( std::move( pred ) );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >

View file

@ -37,6 +37,11 @@ class ArraysAutoTest : public CppUnit::TestFixture
CPPUNIT_TEST( testContains );
CPPUNIT_TEST( testContainsMissing );
CPPUNIT_TEST( testIndexOfPred );
CPPUNIT_TEST( testIndexOfPredMissing );
CPPUNIT_TEST( testContainsPred );
CPPUNIT_TEST( testContainsPredMissing );
CPPUNIT_TEST( testSort );
CPPUNIT_TEST( testAddAllSS2S );
@ -94,6 +99,11 @@ class ArraysAutoTest : public CppUnit::TestFixture
void testContains( );
void testContainsMissing( );
void testIndexOfPred( );
void testIndexOfPredMissing( );
void testContainsPred( );
void testContainsPredMissing( );
void testSort( );
void testAddAllSS2S( );
@ -592,6 +602,98 @@ void ArraysAutoTest::testContainsMissing( )
/*----------------------------------------------------------------------------*/
void ArraysAutoTest::testIndexOfPred( )
{
{
T_Test_ test;
for ( auto i = 0u ; i < StaticSize ; i ++ ) {
test.add( i * 2 + 1 );
}
for ( auto i = 0u ; i < StaticSize ; i ++ ) {
CPPUNIT_ASSERT_EQUAL( int32_t( i ) ,
test.indexOf( [=]( auto v ) {
return v == i * 2 + 1;
} ) );
}
}
{
T_Test_ test;
for ( auto i = 0u ; i < DynamicGrowth ; i ++ ) {
test.add( i * 2 + 1 );
}
for ( auto i = 0u ; i < DynamicGrowth ; i ++ ) {
CPPUNIT_ASSERT_EQUAL( int32_t( i ) ,
test.indexOf( [=]( auto v ) {
return v == i * 2 + 1;
} ) );
}
}
}
void ArraysAutoTest::testIndexOfPredMissing( )
{
{
T_Test_ test;
for ( auto i = 0u ; i < StaticSize ; i ++ ) {
test.add( i * 2 + 1 );
}
CPPUNIT_ASSERT_EQUAL( -1 , test.indexOf( [](auto v){ return v % 2 == 0; } ) );
}
{
T_Test_ test;
for ( auto i = 0u ; i < DynamicGrowth ; i ++ ) {
test.add( i * 2 + 1 );
}
CPPUNIT_ASSERT_EQUAL( -1 , test.indexOf( [](auto v){ return v % 2 == 0; } ) );
}
}
void ArraysAutoTest::testContainsPred( )
{
{
T_Test_ test;
for ( auto i = 0u ; i < StaticSize ; i ++ ) {
test.add( i * 2 + 1 );
}
for ( auto i = 0u ; i < StaticSize ; i ++ ) {
CPPUNIT_ASSERT( test.contains( [=]( auto v ) {
return v == i * 2 + 1;
} ) );
}
}
{
T_Test_ test;
for ( auto i = 0u ; i < DynamicGrowth ; i ++ ) {
test.add( i * 2 + 1 );
}
for ( auto i = 0u ; i < DynamicGrowth ; i ++ ) {
CPPUNIT_ASSERT( test.contains( [=]( auto v ) {
return v == i * 2 + 1;
} ) );
}
}
}
void ArraysAutoTest::testContainsPredMissing( )
{
{
T_Test_ test;
for ( auto i = 0u ; i < StaticSize ; i ++ ) {
test.add( i * 2 + 1 );
}
CPPUNIT_ASSERT( !test.contains( [](auto v){ return v % 2 == 0; } ) );
}
{
T_Test_ test;
for ( auto i = 0u ; i < DynamicGrowth ; i ++ ) {
test.add( i * 2 + 1 );
}
CPPUNIT_ASSERT( !test.contains( [](auto v){ return v % 2 == 0; } ) );
}
}
/*----------------------------------------------------------------------------*/
void ArraysAutoTest::testSort( )
{
{

View file

@ -44,6 +44,11 @@ class ArraysBasicTest : public CppUnit::TestFixture
CPPUNIT_TEST( testContains );
CPPUNIT_TEST( testContainsMissing );
CPPUNIT_TEST( testIndexOfPred );
CPPUNIT_TEST( testIndexOfPredMissing );
CPPUNIT_TEST( testContainsPred );
CPPUNIT_TEST( testContainsPredMissing );
CPPUNIT_TEST( testSort );
CPPUNIT_TEST( testSortComparator );
CPPUNIT_TEST( testSortPartial );
@ -92,6 +97,11 @@ public:
void testContains( );
void testContainsMissing( );
void testIndexOfPred( );
void testIndexOfPredMissing( );
void testContainsPred( );
void testContainsPredMissing( );
void testSort( );
void testSortComparator( );
void testSortPartial( );
@ -419,6 +429,46 @@ void ArraysBasicTest::testContainsMissing( )
/*----------------------------------------------------------------------------*/
void ArraysBasicTest::testIndexOfPred( )
{
T_Array< uint32_t > array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT_EQUAL( 0 , array.indexOf( [](auto i ) {
return i > 100;
} ) );
}
void ArraysBasicTest::testIndexOfPredMissing( )
{
T_Array< uint32_t > array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT_EQUAL( -1 , array.indexOf( [](auto i ) {
return i > 1000;
} ) );
}
void ArraysBasicTest::testContainsPred( )
{
T_Array< uint32_t > array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT( array.contains( [](auto i ) {
return i > 100;
} ) );
}
void ArraysBasicTest::testContainsPredMissing( )
{
T_Array< uint32_t > array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT( !array.contains( [](auto i ) {
return i > 1000;
} ) );
}
/*----------------------------------------------------------------------------*/
void ArraysBasicTest::testSort( )
{
T_Array< uint32_t > array;

View file

@ -39,6 +39,11 @@ class ArraysObjectsTest : public CppUnit::TestFixture
CPPUNIT_TEST( testContains );
CPPUNIT_TEST( testContainsMissing );
CPPUNIT_TEST( testIndexOfPred );
CPPUNIT_TEST( testIndexOfPredMissing );
CPPUNIT_TEST( testContainsPred );
CPPUNIT_TEST( testContainsPredMissing );
CPPUNIT_TEST( testInsertCopyEmpty );
CPPUNIT_TEST( testInsertCopyBefore );
CPPUNIT_TEST( testInsertCopyAfter );
@ -98,6 +103,11 @@ public:
void testContains( );
void testContainsMissing( );
void testIndexOfPred( );
void testIndexOfPredMissing( );
void testContainsPred( );
void testContainsPredMissing( );
void testInsertCopyEmpty( );
void testInsertCopyBefore( );
void testInsertCopyAfter( );
@ -586,6 +596,47 @@ void ArraysObjectsTest::testContainsMissing( )
/*----------------------------------------------------------------------------*/
void ArraysObjectsTest::testIndexOfPred( )
{
T_Array< T_Test > a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT_EQUAL( 1 , a1.indexOf( []( auto const& i ) {
return i.serial > 1;
} ) );
}
void ArraysObjectsTest::testIndexOfPredMissing( )
{
T_Array< T_Test > a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT_EQUAL( -1 , a1.indexOf( []( auto const& i ) {
return i.serial > 4;
} ) );
}
void ArraysObjectsTest::testContainsPred( )
{
T_Array< T_Test > a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT( a1.contains( []( auto const& i ) {
return i.serial > 1;
} ) );
}
void ArraysObjectsTest::testContainsPredMissing( )
{
T_Array< T_Test > a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT( !a1.contains( []( auto const& i ) {
return i.serial > 4;
} ) );
}
/*----------------------------------------------------------------------------*/
void ArraysObjectsTest::testInsertCopyEmpty( )
{
{

View file

@ -40,6 +40,11 @@ class ArraysStaticBasicTest : public CppUnit::TestFixture
CPPUNIT_TEST( testContains );
CPPUNIT_TEST( testContainsMissing );
CPPUNIT_TEST( testIndexOfPred );
CPPUNIT_TEST( testIndexOfPredMissing );
CPPUNIT_TEST( testContainsPred );
CPPUNIT_TEST( testContainsPredMissing );
CPPUNIT_TEST( testSort );
CPPUNIT_TEST( testSortComparator );
CPPUNIT_TEST( testSortPartial );
@ -84,6 +89,11 @@ public:
void testContains( );
void testContainsMissing( );
void testIndexOfPred( );
void testIndexOfPredMissing( );
void testContainsPred( );
void testContainsPredMissing( );
void testSort( );
void testSortComparator( );
void testSortPartial( );
@ -381,6 +391,46 @@ void ArraysStaticBasicTest::testContainsMissing( )
/*----------------------------------------------------------------------------*/
void ArraysStaticBasicTest::testIndexOfPred( )
{
T_Test_ array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT_EQUAL( 0 , array.indexOf( [](auto i ) {
return i > 100;
} ) );
}
void ArraysStaticBasicTest::testIndexOfPredMissing( )
{
T_Test_ array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT_EQUAL( -1 , array.indexOf( [](auto i ) {
return i > 1000;
} ) );
}
void ArraysStaticBasicTest::testContainsPred( )
{
T_Test_ array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT( array.contains( [](auto i ) {
return i > 100;
} ) );
}
void ArraysStaticBasicTest::testContainsPredMissing( )
{
T_Test_ array;
array << 123 << 456 << 789;
CPPUNIT_ASSERT( !array.contains( [](auto i ) {
return i > 1000;
} ) );
}
/*----------------------------------------------------------------------------*/
void ArraysStaticBasicTest::testSort( )
{
T_StaticArray< uint32_t , 5000 > array;

View file

@ -39,6 +39,11 @@ class ArraysStaticObjectsTest : public CppUnit::TestFixture
CPPUNIT_TEST( testContains );
CPPUNIT_TEST( testContainsMissing );
CPPUNIT_TEST( testIndexOfPred );
CPPUNIT_TEST( testIndexOfPredMissing );
CPPUNIT_TEST( testContainsPred );
CPPUNIT_TEST( testContainsPredMissing );
CPPUNIT_TEST( testSort );
CPPUNIT_TEST( testSortComparator );
CPPUNIT_TEST( testSortPartial );
@ -88,6 +93,11 @@ public:
void testContains( );
void testContainsMissing( );
void testIndexOfPred( );
void testIndexOfPredMissing( );
void testContainsPred( );
void testContainsPredMissing( );
void testSort( );
void testSortComparator( );
void testSortPartial( );
@ -612,6 +622,47 @@ void ArraysStaticObjectsTest::testContainsMissing( )
/*----------------------------------------------------------------------------*/
void ArraysStaticObjectsTest::testIndexOfPred( )
{
T_Test_ a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT_EQUAL( 1 , a1.indexOf( []( auto const& i ) {
return i.serial > 1;
} ) );
}
void ArraysStaticObjectsTest::testIndexOfPredMissing( )
{
T_Test_ a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT_EQUAL( -1 , a1.indexOf( []( auto const& i ) {
return i.serial > 4;
} ) );
}
void ArraysStaticObjectsTest::testContainsPred( )
{
T_Test_ a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT( a1.contains( []( auto const& i ) {
return i.serial > 1;
} ) );
}
void ArraysStaticObjectsTest::testContainsPredMissing( )
{
T_Test_ a1;
a1 << 1 << 2 << 3;
CPPUNIT_ASSERT( !a1.contains( []( auto const& i ) {
return i.serial > 4;
} ) );
}
/*----------------------------------------------------------------------------*/
void ArraysStaticObjectsTest::testSort( )
{
T_LargeTest_ array;