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, 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.

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_namespace

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) == EOF

Requirements

There are no requirements on macro inlining. Any macro definition may have BRONTO_INLINE_MACRO() applied to it.

Footnotes

  1. Abseil's ABSL_REFACTOR_INLINE annotation is also supported as an alias for BRONTO_INLINE. See it in action on compiler explorer.

On this page