#begin
directive and ends at the first line that starts with a
#end directive that is not inside a comment or string. Both
the #begin and #end directives may contain
additional comments between tokens.
After the #begin, any valid cpp directive may appear,
without its initial "#" character. However, the only useful multi-line
preprocessor directive is a multi-line definition. For example, the
following code defines a multi-line macro to
make a statement that swaps two variables of type T.
#begin define swap(x,y,T)
do {
T temp = x;
x = y;
y = temp;
} while (0)
#end /* swap */
A multi-line macro may contain lines that end in backslashes; the
preprocessor will concatenate these lines to the following line, just
as it does in ordinary macros. Only non-backslashed newlines are
emitted as newlines in the final output.
At each point in a macro expansion that corresponds to a newline in the
macro definition, the preprocessor will emit a line directive. This directive
allows the compiler to determine that its current source line is within the
macro rather than within the source code that invoked the macro.
#ifndef _SHORTP_H
#define _SHORTP_H
//
// A "Shortp" is a slot-sized pointer used to reduce space usage, but it
// cannot be dereferenced directly. To
// dereference a short pointer, it must be first converted to a long
// pointer. It can also store bits of data (as many as the bits in a
// slot minus 1).
//
// A Shortp corresponding to the pointer type "Tp" is named
// "Tp_x". A "Tp_x" holding a pointer can be created from a "Tp",
// "Tp_x::pointer" returns a "Tp". A "Tp_x" holding data can be created
// from a Ubits32, "Tp_x::data" returns the contained data.
//
#include "utils/basic.h"
#include "utils/bits.h"
#include "common/slot.h"
#include "C/shortp.h"
//
// The following machine independent macro can be used to
// define a short pointer type for a long (64-bit) pointer type Tp
//
#begin define DEFINE_shortp(Tp)
class Tp##_x {
public:
Tp##_x(void) {}
/* Creates an uninitialized short pointer */
Tp##_x(Tp tp) {x = (Shortp)tp;}
/* Creates a short pointer holding a pointer */
Tp##_x(Ubits32 d) {x = (Shortp)((d << 1)|1); }
/* Creates a short pointer holding data. Only the bottom 31 bits
of data are preserved. */
bool is_data(void) { return (x & 0x1) ? TRUE : FALSE; }
/* Returns true iff short pointer holds data */
bool is_pointer(void) { return !is_data(); }
/* Returns true iff short pointer holds a pointer */
Tp pointer() {
/* Requires short pointer holds a pointer */
assert(!is_data());
return (Tp)x;
}
Shortp data() {
/* Requires the short pointer is holding a pointer */
assert(is_data());
return (x >> 1);
}
private:
Shortp x;
}
#end
#endif /* _SHORTP_H */