59 #undef DIGITS_ALWAYS_FIRST 67 #undef MANUAL_NUMCOMPARE 70 #undef DEBUG_NATSTRCMP 74 #ifdef DEBUG_NATSTRCMP 78 static inline void debugPrint(
const char* text,
T item1,
T item2)
80 std::cerr << text <<
": <" << item1 <<
"> <" << item2 <<
">\n";
84 static inline void debugPrint
86 const char* b1,
const char* e1,
87 const char* b2,
const char* e2
91 while (b1 < e1) { std::cerr << *b1++; }
92 std::cerr << *e1 <<
"> ";
95 while (b2 < e2) { std::cerr << *b2++; }
96 std::cerr << *e2 <<
">\n";
100 #ifdef MANUAL_NUMCOMPARE 102 static inline int manual_numcompare(
const char* s1,
const char* s2)
106 const int cmp = (*s1 - *s2);
107 if (!cmp)
return cmp;
120 #ifdef DEBUG_NATSTRCMP 121 debugPrint(
"natstrcmp", s1, s2);
125 enum stateType { SCAN, ALPHA, NUMERIC };
132 const char* numbeg1 =
nullptr;
133 const char* numbeg2 =
nullptr;
134 const char* numend1 =
nullptr;
135 const char* numend2 =
nullptr;
137 stateType state = SCAN;
150 const unsigned digitMask =
151 ((isdigit(*p2) ? 2:0) | (isdigit(*p1) ? 1:0));
157 #ifdef DEBUG_NATSTRCMP 158 debugPrint(
"SCAN", *p1, *p2);
179 #ifdef DIGITS_ALWAYS_FIRST 212 while (*p1 ==
'0') { ++p1; ++zeros1; }
216 while (*p1 ==
'0') { ++p1; }
222 while (*p2 ==
'0') { ++p2; ++zeros2; }
226 while (*p2 ==
'0') { ++p2; }
229 if (zeros1 == zeros2)
235 if (!isdigit(*p1)) --p1;
236 if (!isdigit(*p2)) --p2;
238 numbeg1 = numend1 = p1;
239 numbeg2 = numend2 = p2;
249 #ifdef DEBUG_NATSTRCMP 250 debugPrint(
"ALPHA", *p1, *p2);
274 while (isdigit(*p1)) numend1 = p1++;
275 while (isdigit(*p2)) numend2 = p2++;
277 #ifdef DEBUG_NATSTRCMP 278 debugPrint(
"NUMERIC", *p1, *p2);
279 debugPrint(numbeg1,numend1, numbeg2,numend2);
283 const size_t len1 = (numend1 - numbeg1);
284 const size_t len2 = (numend2 - numbeg2);
290 else if (len1 > len2)
298 const int cmp = strncmp(numbeg1, numbeg2, len1+1);
306 #ifdef MANUAL_STRNCMP 307 return manual_numcompare(numbeg1, numbeg2);
317 if (zeros1 < zeros2)
return -1;
318 if (zeros1 > zeros2)
return 1;
319 if (!*p1 && *p2)
return -1;
320 if (*p1 && !*p2)
return 1;
Specialized string sorting.
int natstrcmp(const char *s1, const char *s2)
'Natural' compare for C-strings