Цикл препроцессора по последовательности заголовочных файлов

Можно ли включить последовательность файлов: file1,file2,file3 в цикл препроцессора?

#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/cat.hpp>

// needed whitespace here----*
#define BOOST_PP_LOCAL_LIMITS (1, 3)

#define GENERATE_FILE_NAME(n) \
   BOOST_PP_STRINGIZE( BOOST_PP_CAT( file , n) ) \
   /**/

#define BOOST_PP_LOCAL_MACRO(n) \
    #include GENERATE_FILE_NAME(n) \

а затем использовать его с:

#include BOOST_PP_LOCAL_ITERATE()

следует расширить до

BOOST_PP_LOCAL_MACRO(1) --> includes file1
BOOST_PP_LOCAL_MACRO(2) --> includes file2
BOOST_PP_LOCAL_MACRO(3) --> includes file3

К сожалению, вышеуказанное не работает из-за #include GENERATE_FILE_NAME(n) в макросе, который не расширяется...

Это вообще возможно?

Комментарий:
Я разместил этот вопрос, потому что мне было интересно, возможно ли это вообще. Я решил свою проблему, включив только один файл, который был сгенерирован из всех файлов file1 file2 file3. Я столкнулся с этим, потому что иногда можно генерировать большие последовательности включаемых файлов (которые не следует объединять только из-за удобочитаемости), и я не был уверен, как включить все это без явного написания всех имен файлов, поэтому я подумал о циклах препроцессора, которые конечно, уродливее, чем мое решение до сих пор :-), но оно красивее :-)


person Gabriel    schedule 18.12.2013    source источник
comment
В зависимости от ситуации может быть лучше автоматически создать файл заголовка, который включает все эти заголовки, а затем включить только этот автоматически созданный файл заголовка.   -  person Some programmer dude    schedule 18.12.2013
comment
Я мог бы придумать несколько вариантов использования, если бы вы также могли объединить индекс цикла в определения   -  person Leeor    schedule 18.12.2013
comment
Я думаю, что это было бы сложно, поскольку стандарты C и C++ имеют эту формулировку в своих пунктах о повторном сканировании во время замены макроса. Результирующая последовательность токенов предварительной обработки, полностью замененная макросом, не обрабатывается как директива предварительной обработки, даже если она похожа на таковую. Тем не менее, я видел некоторые очень удивительные методы, используемые с препроцессором, поэтому я не настолько смел, чтобы сказать, что это невозможно.   -  person Michael Burr    schedule 18.12.2013
comment
Я использую это для создания некоторого кода в цикле BOOST_PP_LOCAL_MACRO (более сложном, чем приведенный выше), который затем включает один файл за другим.   -  person Gabriel    schedule 18.12.2013
comment
Что касается вопроса Джонатана, вы можете прочитать о проблеме XY. Вы только предоставляете нам решение, которое хотите использовать, но не говорите нам, какую проблему вы пытаетесь решить. Могут быть другие или даже лучшие решения.   -  person Some programmer dude    schedule 18.12.2013
comment
Нужно ли делать это с помощью препроцессора или лучше иметь работающий сценарий предварительной сборки?   -  person user2711915    schedule 18.12.2013
comment
C++ и C имеют #define макросов с разными возможностями. Вы ищете решение C или решение C++? На данный момент я удалю тег C.   -  person Sebastian Mach    schedule 18.12.2013
comment
Хорошо, я разместил этот вопрос, потому что мне было интересно, возможно ли это вообще. Я решил свою проблему, включив только один файл, который был создан из всех файлов file1 file2 file3. Я столкнулся с этим, потому что иногда хотелось бы сгенерировать большие последовательности включаемых файлов (которые не должны быть объединены только из-за удобочитаемости), и я не знал, как включить все это без явного написания всех имен файлов, поэтому я подумал о циклах препроцессора. , что, конечно, уродливее, чем мое решение до сих пор :-), но оно красивее :-)   -  person Gabriel    schedule 19.12.2013


Ответы (1)


Это работает с g++:

Наличие препроцессора каталога в пути включения и этот include_range.h:

#if !BOOST_PP_IS_ITERATING

#ifndef INCLUDE_RANGE_PREFIX
    #error Missing INCLUDE_RANGE_PREFIX
#endif
#ifndef INCLUDE_RANGE_MIN
    #error Missing INCLUDE_RANGE_MIN
#endif
#ifndef INCLUDE_RANGE_MAX
    #error Missing INCLUDE_RANGE_MAX
#endif

#include <boost/preprocessor/iteration/iterate.hpp>

#define BOOST_PP_ITERATION_PARAMS_1 (3, \
    (INCLUDE_RANGE_MIN, INCLUDE_RANGE_MAX, <preprocessor/include_range.h>))
#include BOOST_PP_ITERATE()

#else

#define INCLUDE_RANGE_PATH_SUFFIX(F, N) F##N
#define INCLUDE_RANGE_PATH(F, N) <INCLUDE_RANGE_PATH_SUFFIX(F, N)>
#include INCLUDE_RANGE_PATH(INCLUDE_RANGE_PREFIX, BOOST_PP_ITERATION())

#if BOOST_PP_ITERATION_DEPTH() == INCLUDE_RANGE_MAX - INCLUDE_RANGE_MIN + 1
    #undef INCLUDE_RANGE_PREFIX
    #undef INCLUDE_RANGE_MIN
    #undef INCLUDE_RANGE_MAX
#endif

#endif

Вы можете включить ряд файлов (файл2, файл3, файл4):

#define INCLUDE_RANGE_PREFIX file
#define INCLUDE_RANGE_MIN 2
#define INCLUDE_RANGE_MAX 4
#include <preprocessor/include_range.h>

Ограничение: файлы находятся в пути включения.

person Community    schedule 18.12.2013
comment
Не могли бы вы уточнить, что здесь происходит, я вижу некоторые рекурсивные #include INCLUDE_RANGE_PATH(INCLUDE_RANGE_PREFIX, BOOST_PP_ITERATION()) - person Gabriel; 19.12.2013
comment
@Gabriel Это #include INCLUDE_RANGE_PATH ... не является рекурсивным, это просто оценка результата #include BOOST_PP_ITERATE() - person ; 19.12.2013