Boost.MPL 和类型列表生成

2024-04-27

背景

这是用于游戏引擎中的内存管理器。我有一个freelist已实现,并且希望有一个编译时列表(如果有)。 (例如,MPL 或 Fusion 向量)。这freelist对应于分配大小,当分配/释放大小小于常量的对象时,它们将转到相应的freelist.

最后,这意味着全局小对象已经摊销了常量时间分配和常量时间释放。 (耶。)

Problem

问题是生成我需要的类型,因此我最终可能会使用 Fusion 来实例化这些类型。使用的类型有(缩短等):

template <size_t N>
struct data_block
{
    size_t mSize; // = N
    char mData[N];
};

template <typename T, size_t ElementsPerPage,
    template <typename> class Allocator = std::allocator >
class freelist { /* ... */ };

template <typename T>
class callocator; // allocator that uses malloc/free

The freelist的意志管理data_block的 2 次幂大小,从最小值开始到最大值。所以我想要的是:

static const size_t MinimumSmallSize = 4; // anything smaller gets rounded up
static const size_t MaximumSmallSize = 512; // anything bigger goes to the large allocator
static const size_t ElementsPerPage = 4096;

// mpl magic

要生成这个:

typedef boost::mpl::vector<
    freelist<data_block<4>, ElementsPerPage, callocator>,
    freelist<data_block<8>, ElementsPerPage, callocator>
    // ...
    freelist<data_block<256>, ElementsPerPage, callocator>
    freelist<data_block<512>, ElementsPerPage, callocator>
    > free_list_collection;

显然,我可以手动完成此操作,但我宁愿避免这样做,以获得更通用和可调整的界面。在代码中使用 Fusion 向量也应该比硬编码成员更简单。

Question

我不确定解决这个问题的最佳方法;我以前从未广泛使用过 MPL。有任何想法吗?我有一些糟糕的想法,比如制定一个范围,然后remove_if它不是 2 的幂等,但肯定不是最好的。也许是递归的东西,每次都会加倍,推入我的结果向量?我不知道该怎么做。


这是我想出的最好的解决方案,而且相当简单。它需要一个log and pow元模板,我为那些想要玩或尝试的人提供了它:

#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
#include <iostream>

namespace bmpl = boost::mpl;

//// helpers
template <size_t N, size_t Base>
struct log
{
    static const size_t value = 1 + log<N / Base, Base>::value;
};

template <size_t Base>
struct log<1, Base>
{
    static const size_t value = 0;
};

template <size_t Base>
struct log<0, Base>
{
    static const size_t value = 0;
};

template <size_t N, size_t Power>
struct pow
{
    static const size_t value = N * pow<N, Power - 1>::value;
};

template <size_t N>
struct pow<N, 0>
{
    static const size_t value = 1;
};

//// types and constants
template <size_t N>
struct data_block
{
    size_t mSize; // = N
    char mData[N];
};

template <typename T, size_t ElementsPerPage,
    template <typename> class Allocator = std::allocator >
class freelist { /* ... */ };

template <typename T>
class callocator; // allocator that uses malloc/free

static const size_t MinimumSmallSize = 4;
static const size_t MaximumSmallSize = 512;
static const size_t ElementsPerPage = 4096;

//// type generation
// turn a power into a freelist
template <typename T>
struct make_freelist
{
    static const size_t DataSize = pow<2, T::value>::value;
    typedef data_block<DataSize> data_type;

    typedef freelist<data_type, ElementsPerPage, callocator> type;
};

// list of powers
typedef bmpl::range_c<size_t, log<MinimumSmallSize, 2>::value,
                        log<MaximumSmallSize, 2>::value + 1> size_range_powers;

// transform that list into freelists, into a vector
typedef bmpl::transform<size_range_powers, make_freelist<bmpl::_1>,
                            bmpl::back_inserter<bmpl::vector<> > >::type size_range;

//// testing
struct print_type
{
    template <typename T>
    void operator()(const T&) const
    {
        std::cout << typeid(T).name() << "\n";
    }
};

int main(void)
{
    bmpl::for_each<size_range>(print_type());
    std::cout << std::endl;
}

它的核心只是一个struct和两个typedef's. The log技巧大大缩小了范围的大小,并且pow当然只是撤消log。完全按照我想要的方式工作,而且我看不出有任何方法可以使它更简单。

也就是说,我决定使用 Boost.Pool,所以我不需要我的解决方案(因为它们的池大小是动态的,而不是编译时的。)但这很有趣。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Boost.MPL 和类型列表生成 的相关文章

  • 什么定义了类型的大小?

    ISO C 标准规定 sizeof char lt sizeof short lt sizeof int lt sizeof long 我在 BIT Linux mint 19 1 上使用 GCC 8 大小为long int is 8 我正
  • 我的 std::hash for std::tuples...有什么改进吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有些人可能已经注意到 std hash 不支持元组 所以我添加了一个重载 它看起来比我到目前为止看到的解决方案 更好 有人有进一步减少这段代码的
  • Boost MPI 在监听列表时不会释放资源?

    这是一个后续问题如何释放 boost mpi request https stackoverflow com questions 44078901 how do i free a boostmpirequest 我在监听列表而不是单个项目时
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • Winform DatagridView 数字列排序

    我只使用一个简单的 DataGridView 来保存一堆数据 有趣的是 我在特定列中有小数 但是当按小数列排序时 它的排序是错误的 例如 起始顺序可能是 0 56 3 45 500 89 20078 90 1 56 100 29 2 39
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • 选择initializer_list迭代器定义

    Why std initializer list
  • 从内存流播放视频文件

    只是好奇看看这是否可能 我有一个 Windows 应用程序 它从我的电脑上的 avi 文件读取所有字节 然后将其存储在 byte 中 现在我的内存中有 avi 文件 我想直接从内存将其加载到某种视频播放器控件中 我尝试过使用 wmplaye
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • 如何在 Visual Basic DLL 和 C++ DLL 之间创建隔离/免注册 COM?

    我必须在 C DLL 中使用 VB COM DLL 我弄清楚了如何从 C DLL 访问 VB COM DLL 并且它可以工作 现在我遇到了一个问题 我必须使用隔离的 COM 免注册 COM 因为我无法在必须使用它的每台 PC 上注册 DLL
  • 为什么 BinaryFormatter 可以序列化 Action<> 但 Json.net 不能

    尝试序列化 反序列化 Action 尝试我的 1天真 JsonConvert SerializeObject myAction JsonConvert Deserialize
  • FluentAssertions ShouldNotThrow 无法识别异步方法/Func

    我正在尝试检查异步方法是否抛出具体异常 为此 我使用 MSTEST 和 FluentAssertions 2 0 1 我已经检查过这个关于 Codeplex 的讨论 http fluentassertions codeplex com wo
  • ASP.net WebForms - 在标记中使用 GetRouteUrl

    我一直在尝试弄清楚如何将路由功能与 ASP net 4 0 WebForms 一起使用 我将一条路线添加到我的路线集合中 void Application Start RegisterRoutes RouteTable Routes voi
  • 如何禁用基于 ValidationRule 类的按钮?

    如何禁用基于 ValidationRule 类的 WPF 按钮 下面的代码可以很好地突出显示 TextBox
  • 在 C# .NET 中对非 ASCII 字符进行编码

    我想向我的应用程序发送的电子邮件添加自定义标头 标头名称只能包含 ASCII 字符 但对于值和用户可能会输入 UTF 8 字符 我必须对它们进行 Base64 编码 此外 我还必须将它们解码回 UTF 8 以便在 UI 中向用户显示它们 最
  • 意外的 const 引用行为

    include
  • 为什么 C++ 标准没有将 sizeof(bool) 定义为 1?

    Size of char signed char and unsigned char由 C 标准本身定义为 1 个字节 我想知道为什么它没有定义sizeof bool also C 03 标准 5 3 3 1 说 sizeof char s
  • Unity - 在生成时获取随机颜色

    我有一个小问题 我想在我的场景中生成四边形 它们都应该有红色或绿色作为材质 但 Random Range 函数只能是 int 我该如何解决它 void SpawningSquadsRnd rndColor 0 Color red rndCo
  • 如何根据当前日期时间发现财政年度?

    我需要基于当前或今天的日期时间的财政年度 假设我们认为今天的日期是10 April 2011 那么我需要输出为Financial Year 2012在某些情况下 我需要以短格式显示相同的输出FY12 我想以两种方式显示 在我们的要求中 考虑

随机推荐