pputl  0.2.1
pputl Preprocessor Utilities
pputl 0.2.1 | Repo | API Docs | CHANGELOG

__ ___
/\ \__/\_ \
_____ _____ __ __\ \ ,_\//\ \
/\ '__`\/\ '__`\/\ \/\ \\ \ \/ \ \ \
\ \ \_\ \ \ \_\ \ \ \_\ \\ \ \_ \_\ \_
\ \ ,__/\ \ ,__/\ \____/ \ \__\/\____\
\ \ \ \ \ \ \/___/ \/__/\/____/
\/_/ \/_/
pputl Preprocessor Utilities

About

pputl is a C++ preprocessor utilities library. It provides basic preprocessor tools
such as concatenation of multiple symbols, control flow, integer manipulation, etc.
It utilizes a reduce mechanism for some of the logic; see below for more info.

Currently, it uses __VA_OPT__, so a supportive compiler is required (or C++20).
Future releases may ship with a build script for generating the project without this requirement.

Requirements

  • C++20 (or __VA_OPT__ support)

Usage

This is a header-only library; include the include/ directory for access.

install

# copies headers to ${DESTDIR}${PREFIX}/include/pputl/
make install

use

#include <pputl/pputl.h>
#define THREE PPUTL_SUM(1, 1, 1)
#if PPUTL_NEQ(THREE, 3)
static_assert(false);
#endif
#define MULTICAT PPUTL_CAT(my, cool, cat) // mycoolcat
#define SUM_REDUCER(accum, val, i) PPUTL_ADD(accum, val)
#define SUM(...) PPUTL_REDUCE(SUM_REDUCER, 0, __VA_ARGS__)
#define SEVEN SUM(1, 2, 4)
// const char *my_cool_string = "my.cool.string";
const char *PPUTL_JOIN_GLUE(_, my, cool, string) =
PPUTL_STRINGIZE(PPUTL_JOIN_DOT(my, cool, string));

Tools

pputl comes with a reduce macro generator in the tools/ folder.
This script generates a set of macros that allow for pseudo-recursive value reduction.
Due to the inability for the preprocessor to recurse (without special, [slow!] expansion logic),
it's necessary to generate a new set of macros if REDUCE call chaining is desired.

Output is sent to stdout.

# node genReduceMacro [NAMESPACE] [PREFIX=REDUCE] [STACK_DEPTH=256] [DETAIL=true]
node tools/genReduceMacro NS REDUCE 4 false # true makes entry macro name NS_DETAIL_REDUCE
#define NS_REDUCE(reducer, initial, ...) \
NS_DETAIL_REDUCE_CHOOSER(__VA_ARGS__) \
(reducer, initial, (0, 1, 2, 3)__VA_OPT__(, ) __VA_ARGS__)
#
#define NS_DETAIL_REDUCE_CAT_X(a, b) a##b
#define NS_DETAIL_REDUCE_CAT(a, b) NS_DETAIL_REDUCE_CAT_X(a, b)
#
#define NS_DETAIL_REDUCE_FIRST(i, ...) i
#define NS_DETAIL_REDUCE_REST(_, ...) __VA_ARGS__
#/* */ // clang-format off
#define NS_DETAIL_REDUCE_0(r, a, is) a
#define NS_DETAIL_REDUCE_1(r, a, is, v) r(a, v, NS_DETAIL_REDUCE_FIRST is)
#define NS_DETAIL_REDUCE_2(r, a, is, v, ...) NS_DETAIL_REDUCE_1(r, r(a, v, NS_DETAIL_REDUCE_FIRST is), (NS_DETAIL_REDUCE_REST is), __VA_ARGS__)
#define NS_DETAIL_REDUCE_3(r, a, is, v, ...) NS_DETAIL_REDUCE_2(r, r(a, v, NS_DETAIL_REDUCE_FIRST is), (NS_DETAIL_REDUCE_REST is), __VA_ARGS__)
#/* */ // clang-format on
#define NS_DETAIL_REDUCE_CHOICE(_3, _2, _1, size, ...) \
NS_DETAIL_REDUCE_CAT(NS_DETAIL_REDUCE_, size)
#
#define NS_DETAIL_REDUCE_CHOOSER(...) \
NS_DETAIL_REDUCE_CHOICE(__VA_ARGS__ __VA_OPT__(, ) 3, 2, 1, 0)

The reducing control flow is capable of perfoming any kind of operation,
but other types (e.g. transform) may be useful. More generation scripts may be added here.

Testing

All API features are statically tested with jpcx/cctest

make -j8 test

Contributing

Contribution is welcome! Please make a pull request.
I'd like to maximize the utility of the preprocessor, especially in the wake of __VA_OPT__.

Documentation

Project documentation is generated by Doxygen and is hosted by GitHub Pages.

pputl.h
Group file for pputl - Contains all library functionality.
PPUTL_JOIN_GLUE
#define PPUTL_JOIN_GLUE(glue,...)
Definition: glue.h:61
PPUTL_STRINGIZE
#define PPUTL_STRINGIZE(...)
Definition: stringize.h:37
PPUTL_JOIN_DOT
#define PPUTL_JOIN_DOT(...)
Definition: dot.h:59