#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 */