Inlining
Function inlining
Attaching the BRONTO_INLINE() attribute to a function indicates that calls to
the function should be replaced with the expression in the function's body.1
class Container {
public:
bool empty() const { ... }
...
};
// Deprecated. Use the `empty` member function instead.
BRONTO_INLINE()
bool IsEmpty(const Container& c) {
return c.empty();
}Requirements
For a function to be inlined, it must either
- have an empty body,
- have a single return statement (and no other statements), or
- have a single statement which is an expression.
Constructor inlining
Attaching the BRONTO_INLINE() attribute to a delegating constructor indicates
that constructions invoking that constructor should be replaced with the
delegated-to constructor. This should feel similar to
function inlining, as constructors are very nearly
functions.
class Interval {
public:
BRONTO_INLINE()
Interval(double lower, double upper)
: Interval(make(lower, upper).value()) {}
static std::expected<Interval, InvalidIntervalError> make(
double lower, double upper) {
if (lower > upper) { return std::nullopt; }
Interval i;
i.lower_ = lower;
i.upper_ = upper;
return i;
}
...
};Requirements
For a constructor to be inlined, it must delegate to another constructor of the same type and otherwise have an empty body.
Type inlining
Attaching the BRONTO_INLINE() to a type alias indicates that uses of the alias
should be replaced by the aliased type. This should also feel similar to
function inlining, but at the type-level, rather than
expression-level.
template <typename T, typename U>
using PtrPair BRONTO_INLINE() = std::pair<T*, U*>;Requirements
For a type alias to be inlined it must not have variadic or non-type template parameters.
Enumerator inlining
Attaching the BRONTO_INLINE() attribute to an enumerator indicates that uses
of that enumerator should be replaced with its initializing expression. This
should feel similar to function inlining, but at the
expression level for named constants.
enum Color {
Red,
Green,
Cerulean,
Blue BRONTO_INLINE() = Cerulean
};You can see an example live on Compiler Explorer.
Requirements
For an enumerator to be inlined, it must have an explicit initializer. Enumerators dependent on template parameters are not currently supported.
Namespace inlining
Attaching the BRONTO_INLINE() to a using directive indicates that any symbol
found through the using directive should be qualified with the named
namespace.
For example, one could
add std qualifications via
BRONTO_INLINE() using namespace std;or rename a namespace with
namespace new_namespace {
BRONTO_INLINE() using namespace old_namespace;
} // new_namespaceExample use cases
Requirements
There are no requirements on using directives. Any using directive may have
BRONTO_INLINE() applied to it.
Macro inlining
Defining a macro whose initial tokens are BRONTO_INLINE_MACRO() indicates that
the subsequent macro body should be directly inserted into expansion sites. Only
a single level of expansion will be inlined; any macros present in the inlined
macro body will be written as-is, rather than recursively expanded. Macros will
only be inlined if they are written directly in the source text and not if they
are encountered during expansion of another macro.
#define IS_EOF(ch) BRONTO_INLINE_MACRO() (ch) == EOFRequirements
There are no requirements on macro inlining. Any macro definition may have
BRONTO_INLINE_MACRO() applied to it.
Footnotes
-
Abseil's
ABSL_REFACTOR_INLINEannotation is also supported as an alias forBRONTO_INLINE. See it in action on compiler explorer. ↩