Вот исходный код файла, содержащего библиотечную функцию, как и было обещано;пожалуйста, обязательно прочитайте замечания, которые я сделал ниже, в списках кодов.Еще раз спасибо aaa за помощь в демонстрации того, как инициализировать статический массив с помощью BOOST_PP_ENUM!
Исходный код для xi / mpl / lut.h :
#ifndef __XI_LUT_INCLUDED__
#define __XI_LUT_INCLUDED__
#ifndef __cplusplus
#error The file __FILE__ requires a C++ compiler in order to be successfully compiled.
#endif
#include <boost/mpl/apply.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/multiplies.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#define __XI_LUT_SET_INDEX(z, n, sequence) \
mpl::at_c<sequence, n>::type::value
#define __XI_GENERATE_LUT_IMPL(function, tableType, tableName, tableSize) \
\
template <typename sequence, typename size> \
struct __compileTable_##function##_##tableSize##: \
mpl::if_<mpl::greater<size, mpl::int_<0>>, \
__compileTable_##function##_##tableSize##< \
mpl::push_front<sequence, \
mpl::apply< \
function##<mpl::_>, \
size \
>::type>::type, \
size::prior \
>, \
sequence \
>::type \
{}; \
\
typedef __compileTable_##function##_##tableSize##< \
mpl::vector<>, \
mpl::int_<##tableSize##> \
>::type __compiledTable_##function##_##tableSize##; \
\
static const tableType tableName##[] = { \
BOOST_PP_ENUM( \
tableSize##, \
__XI_LUT_SET_INDEX, \
__compiledTable_##function##_##tableSize## \
) \
}
#define XI_GENERATE_LUT(function, tableType, tableName, tableSize) \
__XI_GENERATE_LUT_IMPL(function, tableType, tableName, tableSize)
#endif
Исходный код для полезного тестового файла:
#include <boost/mpl/greater.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/multiplies.hpp>
#include <boost/mpl/placeholders.hpp>
#include <cstdio>
#include <xi/mpl/lut.hpp>
namespace mpl = boost::mpl;
template <typename x>
struct factorial:
mpl::if_<mpl::greater<x, mpl::int_<1>>,
mpl::multiplies<x, factorial<x::prior>>,
mpl::int_<1>
>::type
{};
XI_GENERATE_LUT(factorial, int, FACTORIAL_TABLE, 4);
int main(int argc, char ** argv) {
// This should print '24:'
printf("Result: %d.\n", FACTORIAL_TABLE[3]);
return 0;
}
Я пока воздержусь от предоставления URL-адреса файла, чтобы продолжить редактирование списка кода.Я уверен, что код можно улучшить в целях совместимости, поэтому он определенно не находится в конечном состоянии.Вот некоторые известные проблемы:
- Код не будет компилироваться в MSVC 9.0.
- Попытка создать таблицу поиска определенного размера для имени метафункции после того, как она уже была созданаодного и того же размера и для одного и того же имени метафункции приведет к ошибке, поскольку для этих параметров будут определены соответствующие типы и шаблоны.Я не хочу использовать
__COUNTER__
для решения этой проблемы, поскольку это нестандартное макроопределение.
Я не пробовал компилировать этот код на других компиляторах, кроме ICC и MSCV, ихотел бы знать, как GCC справляется с этим - пожалуйста, дайте мне знать о любых проблемах, которые возникают, чтобы можно было принять правильное решение.Я опубликую URL-адрес файла, как только код заработает без проблем на большинстве основных компиляторов.Любая обратная связь будет принята с благодарностью!