diff -r e20de85af2ee -r ce057bb09d0b genericopenlibs/cstdlib/LSTDLIB/QSORT.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/cstdlib/LSTDLIB/QSORT.CPP Fri Jun 04 16:20:51 2010 +0100 @@ -0,0 +1,206 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Map ANSI bsearch and qsort onto EPOC32 functions +// +// + +#include +#include + +NONSHARABLE_CLASS(TAnsiKey) : public TKey + { +public: + TAnsiKey(const TAny* key, const TAny* base, TInt length, TInt (*compar)(const TAny*, const TAny*)) + : iSearchKey(key), iCmp(compar) + { SetPtr(base); iKeyLength=length; } + + virtual TInt Compare(TInt aLeft,TInt aRight) const; + virtual TAny *At(TInt anIndex) const; +private: + const TAny* iSearchKey; + TInt (*iCmp)(const TAny*, const TAny*); + }; + +TInt TAnsiKey::Compare (TInt aLeft,TInt aRight) const + { + if (aRight==KIndexPtr) + return (*iCmp)(At(aLeft),iSearchKey); + else + return (*iCmp)(At(aLeft),At(aRight)); + } + +TAny* TAnsiKey::At (TInt aPos) const + { + return (TUint8*)iPtr+(aPos*iKeyLength); + } + +NONSHARABLE_CLASS(TAnsiSwap) : public TSwap + { +public: + TAnsiSwap(const TAny* base, TInt length) : iPtr(base), iLength(length) {} + + virtual void Swap(TInt aLeft,TInt aRight) const; +private: + TUint8* At(TInt aPos) const {return (TUint8*)iPtr+(aPos*iLength);} + + const TAny* iPtr; + TInt iLength; + }; + +void TAnsiSwap::Swap(TInt aLeft,TInt aRight) const + { + TUint8* left=At(aLeft); + TUint8* right=At(aRight); + TUint8 tmp; + + for (TInt i=iLength; i>0; i--) + { + tmp=*left; + *left++=*right; + *right++=tmp; + } + } + +extern "C" { + +/* +FUNCTION +<>---binary search + +INDEX + bsearch + +ANSI_SYNOPSIS + #include + void *bsearch(const void *<[key]>, const void *<[base]>, + size_t <[nmemb]>, size_t <[size]>, + int (*<[compar]>)(const void *, const void *)); + +TRAD_SYNOPSIS + #include + char *bsearch(<[key]>, <[base]>, <[nmemb]>, <[size]>, <[compar]>) + char *<[key]>; + char *<[base]>; + size_t <[nmemb]>, <[size]>; + int (*<[compar]>)(); + +DESCRIPTION +<> searches an array beginning at <[base]> for any element +that matches <[key]>, using binary search. <[nmemb]> is the element +count of the array; <[size]> is the size of each element. + +The array must be sorted in ascending order with respect to the +comparison function <[compar]> (which you supply as the last argument of +<>). + +You must define the comparison function <<(*<[compar]>)>> to have two +arguments; its result must be negative if the first argument is +less than the second, zero if the two arguments match, and +positive if the first argument is greater than the second (where +``less than'' and ``greater than'' refer to whatever arbitrary +ordering is appropriate). + +RETURNS +Returns a pointer to an element of <[array]> that matches <[key]>. If +more than one matching element is available, the result may point to +any of them. Returns NULL if no matching element is found. + +PORTABILITY +<> is ANSI. + +No supporting OS subroutines are required. +*/ + +/** +searches an array beginning at <[base]> for any element +that matches <[key]>, using binary search +@return a pointer to an element of <[array]> that matches <[key]>. If +more than one matching element is available, the result may point to +any of them. Returns NULL if no matching element is found. +@param key +@param base +@param nmemb +@param size +*/ +EXPORT_C void* bsearch (const void* key, const void* base, size_t nmemb, size_t size, + int (*compar)(const void*, const void*)) + { + TAnsiKey searchMe(key, base, size, compar); + TInt result=KIndexPtr; + TInt r=User::BinarySearch(nmemb, searchMe, result); + if (r==0) + return searchMe.At(result); + else + return NULL; + } + +/* +FUNCTION +<>---sort an array + +INDEX + qsort + +ANSI_SYNOPSIS + #include + void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>, + int (*<[compar]>)(const void *, const void *) ); + +TRAD_SYNOPSIS + #include + qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> ) + char *<[base]>; + size_t <[nmemb]>; + size_t <[size]>; + int (*<[compar]>)(); + +DESCRIPTION +<> sorts an array (beginning at <[base]>) of <[nmemb]> objects. +<[size]> describes the size of each element of the array. + +You must supply a pointer to a comparison function, using the argument +shown as <[compar]>. (This permits sorting objects of unknown +properties.) Define the comparison function to accept two arguments, +each a pointer to an element of the array starting at <[base]>. The +result of <<(*<[compar]>)>> must be negative if the first argument is +less than the second, zero if the two arguments match, and positive if +the first argument is greater than the second (where ``less than'' and +``greater than'' refer to whatever arbitrary ordering is appropriate). + +The array is sorted in place; that is, when <> returns, the +array elements beginning at <[base]> have been reordered. + +RETURNS +<> does not return a result. + +PORTABILITY +<> is required by ANSI (without specifying the sorting algorithm). +*/ + +/** +Sort an array. +@param base +@param nmemb +@param size describes the size of each element of the array +*/ +EXPORT_C void qsort (void* base, size_t nmemb, size_t size, + int (*compar)(const void*, const void*)) + { + TAnsiKey searchMe(NULL, base, size, compar); + TAnsiSwap swapUs(base,size); + User::QuickSort(nmemb, searchMe, swapUs); + return; + } + +} // extern "C"