在编译时生成模板参数

Sam*_*all 5 c++ embedded c-preprocessor c++11

我创建了一个看起来像数组的类,但它不是将数据保存在程序本身中,而是从文件中流出字节(以减少RAM影响).现在我已经完成了所有这些工作,但程序员必须使用以下方法定义类:

#define CreateReadOnlyBlock(name, location, size, ...)          \
template<>                                                      \
const unsigned int ReadOnlyBlock<location, size>::Data[]        \
    __asm__( ".readonly__" #location "__" #name)                \
    = { __VA_ARGS__ };                                          \
ReadOnlyBlock<location, size> name;
Run Code Online (Sandbox Code Playgroud)

例:

//A read only array of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray, 0, 4, 0, 1, 2, 3); 
Run Code Online (Sandbox Code Playgroud)

请注意,这是针对嵌入式处理器的,并且asm指令通过汇编程序中的工具来创建只读文件.

所以这是我的问题:如何消除"位置"和"大小"变量?我讨厌程序员必须手动输入,并且更喜欢在编译时生成这些的方法.所以代替程序员需要输入:

//A read only array at location 0 of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray1, 0, 4, 0, 1, 2, 3); 
//A read only array at location 4 of {4, 5, 6, 7}
CreateReadOnlyBlock(readOnlyArray2, 4, 4, 4, 5, 6, 7); 
Run Code Online (Sandbox Code Playgroud)

他们可以输入:

CreateReadOnlyBlock(readOnlyArray1, 0, 1, 2, 3); 
CreateReadOnlyBlock(readOnlyArray2, 4, 5, 6, 7); 
Run Code Online (Sandbox Code Playgroud)

并且将生成适当的常量.基本上我正在寻找一些方法来生成和放置这些常量在编译时基于以前的定义.C++ 11是公平的游戏,我对它并不十分熟悉(constexpr的东西看似合理吗?).此外,C-Preprocessor也可以,如果它没有比现在更丑陋.这可能吗?

为清晰起见编辑:

在ReadOnlyBlock类中有这个方法:

    template<const int _location, const int _size> class ReadOnlyBlock
    {
        ...
        unsigned int operator[] (size_t index)
        {
            return LoadFromROM(index + _location);
        }
    }
Run Code Online (Sandbox Code Playgroud)

位置变量和ROM文件之间存在内在的相互依赖性,我无法想到如何破解.我这样做有过的工具链完整的控制中,但是,但是我需要一种方法来通过汇编工具如何构建文件以及指示C++代码,其中块所在的文件中.

另一个编辑:

文件及其块可能非常大,多达1k字,因此很多预处理器魔法可能会崩溃.另外,感谢大家到目前为止的帮助!

Dan*_*rey 1

我仍然没有看到生成名称(该#location片段)的完整解决方案,但对于其余部分,我想您可以使用如下所示的方法:

template< std::size_t Line >
struct current_location : current_location< Line - 1 > {};

template<>
struct current_location< 0 > : std::integral_constant< std::size_t, 0 > {};

#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))

#define CreateReadOnlyBlock(name, ...)                          \
template<>                                                      \
const unsigned int ReadOnlyBlock<                               \
    current_location<__LINE__-1>::value, NUMARGS(__VA_ARGS__)   \
>::Data[]                                                       \
    __asm__( ".readonly__" #name)                               \
    = { __VA_ARGS__ };                                          \
ReadOnlyBlock<current_location<__LINE__-1>::value,              \
              NUMARGS(__VA_ARGS__)> name;                       \
template<>                                                      \
struct current_location<__LINE__>                               \
    : std::integral_constant<std::size_t,                       \
        current_location<__LINE__-1>::value+NUMARGS(__VA_ARGS__)> \
{};
Run Code Online (Sandbox Code Playgroud)