Created
July 12, 2014 15:13
-
-
Save huandu/08eb990a9b85ef3b4edb to your computer and use it in GitHub Desktop.
A macro implementation of `strrchr()`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
#define _STRRCHR_IMPL_COMMON(str, ch, offset) (str)[sizeof((str)) - 1 - (offset)] == (ch)? (str) + sizeof((str)) - (offset): sizeof((str)) <= (offset) + 1? (str) | |
#define _STRRCHR_IMPL_31(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 31): (str)) | |
#define _STRRCHR_IMPL_30(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 30): _STRRCHR_IMPL_31(str, ch)) | |
#define _STRRCHR_IMPL_29(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 29): _STRRCHR_IMPL_30(str, ch)) | |
#define _STRRCHR_IMPL_28(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 28): _STRRCHR_IMPL_29(str, ch)) | |
#define _STRRCHR_IMPL_27(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 27): _STRRCHR_IMPL_28(str, ch)) | |
#define _STRRCHR_IMPL_26(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 26): _STRRCHR_IMPL_27(str, ch)) | |
#define _STRRCHR_IMPL_25(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 25): _STRRCHR_IMPL_26(str, ch)) | |
#define _STRRCHR_IMPL_24(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 24): _STRRCHR_IMPL_25(str, ch)) | |
#define _STRRCHR_IMPL_23(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 23): _STRRCHR_IMPL_24(str, ch)) | |
#define _STRRCHR_IMPL_22(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 22): _STRRCHR_IMPL_23(str, ch)) | |
#define _STRRCHR_IMPL_21(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 21): _STRRCHR_IMPL_22(str, ch)) | |
#define _STRRCHR_IMPL_20(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 20): _STRRCHR_IMPL_21(str, ch)) | |
#define _STRRCHR_IMPL_19(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 19): _STRRCHR_IMPL_20(str, ch)) | |
#define _STRRCHR_IMPL_18(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 18): _STRRCHR_IMPL_19(str, ch)) | |
#define _STRRCHR_IMPL_17(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 17): _STRRCHR_IMPL_18(str, ch)) | |
#define _STRRCHR_IMPL_16(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 16): _STRRCHR_IMPL_17(str, ch)) | |
#define _STRRCHR_IMPL_15(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 15): _STRRCHR_IMPL_16(str, ch)) | |
#define _STRRCHR_IMPL_14(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 14): _STRRCHR_IMPL_15(str, ch)) | |
#define _STRRCHR_IMPL_13(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 13): _STRRCHR_IMPL_14(str, ch)) | |
#define _STRRCHR_IMPL_12(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 12): _STRRCHR_IMPL_13(str, ch)) | |
#define _STRRCHR_IMPL_11(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 11): _STRRCHR_IMPL_12(str, ch)) | |
#define _STRRCHR_IMPL_10(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 10): _STRRCHR_IMPL_11(str, ch)) | |
#define _STRRCHR_IMPL_9(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 9): _STRRCHR_IMPL_10(str, ch)) | |
#define _STRRCHR_IMPL_8(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 8): _STRRCHR_IMPL_9(str, ch)) | |
#define _STRRCHR_IMPL_7(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 7): _STRRCHR_IMPL_8(str, ch)) | |
#define _STRRCHR_IMPL_6(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 6): _STRRCHR_IMPL_7(str, ch)) | |
#define _STRRCHR_IMPL_5(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 5): _STRRCHR_IMPL_6(str, ch)) | |
#define _STRRCHR_IMPL_4(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 4): _STRRCHR_IMPL_5(str, ch)) | |
#define _STRRCHR_IMPL_3(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 3): _STRRCHR_IMPL_4(str, ch)) | |
#define _STRRCHR_IMPL_2(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 2): _STRRCHR_IMPL_3(str, ch)) | |
#define _STRRCHR_IMPL_1(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 1): _STRRCHR_IMPL_2(str, ch)) | |
#define _STRRCHR_IMPL_0(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 0): _STRRCHR_IMPL_1(str, ch)) | |
// a macro version of strrchr(). | |
// it has several limitations: | |
// - str must be a literal string, e.g. "a string". | |
// - if ch cannot be found in last 32 characters, it will return the whole string. | |
// this limit can be increased by adding more _STRRCHR_IMPL_* macros. | |
#define _STRRCHR(str, ch) (sizeof((str)) <= 1? (str): _STRRCHR_IMPL_0(str, ch)) | |
#define __FILENAME__ _STRRCHR(__FILE__, '/') | |
int main() { | |
cout << "full file path: \t" << __FILE__ << endl; | |
cout << "short filename: \t" << __FILENAME__ << endl; | |
cout << endl; | |
cout << "case 1: \n expected: \tefgh.c\n actual: \t" << _STRRCHR("0123/2345/4567/6789/8901/0123/2345/4567/6789/abcd/cdef/efgh.c", '/') << endl; | |
cout << "case 2: \n expected: \tabcdcdefefgh.c\n actual: \t" << _STRRCHR("abcdcdefefgh.c", '/') << endl; | |
cout << "case 3: \n expected: \tabcd/cdef/0123456789012345678901234567890.c\n actual: \t" << _STRRCHR("abcd/cdef/0123456789012345678901234567890.c", '/') << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
handle wchar_t[]
fixed sizeof