Is it possible to have stringification after numeric evaluation?
This is better explained with a simple example:
#define A 1
#define B 2
#define SUM (A + B)
#define STR_IMPL_(x) #x
#define STR(x) STR_IMPL_(x)
char *sum = STR(SUM);
As written this generates the single line:
char *sum = "(1 + 2)";
Is it possible, somehow, to generate char *sum = "3"; instead?
I suspect this is not possible because CPP is a purely text processor (altough it can do arithmetic, at least in conditionals), but I might have overlooked something.
Yes. For reference here are some specific definitions I'll use:
Arithmetic approach
Given these definitions, macro expansions cannot evaluate expressions, but they can perform arithmetic. Instead of the operators you would use macros, each of which would implement arithmetic from scratch. Here's a boost pp usage using this approach:
Demo
With this approach, you get to simply expand a macro to a result; that result can then be stringified. But you're implementing arithmetic itself in macros as opposed to operators, and that takes a lot of macros. So to pull this off, either your number ranges need to be severely limited, or you need to use numbers that are decomposable to macro evaluation (e.g., represent 20000 as
(2,0,0,0,0)as opposed to20000). Boost pp arithmetic uses the former approach (works with ranges from0to256; yes, I realize that's 257 numbers).Expression approach
Alternately, you can evaluate expressions. As noted, the preprocessor can evaluate expressions in conditional directives. Using that as a primitive, you can tease out the result; e.g., if
EXPRESSIONexpands to your expression, you can#define D0, representing the unit digit of the result, using a construct like this:You can then similarly
#defineD1to be the specific digit for the ten's place,D2for the hundreds, etc... then have aRESULTmacro expand to... D3##D2##D1##D0. Wrap this entire thing into something likeevaluator.hppand you can pump an arbitrary expression in by definingEXPRESSIONas your expression, using#include "evaluator.hpp"to evaluate it, and finally useRESULTto represent the result. With this approach each "evaluator" needs the specific Dx macros defined to the specific digits to work... so that behaves analogously to "variables", but consumes the entire evaluator.Boost pp has this capability with each evaluator known as a "slot", and provides 5 slots. So you have to pump with
#include's, and each evaluator can only store one result at a time... but in return your range is not restricted (more than native ranges) and you're actually evaluating expressions. Here's an example of using this approach using boost pp:Demo
(Edit: Hand rolled evaluator here (wandbox) might be worth review to see how the mechanics explained above work).
TL;DR summary
arithmetic- pro: evaluates entirely by macro invocation
- con: macros instead of infix operators
- con: either ranges are limited or uses alternate literal representations
expressions- pro: evaluates actual expressions (infix, groups, etc)
- pro: ranges as open as native ranges, with ordinary literals
- con: requires `#include` to pump generic mechanism
- con: reuse of evaluator must lose previous result