2016-10-03 3 views
1

Если у меня есть последовательность препроцессора такой, чтоМожет препроцессор определить тип

FOO((TEST, (BAR,BAZ)), 
    (TEST2, 25, (BART, BAC) 
    ) 

Есть ли способ, чтобы определить, что в первом аргументе второй элемент представляет собой кортеж, в то время как во втором аргументе второй элемент число?

первый аргумент, второй элемент = (BAR, BAZ) второй аргумент, второй элемент = 25

Я использую повысить препроцессора. Я понимаю, что просто стандартизация операций проще всего. Тем не менее, мне любопытно, возможно ли препроцессор определить типы и вернуть эту информацию мне полезным способом.

ответ

1

Вы можете использовать Boost.VMD (доступный с Boost 1.60) для достижения желаемого. Он имеет несколько макросов, которые определяют тип элемента (BOOST_VMD_IS_TUPLE, BOOST_VMD_IS_SEQ, BOOST_VMD_IS_NUMBER, ...). Для этой библиотеки требуется достаточно современный компилятор с поддержкой переменных массивов. Here пример, который печатает «тип» второго элемента кортежа вы передаете:

#include <iostream> 
#include <boost/preprocessor.hpp> 
#include <boost/vmd/is_tuple.hpp> 
#include <boost/vmd/is_number.hpp> 

#define IT_IS_A_TUPLE(TUPLE) BOOST_PP_STRINGIZE(TUPLE) " is a tuple" 
#define IT_IS_NOT_A_TUPLE(ARG) BOOST_PP_STRINGIZE(ARG) " is something else" 

#define IT_IS_A_NUMBER(NUMBER) BOOST_PP_STRINGIZE(NUMBER) " is a number" 
#define IT_IS_NOT_A_NUMBER(ARG) BOOST_PP_IIF(BOOST_VMD_IS_TUPLE(ARG),IT_IS_A_TUPLE,IT_IS_NOT_A_TUPLE)(ARG) 

#define DESCRIBE_ARGUMENT(ARG) BOOST_PP_IIF(BOOST_VMD_IS_NUMBER(ARG),IT_IS_A_NUMBER,IT_IS_NOT_A_NUMBER)(ARG) 
#define FOO(TUPLE) DESCRIBE_ARGUMENT(BOOST_PP_TUPLE_ELEM(1,TUPLE)) 

int main() 
{ 
    std::cout << FOO((TEST, (BAR,BAZ))) << std::endl; 
    std::cout << FOO((TEST2, 25, (BART, BAC))) << std::endl; 
} 

Another example использованием BOOST_VMD_GET_TYPE:

#include <iostream> 
#include <boost/preprocessor.hpp> 
#include <boost/vmd/get_type.hpp> 


#define WHEN_ARG_IS_A_BOOST_VMD_TYPE_TUPLE(TUPLE) BOOST_PP_STRINGIZE(TUPLE) " is a tuple" 

#define WHEN_ARG_IS_A_BOOST_VMD_TYPE_NUMBER(NUMBER) BOOST_PP_STRINGIZE(NUMBER) " is a number" 

#define WHEN_ARG_IS_A_BOOST_VMD_TYPE_SEQ(SEQ) BOOST_PP_STRINGIZE(SEQ) " is a sequence" 

#define DESCRIBE_ARGUMENT(ARG) BOOST_PP_EXPAND(BOOST_PP_CAT(WHEN_ARG_IS_A_,BOOST_VMD_GET_TYPE(ARG))(ARG)) 
#define FOO(TUPLE) DESCRIBE_ARGUMENT(BOOST_PP_TUPLE_ELEM(1,TUPLE)) 

int main() 
{ 
    std::cout << FOO((TEST, (BAR,BAZ))) << std::endl; 
    std::cout << FOO((TEST2, 25, (BART, BAC))) << std::endl; 
    std::cout << FOO((TEST3,(BAR)(BAZ),(BAR,BAZ))) << std::endl; 
} 
Смежные вопросы