/*- * Copyright 2005 Guram Dukashvili * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ //--------------------------------------------------------------------------- #ifndef QSortBSearchH #define QSortBSearchH //------------------------------------------------------------------------------- namespace ksys { //------------------------------------------------------------------------------- template< class T> #ifndef __BCPLUSPLUS__ inline #endif void qSort(T * ptr, intptr_t lb, intptr_t ub) { intptr_t l, r, m; if( lb < ub ){ if( ub - lb < 12 ){ for( r = ub; r > lb; r-- ){ for( m = r, l = m - 1; l >= lb; l-- ) if( ptr[m] < ptr[l] ) m = l; xchg(ptr[m],ptr[r]); } } else{ m = lb + ((ub - lb) >> 1); l = lb, r = ub; for(;;){ while( l < r && ptr[m] > ptr[l] ) l++; while( r >= l && ptr[m] < ptr[r] ) r--; if( l >= r ) break; xchg(ptr[l],ptr[r]); if( r == m ) m = l; else if( l == m ) m = r; l++; r--; } qSort(ptr,lb,r); qSort(ptr,r + 1,ub); } } } //------------------------------------------------------------------------------- template #ifndef __BCPLUSPLUS__ inline #endif void qSort(T * const ptr,intptr_t lb,intptr_t ub,const F f) { intptr_t l, r, m; if( lb < ub ){ if( ub - lb < 12 ){ for( r = ub; r > lb; r-- ){ for( m = r, l = m - 1; l >= lb; l-- ) if( f(ptr[m],ptr[l]) < 0 ) m = l; xchg(ptr[m],ptr[r]); } } else{ m = lb + ((ub - lb) >> 1); l = lb, r = ub; for(;;){ while( l < r && f(ptr[m],ptr[l]) > 0 ) l++; while( r >= l && f(ptr[m],ptr[r]) < 0 ) r--; if( l >= r ) break; xchg(ptr[l],ptr[r]); if( r == m ) m = l; else if( l == m ) m = r; l++; r--; } qSort(ptr,lb,r,f); qSort(ptr,r + 1,ub,f); } } } //------------------------------------------------------------------------------- template #ifndef __BCPLUSPLUS__ inline #endif void qSort(T * const ptr, intptr_t lb, intptr_t ub) { intptr_t l, r, m; if( lb < ub ){ if( ub - lb < 12 ){ for( r = ub; r > lb; r-- ){ for( m = r, l = m - 1; l >= lb; l-- ) if( f(ptr[m], ptr[l]) < 0 ) m = l; T t = ptr[m]; ptr[m] = ptr[r]; ptr[r] = t; } } else{ m = lb + ((ub - lb) >> 1); l = lb, r = ub; for(;;){ while( l < r && f(ptr[m], ptr[l]) > 0 ) l++; while( r >= l && f(ptr[m], ptr[r]) < 0 ) r--; if( l >= r ) break; T t = ptr[l]; ptr[l] = ptr[r]; ptr[r] = t; if( r == m ) m = l; else if( l == m ) m = r; l++; r--; } qSort< T,f>(ptr, lb, r); qSort< T,f>(ptr, r + 1, ub); } } } //------------------------------------------------------------------------------- template< class T,class PT> #ifndef __BCPLUSPLUS__ inline #endif void qSort(T * const ptr, intptr_t lb, intptr_t ub, intptr_t(*const f)(const T & p1, const T & p2, const PT & param), const PT & param) { intptr_t l, r, m; if( lb < ub ){ if( ub - lb < 12 ){ for( r = ub; r > lb; r-- ){ for( m = r, l = m - 1; l >= lb; l-- ) if( f(ptr[m], ptr[l], param) < 0 ) m = l; T t = ptr[m]; ptr[m] = ptr[r]; ptr[r] = t; } } else{ m = lb + ((ub - lb) >> 1); l = lb, r = ub; for(;;){ while( l < r && f(ptr[m], ptr[l], param) > 0 ) l++; while( r >= l && f(ptr[m], ptr[r], param) < 0 ) r--; if( l >= r ) break; T t = ptr[l]; ptr[l] = ptr[r]; ptr[r] = t; if( r == m ) m = l; else if( l == m ) m = r; l++; r--; } qSort< T>(ptr, lb, r, f, param); qSort< T>(ptr, r + 1, ub, f, param); } } } //------------------------------------------------------------------------------- template< class T, class PT, intptr_t(*const f)(const T & p1, const T & p2, const PT & param) > #ifndef __BCPLUSPLUS__ inline #endif void qSort(T * const ptr, intptr_t lb, intptr_t ub, const PT & param) { intptr_t l, r, m; if( lb < ub ){ if( ub - lb < 12 ){ for( r = ub; r > lb; r-- ){ for( m = r, l = m - 1; l >= lb; l-- ) if( f(ptr[m], ptr[l], param) < 0 ) m = l; T t = ptr[m]; ptr[m] = ptr[r]; ptr[r] = t; } } else{ m = lb + ((ub - lb) >> 1); l = lb, r = ub; for(;;){ while( l < r && f(ptr[m], ptr[l], param) > 0 ) l++; while( r >= l && f(ptr[m], ptr[r], param) < 0 ) r--; if( l >= r ) break; T t = ptr[l]; ptr[l] = ptr[r]; ptr[r] = t; if( r == m ) m = l; else if( l == m ) m = r; l++; r--; } qSort< T>(ptr, lb, r, f, param); qSort< T>(ptr, r + 1, ub, f, param); } } } //------------------------------------------------------------------------------- /*template < class T, class PT, long (*f)(const T & p1,const T & p2,PT param), void (*e)(T * ptr,long p1,long p2,PT param) > #ifndef __BCPLUSPLUS__ inline #endif void qSort(T * ptr,long lb,long ub,PT param) { long l, r, m; if( lb < ub ){ if( ub - lb < 12 ){ for( r = ub; r > lb; r-- ){ for( m = r, l = m - 1; l >= lb; l-- ) if( f(ptr[m],ptr[l]) < 0 ) m = l; e(ptr,m,r,param); } } else { m = lb + ((ub - lb) >> 1); l = lb, r = ub; for(;;){ while( l < r && f(ptr[m],ptr[l]) > 0 ) l++; while( r >= l && f(ptr[m],ptr[r]) < 0 ) r--; if( l >= r ) break; e(ptr,l,r,param); if( r == m ) m = l; else if( l == m ) m = r; l++; r--; } qSort(ptr, lb, r, param); qSort(ptr, r + 1, ub, param); } } }*/ //------------------------------------------------------------------------------- template< class T> #ifndef __BCPLUSPLUS__ inline #endif intptr_t bSearch(const T * bsa, const T & item, intptr_t & c) { intptr_t low = 0, high = c - 1, pos = -1; c = 1; while( low <= high ){ pos = (low + high) / 2; c = item > bsa[pos] ? 1 : item < bsa[pos] ? -1 : 0; if( c > 0 ){ low = pos + 1; } else if( c < 0 ){ high = pos - 1; } else break; } return pos; } //------------------------------------------------------------------------------- template< class T> #ifndef __BCPLUSPLUS__ inline #endif intptr_t bSearch(const T * bsa, const T & item, intptr_t & c, intptr_t(*const F)(const T &, const T &)) { intptr_t low = 0, high = c - 1, pos = -1; c = 1; while( low <= high ){ pos = (low + high) / 2; c = F(item, bsa[pos]); if( c > 0 ){ low = pos + 1; } else if( c < 0 ){ high = pos - 1; } else break; } return pos; } //------------------------------------------------------------------------------- template< class T,intptr_t(*F)(const T &, const T &)> #ifndef __BCPLUSPLUS__ inline #endif intptr_t bSearch(const T * bsa, const T & item, intptr_t & c) { intptr_t low = 0, high = c - 1, pos = -1; c = 1; while( low <= high ){ pos = (low + high) / 2; c = F(item, bsa[pos]); if( c > 0 ){ low = pos + 1; } else if( c < 0 ){ high = pos - 1; } else break; } return pos; } //------------------------------------------------------------------------------- } //------------------------------------------------------------------------------- #endif