25#ifndef INCLUDE_CORE_KICAD_ALGO_H_
26#define INCLUDE_CORE_KICAD_ALGO_H_
44template <
typename _Type,
typename _Function>
45void run_on_pair( std::pair<_Type, _Type>& __pair, _Function __f )
61template <
typename _InputIterator,
typename _Function>
62void adjacent_pairs( _InputIterator __first, _InputIterator __last, _Function __f )
64 if( __first != __last )
66 _InputIterator __follow = __first;
68 for( ; __first != __last; ++__first, ++__follow )
69 __f( *__follow, *__first );
83template <
typename _InputIterator,
typename _Function>
84void for_all_pairs( _InputIterator __first, _InputIterator __last, _Function __f )
86 if( __first != __last )
88 _InputIterator __follow = __first;
90 for( ; __first != __last; ++__first, ++__follow )
91 for( _InputIterator __it = __first; __it != __last; ++__it )
92 __f( *__follow, *__it );
99template <
class _Container,
typename _Value>
100bool contains(
const _Container& __container, _Value __value )
102 return std::find( __container.begin(), __container.end(), __value ) != __container.end();
112template <
typename _Type,
typename _Value>
115 return __pair.first ==
static_cast<_Type
>( __value )
116 || __pair.second ==
static_cast<_Type
>( __value );
131 wxCHECK_MSG( __wrap > 0,
false, wxT(
"Wrap must be positive!" ) );
133 while( __maxval >= __wrap )
136 while( __maxval < 0 )
139 while( __minval >= __wrap )
142 while( __minval < 0 )
148 while( __val >= __wrap )
151 if( __maxval > __minval )
152 return __val >= __minval && __val <= __maxval;
154 return __val >= __minval || __val <= __maxval;
164template <
class _Container,
typename _Value>
167 __c.erase( std::remove( __c.begin(), __c.end(), __value ), __c.end() );
173template <
class _Container,
class _Function>
176 __c.erase( std::remove_if( __c.begin(), __c.end(), std::forward<_Function>( __f ) ), __c.end() );
182template <
class _Container>
185 __c.erase( std::unique( __c.begin(), __c.end() ), __c.end() );
188template <
class _Container,
class _Function>
191 __c.erase( std::unique( __c.begin(), __c.end(), std::forward<_Function>( __f ) ), __c.end() );
197template <typename T, std::enable_if_t<std::is_integral<T>::value,
int> = 0>
207template <
class _Container>
210 size_t __c1_size = __c1.size();
211 size_t __c2_size = __c2.size();
213 if( __c1_size == 0 || __c2_size == 0 )
217 std::vector<std::vector<size_t>> table( __c1_size + 1, std::vector<size_t>( __c2_size + 1, 0 ) );
221 for(
size_t i = 1; i <= __c1_size; ++i )
223 for(
size_t j = 1; j <= __c2_size; ++j )
225 if( __c1[i - 1] == __c2[j - 1] )
227 table[i][j] = table[i - 1][j - 1] + 1;
228 longest = std::max( longest,
static_cast<size_t>( table[i][j] ) );
245template <
class Container1Iter,
class Container2Iter>
247 Container2Iter aC2_first, Container2Iter aC2_last )
249#ifdef __cpp_lib_three_way_comparison
251 std::lexicographical_compare_three_way( aC1_first, aC1_last, aC2_first, aC2_last );
252 return retval == std::strong_ordering::equal
254 : ( retval == std::strong_ordering::less ? -1 : 1 );
256 Container1Iter it1 = aC1_first;
257 Container2Iter it2 = aC2_first;
259 while( it1 != aC1_last && it2 != aC2_last )
269 if( it2 == aC2_last )
270 return !( it1 == aC1_last );
void delete_if(_Container &__c, _Function &&__f)
Deletes all values from __c for which __f returns true.
void remove_duplicates(_Container &__c)
Deletes all duplicate values from __c.
void delete_matching(_Container &__c, _Value __value)
Covers for the horrifically named std::remove and std::remove_if (neither of which remove anything).
bool signbit(T v)
Integral version of std::signbit that works all compilers.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
bool pair_contains(const std::pair< _Type, _Type > __pair, _Value __value)
Returns true if either of the elements in an std::pair contains the given value.
bool within_wrapped_range(T __val, T __minval, T __maxval, T __wrap)
Test if __val lies within __minval and __maxval in a wrapped range.
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
int lexicographical_compare_three_way(Container1Iter aC1_first, Container1Iter aC1_last, Container2Iter aC2_first, Container2Iter aC2_last)
Compares two containers lexicographically.
void adjacent_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every sequential pair of elements of a sequence.
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
size_t longest_common_subset(const _Container &__c1, const _Container &__c2)
Returns the length of the longest common subset of values between two containers.