В предыдущей статье такое приведение правил ANSI-UNICODE я уже делал. Теперь я хочу показать, к чему это все привело.
Для начала стоит отметить, что с переходом на vs2010 макросы уже не принимают отсутствие каких-либо идентификаторов между запятыми. Следовательно, набор этих правил приходится адаптировать.
Я посчитал нужным ввести некоторые обозначения трансляции:
u - основной признак трансляции (unicode)
l - задан только левый фрагмент текста трансляции (left)
r - задан только правый фрагмент текста трансляции (right)
t - трансляция шаблона или какой-либо его специализации (template)
a - задан только ANSI-фрагмент (ansi)
u - задан только UNICODE-фрагмент (unicode) [да, все верно, еще один u]
таким образом, мы можем сформировать общий набор правил трансляции:
uru() - добавить UNICODE-префикс, т.е. имеем правую часть какого-то текста, к которой слева нужно добавить UNICODE-фрагмент, для ANSI текст оставить без левой части, например:
предотвратить его поломку помогут макросы с модификатором t ( ut, utru, utl и т.п. )
utl() - аналог ul только с возможностью добавления параметров шаблона, например:
Для начала стоит отметить, что с переходом на vs2010 макросы уже не принимают отсутствие каких-либо идентификаторов между запятыми. Следовательно, набор этих правил приходится адаптировать.
Я посчитал нужным ввести некоторые обозначения трансляции:
u - основной признак трансляции (unicode)
l - задан только левый фрагмент текста трансляции (left)
r - задан только правый фрагмент текста трансляции (right)
t - трансляция шаблона или какой-либо его специализации (template)
a - задан только ANSI-фрагмент (ansi)
u - задан только UNICODE-фрагмент (unicode) [да, все верно, еще один u]
таким образом, мы можем сформировать общий набор правил трансляции:
#ifndef UNICODE #define u( left, right, ansi, unicode ) left ## ansi ## right #define ua( left, right, ansi ) left ## ansi ## right #define uu( left, right, unicode ) left ## right #define ul( left, ansi, unicode ) left ## ansi #define ula( left, ansi ) left ## ansi #define ulu( left, unicode ) left #define ur( right, ansi, unicode ) ansi ## right #define ura( right, ansi ) ansi ## right #define uru( right, unicode ) right #define ut( left, right, ansi, unicode, ... ) left ## ansi ## right < __VA_ARGS__ > #define uta( left, right, ansi, ... ) left ## ansi ## right < __VA_ARGS__ > #define utu( left, right, unicode, ... ) left ## right < __VA_ARGS__ > #define utl( left, ansi, unicode, ... ) left ## ansi < __VA_ARGS__ > #define utla( left, ansi, ... ) left ## ansi < __VA_ARGS__ > #define utlu( left, unicode, ... ) left < __VA_ARGS__ > #define utr( right, ansi, unicode, ... ) ansi ## right < __VA_ARGS__ > #define utra( right, ansi, ... ) ansi ## right < __VA_ARGS__ > #define utru( right, unicode, ... ) right < __VA_ARGS__ > #else #define u( left, right, ansi, unicode ) left ## unicode ## right #define ua( left, right, ansi ) left ## right #define uu( left, right, unicode ) left ## unicode ## right #define ul( left, ansi, unicode ) left ## unicode #define ula( left, ansi ) left #define ulu( left, unicode ) left ## unicode #define ur( right, ansi, unicode ) unicode ## right #define ura( right, ansi ) right #define uru( right, unicode ) unicode ## right #define ut( left, right, ansi, unicode, ... ) left ## unicode ## right < __VA_ARGS__ > #define uta( left, right, ansi, ... ) left ## right < __VA_ARGS__ > #define utu( left, right, unicode, ... ) left ## unicode ## right < __VA_ARGS__ > #define utl( left, ansi, unicode, ... ) left ## unicode < __VA_ARGS__ > #define utla( left, ansi, ... ) left < __VA_ARGS__ > #define utlu( left, unicode, ... ) left ## unicode < __VA_ARGS__ > #define utr( right, ansi, unicode, ... ) unicode ## right < __VA_ARGS__ > #define utra( right, ansi, ... ) right < __VA_ARGS__ > #define utru( right, unicode, ... ) unicode ## right < __VA_ARGS__ > #endifкаждый макрос очень просто расшифровывается, а набор их параметров следует строго из названия, например:
uru() - добавить UNICODE-префикс, т.е. имеем правую часть какого-то текста, к которой слева нужно добавить UNICODE-фрагмент, для ANSI текст оставить без левой части, например:
uru( CHAR, W ); //транслирует CHAR и WCHAR; uru( "текст", L ); //транслирует "текст" и L"текст", неожиданно, да? :))ul() - добавить соответствующий кодировке постфикс, т.е. имеем левую часть какого-то текста, к которой нужно добавить фрагмент справа, например:
ul( SendMessage, A, W ); //транслирует SendMessageA и SendMessageW ul( LOGFONT, A, W ); //транслирует LOGFONTA и LOGFONTWur() - добавить соответствующий кодировке префикс, т.е. имеем правую часть какого-то текста, к которой нужно добавить фрагмент слева, например:
ur( len, str, wcs ); //транслирует strlen и wcslenuu() - добавить UNICODE-инфикс, т.е. имеем левую и правую части какого-то текста, между которыми нужно добавить фрагмент, например:
uu( _sc, printf, w ); //транслирует _scprintf и _scwprintf uu( _, icmp, str, wcs ); //транслирует _stricmp и _wcsicmpввод шаблонов в эти правила, с точки зрения грамматики не требуется, но особенности реализации редакторов исходного кода в visual studio пока не могут полноценно раскрывать код внутри макроса, поэтому при их использовании в шаблонах, ломается сode folding
предотвратить его поломку помогут макросы с модификатором t ( ut, utru, utl и т.п. )
utl() - аналог ul только с возможностью добавления параметров шаблона, например:
utl( MyClass, A, W, X, Y, Z ); //транслирует MyClassAНа самом деле, я уже достаточно долго работаю с этим инструментом и успел оценить его плюсы и минусы, а чтобы в дальнейшем, при встрече с такими u-макросами можно было предметно обсуждать насущные темы, я буду обращаться к ним с помощью простой и, на мой взгляд, очевидной терминологии: u-логика или u-макроси MyClassW< X, Y, Z >
Комментариев нет:
Отправить комментарий