7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 00:21:25 +00:00

Replace std::lexicographical_compare_three_way

On platforms that don't yet support the std:: version, we implement our
own, possibly slower, version of the 3-way compare
This commit is contained in:
Seth Hillbrand 2024-07-24 17:50:20 +02:00
parent 6bdafca1f0
commit 433677fc21
3 changed files with 64 additions and 3 deletions
include
libs/core/include/core
qa/tests/common

View File

@ -26,6 +26,7 @@
#include <stdexcept>
#include <vector>
#include <core/kicad_algo.h>
#include <import_export.h>
#if defined( _MSC_VER )
@ -115,9 +116,7 @@ public:
int compare( const BASE_SET& other ) const
{
auto result = std::lexicographical_compare_three_way(
m_bits.begin(), m_bits.end(), other.m_bits.begin(), other.m_bits.end() );
return result == std::strong_ordering::equal ? 0 : ( result == std::strong_ordering::less ? -1 : 1 );
return alg::lexicographical_compare_3way( m_bits, other.m_bits );
}
iterator begin() { return m_bits.begin(); }

View File

@ -239,6 +239,42 @@ size_t longest_common_subset( const _Container& __c1, const _Container& __c2 )
return longest;
}
/**
* @brief Compares two containers lexicographically.
*
* Returns a negative value if the first container is less than the second,
* zero if they are equal, and a positive value if the first container is
* greater than the second. This is a re-implementation of std::lexicographical_compare_3way
* because it is not available in all compilers.
*/
template <class _Container1, class _Container2>
int lexicographical_compare_3way( const _Container1& __c1, const _Container2& __c2 )
{
#ifdef __cpp_lib_three_way_comparison // Check to see if we have an optimized version
auto retval = std::lexicographical_compare_three_way( __c1.begin(), __c1.end(), __c2.begin(), __c2.end() );
return retval == std::strong_ordering::equal ? 0 : ( retval == std::strong_ordering::less ? -1 : 1 );
#else
auto it1 = __c1.begin();
auto it2 = __c2.begin();
while( it1 != __c1.end() && it2 != __c2.end() )
{
if( *it1 < *it2 )
return -1;
if( *it1 > *it2 )
return 1;
++it1;
++it2;
}
if( it2 == __c2.end() )
return !( it1 == __c1.end() );
else
return -1;
#endif // __cpp_lib_three_way_comparison
}
} // namespace alg
#endif /* INCLUDE_CORE_KICAD_ALGO_H_ */

View File

@ -125,6 +125,32 @@ BOOST_AUTO_TEST_CASE(BASE_SETComparisonOperator)
BOOST_CHECK( !( set1 < set2 ) ); // Although sizes are equal, elements in set2 are subsets of set1
}
// Test compare function
BOOST_AUTO_TEST_CASE(BASE_SETCompareFunction)
{
BASE_SET set1( 10 );
BASE_SET set2( 10 );
BASE_SET set3( 10 );
BASE_SET set4( 15 );
set1.set( 2 );
set1.set( 4 );
set2.set( 2 );
set2.set( 4 );
set3.set( 2 );
set4.set( 2 );
BOOST_CHECK_EQUAL( set1.compare( set2 ), 0 ); // set1 and set2 are equal
BOOST_CHECK_EQUAL( set1.compare( set3 ), 1 ); // set1 is greater than set3
BOOST_CHECK_EQUAL( set3.compare( set1 ), -1 ); // set3 is less than set1
BOOST_CHECK_EQUAL( set3.compare( set4 ), -1 ); // set3 is less than set4
BOOST_CHECK_EQUAL( set4.compare( set3 ), 1 ); // set4 is greater than set3
}
// Test boolean operator&=
BOOST_AUTO_TEST_CASE(BASE_SETAndAssignment)
{