Skip to content

Instantly share code, notes, and snippets.

@ipid
Last active May 30, 2019 10:58
Show Gist options
  • Save ipid/65a0a3f8b9fa6de05ee8f782b9a6a81c to your computer and use it in GitHub Desktop.
Save ipid/65a0a3f8b9fa6de05ee8f782b9a6a81c to your computer and use it in GitHub Desktop.
Define variables on the heap but use them like stack variables. Heap variables have never been so simple to use.
#pragma once
#ifndef HEAP_VAR_HPP
#define HEAP_VAR_HPP
/*
Introduction:
In order not to cause a stack overflow, sometimes you must define
large objects on the heap. But heap variables are somewhat hard to use.
Macro `HEAP_VARS` defines multiple variables on the heap,
but you can use them like stack variables.
To define heap variable with constructor parameters,
use macro `HEAP_VAR`, which defines only one heap variable.
NOTE: Require C++17 support.
Usage:
Define variable `a` and `b` of type VeryLargeClass:
> HEAP_VARS(VeryLargeClass, a, b);
Define variable `v` of type VeryLargeClass with constructor params:
> HEAP_VAR(VeryLargeClass, v, param1, param2);
Variable `a`, `b` and `v` are allocated on the heap,
but you can use them just like they were defined on the stack:
> a.someProperty = someValue; // property assignment
> cout << &b << endl; // get address
> v.method(); // calling method
These variables are allocated with std::unique_ptr and
automatically deleted at the end of scope. You don't have to delete them.
介绍:
为了不爆栈,有时候您得把一些大的对象分配在堆上,
但是堆上的对象或多或少有点麻烦,难以使用。
本文件提供的 HEAP_VARS 宏可以让您将多个变量定义在堆上,
但是用起来就和栈变量一样简单。
如果定义堆上变量时需要给构造函数传入参数,
可以使用 HEAP_VAR 宏,它只能创建一个变量。
注:需要 C++17 支持。
用法:
定义 VeryLargeClass 类型的变量 a 和 b:
> HEAP_VARS(VeryLargeClass, a, b);
定义 VeryLargeClass 类型的变量 v,同时给构造函数传入参数:
> HEAP_VAR(VeryLargeClass, v, param1, param2);
变量 a、b 和 v 分配在堆上,
但是用起来就像是栈上的变量一样:
> a.someProperty = someValue; // 属性赋值
> cout << &a << endl; // 取地址
> v.method(); // 调用方法
这些变量是用 std::unique_ptr 来分配的,它们在
作用域外就会被自动释放,所以你不需要手动 delete 它们。
*/
#ifndef __cpp_structured_bindings
#error heap_var.hpp only supports C++17 or higher. Please enable C++17 in your compiler.
#endif
#if defined(HEAP_VAR) || defined(HEAP_VARS)
#error The macro HEAP_VAR(S) provided by heap_var.hpp conflicts with other macros. heap_var.hpp can not work.
#endif
#if defined(HEAP_VAR__TOKENPASTE) || defined(HEAP_VAR__TOKENPASTE_HELPER)
#error The internal macros used by heap_var.hpp conflicts with other macros. heap_var.hpp can not work.
#endif
#include <memory>
#define HEAP_VAR__TOKENPASTE_HELPER(name, arg) name##arg
#define HEAP_VAR__TOKENPASTE(name, arg) HEAP_VAR__TOKENPASTE_HELPER(name, arg)
/*
Define variables of type `VarType`, using them like stack variables.
Usage:
HEAP_VARS(VeryLargeClass, a, b);
*/
#define HEAP_VARS(VarType, ...) \
struct HEAP_VAR__TOKENPASTE(HEAP_VAR__HelperType, __LINE__) { \
VarType __VA_ARGS__; \
}; \
\
auto HEAP_VAR__TOKENPASTE(HEAP_VAR__vars_pool, __LINE__) = std::make_unique<HEAP_VAR__TOKENPASTE(HEAP_VAR__HelperType, __LINE__)>(); \
auto& [__VA_ARGS__] = *HEAP_VAR__TOKENPASTE(HEAP_VAR__vars_pool, __LINE__)
/*
Define single variable of type `VarType`, using it like stack variables.
Usage:
HEAP_VAR(VeryLargeClass, cls_obj, param1, param2);
*/
#define HEAP_VAR(VarType, var_name, ...) \
auto HEAP_VAR__TOKENPASTE(HEAP_VAR__var_pool, __LINE__) = std::make_unique<VarType>(__VA_ARGS__); \
VarType& var_name = *HEAP_VAR__TOKENPASTE(HEAP_VAR__var_pool, __LINE__)
#endif // HEAP_VAR_HPP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment