00001 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00002
00003
00004
00005
00006
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
00016 #define ON__HAVE_RELIABLE_SYSTEM_QSORT
00017 #define ON__QSORT_FASTER_THAN_HSORT
00018
00019 #elif defined(_GNU_SOURCE)
00020
00021
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
00030
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
00048
00049
00050
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
00066
00067
00068
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);
00092 }
00093 else {
00094 memcpy(e_tmp,e_end,width);
00095 memcpy(e_end,base,width);
00096 if (!(--i_end)) {
00097 memcpy(base,e_tmp,width);
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 )
00110 {j++; e_j += width;}
00111 if (compar(e_tmp,e_j)<0 ) {
00112 memcpy(e_i,e_j,width);
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);
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);
00141 }
00142 else {
00143 memcpy(e_tmp,e_end,width);
00144 memcpy(e_end,base,width);
00145 if (!(--i_end)) {
00146 memcpy(base,e_tmp,width);
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 )
00159 {j++; e_j += width;}
00160 if (compar(context,e_tmp,e_j)<0 ) {
00161 memcpy(e_i,e_j,width);
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);
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