opennurbs_sort.cpp
Go to the documentation of this file.
00001 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00002 
00003 /*
00004 If the speed of ON_qsort() functions on arrays that
00005 are nearly sorted is as good as heap sort, then define
00006 ON__QSORT_FASTER_THAN_HSORT.
00007 */
00008 
00009 #define ON_COMPILING_OPENNURBS_SORT_CPP
00010 
00011 #if defined(ON_OS_WINDOWS) && defined(ON_COMPILER_MSC)
00012 
00013 #pragma optimize("t", on)
00014 
00015 // have a reliable thread safe CRT qsort.
00016 #define ON__HAVE_RELIABLE_SYSTEM_QSORT
00017 #define ON__QSORT_FASTER_THAN_HSORT
00018 
00019 #elif defined(_GNU_SOURCE)
00020 
00021 // have a reliable thread safe CRT qsort.
00022 #define ON__HAVE_RELIABLE_SYSTEM_QSORT
00023 #define ON__QSORT_FASTER_THAN_HSORT
00024 
00025 #endif
00026 
00027 #if defined(ON_OS_WINDOWS) && defined(ON_COMPILER_MSC)
00028 
00029 // have a reliable thread safe CRT qsort with context that is
00030 // faster than the functions below.
00031 #define ON__HAVE_RELIABLE_SYSTEM_CONTEXT_QSORT
00032 #define ON__QSORT_FASTER_THAN_HSORT
00033 
00034 #elif defined(_GNU_SOURCE)
00035 
00036 #define ON__HAVE_RELIABLE_SYSTEM_CONTEXT_QSORT
00037 #define ON__QSORT_FASTER_THAN_HSORT
00038 
00039 #endif
00040 
00041 #define work_size 64
00042 
00043 void 
00044 ON_qsort( void *base, size_t nel, size_t width, int (*compar)(void*,const void *, const void *),void* context)
00045 {
00046 #if defined(ON__HAVE_RELIABLE_SYSTEM_CONTEXT_QSORT)
00047   // The call here must be a thread safe system qsort
00048   // that is faster than the alternative code in this function.
00049   // In particular, if it uses a random number generator to
00050   // find pivots, that calculation must be thread safe.
00051 #if defined(ON_COMPILER_MSC)
00052   qsort_s(base,nel,width,compar,context);
00053 #elif defined(ON_COMPILER_XCODE)
00054   qsort_r(base,nel,width,context,compar);
00055 #endif
00056 #else
00057   ON_hsort(base, nel, width, compar, context);
00058 #endif
00059 }
00060 
00061 void 
00062 ON_qsort( void *base, size_t nel, size_t width, int (*compar)(const void *, const void *))
00063 {
00064 #if defined(ON__HAVE_RELIABLE_SYSTEM_QSORT)
00065   // The call here must be a thread safe system qsort
00066   // that is faster than the alternative code in this function.
00067   // In particular, if it uses a random number generator to
00068   // find pivots, that calculation must be thread safe.
00069   qsort(base,nel,width,compar);
00070 #else
00071   ON_hsort(base, nel, width, compar);
00072 #endif
00073 }
00074 
00075 void
00076 ON_hsort(void *base, size_t nel, size_t width, int (*compar)(const void*,const void*))
00077 {
00078   size_t
00079     i_end,k;
00080   unsigned char
00081     work_memory[work_size], *e_tmp, *e_end;
00082 
00083   if (nel < 2) return;
00084   k = nel >> 1;
00085   i_end = nel-1;
00086   e_end = ((unsigned char*)base) + i_end*width;
00087   e_tmp = (width > work_size) ? (unsigned char*)onmalloc(width) : work_memory;
00088   for (;;) {
00089     if (k) {
00090       --k;
00091       memcpy(e_tmp,((unsigned char*)base)+k*width,width); /* e_tmp = e[k]; */
00092     } 
00093     else {      
00094       memcpy(e_tmp,e_end,width);     /* e_tmp = e[i_end]; */
00095       memcpy(e_end,base,width);      /* e[i_end] = e[0];  */
00096       if (!(--i_end)) {
00097         memcpy(base,e_tmp,width);    /* e[0] = e_tmp;     */
00098         break;
00099       }
00100       e_end -= width;
00101     }
00102     { size_t i, j;
00103       unsigned char *e_i, *e_j;
00104       i = k;
00105       j = (k<<1) + 1;
00106       e_i = ((unsigned char*)base) + i*width;
00107       while (j <= i_end) {
00108         e_j = ((unsigned char*)base) + j*width;
00109         if (j < i_end && compar(e_j,e_j+width)<0 /*e[j] < e[j + 1] */)
00110           {j++; e_j += width;}
00111         if (compar(e_tmp,e_j)<0 /* e_tmp < e[j] */) {
00112           memcpy(e_i,e_j,width); /* e[i] = e[j]; */
00113           i = j;
00114           e_i = e_j;
00115           j = (j<<1) + 1;
00116         } else j = i_end + 1;
00117       }
00118       memcpy(e_i,e_tmp,width); /* e[i] = e_tmp; */
00119     }
00120   }
00121   if (width > work_size) onfree(e_tmp); 
00122 }
00123 
00124 void
00125 ON_hsort(void *base, size_t nel, size_t width, int (*compar)(void*,const void*,const void*), void* context)
00126 {
00127   size_t
00128     i_end,k;
00129   unsigned char
00130     work_memory[work_size], *e_tmp, *e_end;
00131 
00132   if (nel < 2) return;
00133   k = nel >> 1;
00134   i_end = nel-1;
00135   e_end = ((unsigned char*)base) + i_end*width;
00136   e_tmp = (width > work_size) ? (unsigned char*)onmalloc(width) : work_memory;
00137   for (;;) {
00138     if (k) {
00139       --k;
00140       memcpy(e_tmp,((unsigned char*)base)+k*width,width); /* e_tmp = e[k]; */
00141     } 
00142     else {      
00143       memcpy(e_tmp,e_end,width);     /* e_tmp = e[i_end]; */
00144       memcpy(e_end,base,width);      /* e[i_end] = e[0];  */
00145       if (!(--i_end)) {
00146         memcpy(base,e_tmp,width);    /* e[0] = e_tmp;     */
00147         break;
00148       }
00149       e_end -= width;
00150     }
00151     { size_t i, j;
00152       unsigned char *e_i, *e_j;
00153       i = k;
00154       j = (k<<1) + 1;
00155       e_i = ((unsigned char*)base) + i*width;
00156       while (j <= i_end) {
00157         e_j = ((unsigned char*)base) + j*width;
00158         if (j < i_end && compar(context,e_j,e_j+width)<0 /*e[j] < e[j + 1] */)
00159           {j++; e_j += width;}
00160         if (compar(context,e_tmp,e_j)<0 /* e_tmp < e[j] */) {
00161           memcpy(e_i,e_j,width); /* e[i] = e[j]; */
00162           i = j;
00163           e_i = e_j;
00164           j = (j<<1) + 1;
00165         } else j = i_end + 1;
00166       }
00167       memcpy(e_i,e_tmp,width); /* e[i] = e_tmp; */
00168     }
00169   }
00170   if (width > work_size) onfree(e_tmp); 
00171 }
00172 
00173 #undef work_size  
00174 
00175 #define ON_COMPILING_OPENNURBS_QSORT_FUNCTIONS
00176 #define ON_COMPILING_OPENNURBS_HSORT_FUNCTIONS
00177 #define ON_SORT_TEMPLATE_STATIC_FUNCTION
00178 
00179 #define ON_SORT_TEMPLATE_TYPE double
00180 #define ON_QSORT_FNAME ON_qsort_double
00181 #define ON_HSORT_FNAME ON_hsort_double
00182 #include "pcl/surface/3rdparty/opennurbs/opennurbs_qsort_template.h"
00183 #include "pcl/surface/3rdparty/opennurbs/opennurbs_hsort_template.h"
00184 #undef ON_SORT_TEMPLATE_TYPE
00185 #undef ON_QSORT_FNAME
00186 #undef ON_HSORT_FNAME
00187 
00188 void ON_SortDoubleArray( 
00189         ON::sort_algorithm sort_algorithm,
00190         double* a,
00191         size_t nel
00192         )
00193 {
00194   if ( ON::heap_sort == sort_algorithm )
00195     ON_hsort_double(a,nel);
00196   else
00197     ON_qsort_double(a,nel);
00198 }
00199 
00200 #define ON_SORT_TEMPLATE_TYPE float
00201 #define ON_QSORT_FNAME ON_qsort_float
00202 #define ON_HSORT_FNAME ON_hsort_float
00203 #include "pcl/surface/3rdparty/opennurbs/opennurbs_qsort_template.h"
00204 #include "pcl/surface/3rdparty/opennurbs/opennurbs_hsort_template.h"
00205 #undef ON_SORT_TEMPLATE_TYPE
00206 #undef ON_QSORT_FNAME
00207 #undef ON_HSORT_FNAME
00208 
00209 void ON_SortFloatArray( 
00210         ON::sort_algorithm sort_algorithm,
00211         float* a,
00212         size_t nel
00213         )
00214 {
00215   if ( ON::heap_sort == sort_algorithm )
00216     ON_hsort_float(a,nel);
00217   else
00218     ON_qsort_float(a,nel);
00219 }
00220 
00221 
00222 #define ON_SORT_TEMPLATE_TYPE int
00223 #define ON_QSORT_FNAME ON_qsort_int
00224 #define ON_HSORT_FNAME ON_hsort_int
00225 #include "pcl/surface/3rdparty/opennurbs/opennurbs_qsort_template.h"
00226 #include "pcl/surface/3rdparty/opennurbs/opennurbs_hsort_template.h"
00227 #undef ON_SORT_TEMPLATE_TYPE
00228 #undef ON_QSORT_FNAME
00229 #undef ON_HSORT_FNAME
00230 
00231 void ON_SortIntArray(
00232         ON::sort_algorithm sort_algorithm,
00233         int* a,
00234         size_t nel
00235         )
00236 {
00237   if ( ON::heap_sort == sort_algorithm )
00238     ON_hsort_int(a,nel);
00239   else
00240     ON_qsort_int(a,nel);
00241 }
00242 
00243 
00244 #define ON_SORT_TEMPLATE_TYPE unsigned int
00245 #define ON_QSORT_FNAME ON_qsort_uint
00246 #define ON_HSORT_FNAME ON_hsort_uint
00247 #include "pcl/surface/3rdparty/opennurbs/opennurbs_qsort_template.h"
00248 #include "pcl/surface/3rdparty/opennurbs/opennurbs_hsort_template.h"
00249 #undef ON_SORT_TEMPLATE_TYPE
00250 #undef ON_QSORT_FNAME
00251 #undef ON_HSORT_FNAME
00252 
00253 void ON_SortUnsignedIntArray(
00254         ON::sort_algorithm sort_algorithm,
00255         unsigned int* a,
00256         size_t nel
00257         )
00258 {
00259   if ( ON::heap_sort == sort_algorithm )
00260     ON_hsort_uint(a,nel);
00261   else
00262     ON_qsort_uint(a,nel);
00263 }
00264 


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:03