shouting versus dotting
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Sun Oct 5 17:03:08 PDT 2008
Jason House wrote:
> Andrei Alexandrescu wrote:
>
>> Leandro Lucarella wrote:
>>> "enum" as the way to declare manifest constants were much more ugly than
>>> "!(", and most of the people were against it. I don't see why ".(" should
>>> be introduced.
>> Ugly or not, enumerated symbols were manifest constants to begin with.
>> That's kinda hard to argue against because it's a sheer fact.
>
> Even before we expanded enums, I hated how there was no toString() for enum
> types.
defineEnum in std.typecons provides that (and parsing too).
> Walter explained this was because bit masks made it difficult. I
> like using enums for a restricted set of options. That'd allow the
> compiler to provide toString and catch misuse in switch statements...
> Including when I add or remove allowed values.
Walter hasn't gotten around to implementing the final switch statement,
which does exactly as you mention. For the interested I paste the
relevant section in TDPL - hot off the oven:
\section{The \protect\cc{final switch} Statement}
It is often the case that @switch@ is meant to handle all possible
cases, such as all values of a small integer or of an enumerated
type. If, during maintenance, the number of cases is changing, all of
the dependent @switch@ statements suddenly fall out of sync and must
be manually searched for and modified. For such situations, the
\cc{final switch} statement comes in handy:
\begin{D}
enum deviceStatusMask = 3;
...
void Handle(uint x) {
final switch (x & deviceStatusMask) {
case 0: ...
case 1: ...
case 2: ...
case 3: ...
}
}
\end{D}
Should the value of @mask@ change later to, say, 7, attempting to
recompile @Handle@ is met with refusal on the following grounds:
\begin{lstlisting}[language=sys]
Error: final switch statement must handle all values
\end{lstlisting}
The \cc{final switch} statement looks at the shape of its controlling
expression to figure out the bounds, as follows:
\begin{itemize*}
\item If \meta{expression} is \metai{e} @&@ \metaii{e} and one of
\metai{e} and \metaii{e} evaluates to a positive compile-time value
@c@, then the range is determined as @0@ up to (and including) @c at .
\item If \meta{expression} is \metai{e} \cc{\%} \metaii{e} and
\metaii{e} evaluates to a positive compile-time value @c@, then the
range is determined as @0@ up to (and not including) \cc{c}.
\item If \meta{expression} is an unsigned right shift (either
\metai{e} \cc{>>} \metaii{e} operating on unsigned numbers, or
\metai{e} \cc{>>>} \metaii{e}), and if \metaii{e} evaluates to a
compile-time value @c@, then the range is determined as @0@ up to
(and not including) \cc{1 << (8 *} \metai{e}\cc{.sizeof - c)}.%>>
\item If \meta{expression} is the assignment variant of one of the
above (@&=@, \cc{\%=} etc.) then the range the same as for the
non-assignment variant.
\item If \meta{expression} is an enumerated type, the range is the
entire set of values of the enumerated type.
\item Otherwise, the range is @e.min@ up to and including
@e.max at . (The @min@ and @max@ constants are defined for all numeric
types.)
\end{itemize*}
There are quite a few other cases in which the range of an expression
could be effectively determined, but \cc{final switch} only handles
the usual ones. A @default@ label is allowed inside a \cc{final
switch} statement and practically turns off all checks because it
ensures \emph{de facto} that all values are handled.
Andrei
More information about the Digitalmars-d
mailing list