Purged out-of-date documentation.

This commit is contained in:
Anton Bachin 2015-05-05 17:49:02 -04:00
parent 216f026fe1
commit 3ac5e84cf9

135
enum.h
View File

@ -1,32 +1,3 @@
/// @file EnumInternal.h
/// Internal definitions for the enum type generator in `Enum.h`.
///
/// Several definitions must precede the public `ENUM` macro and the interface
/// defined in it. This includes helper classes and all `constexpr` functions,
/// which cannot be forward-declared. In order to make `Enum.h` more readable,
/// these definitions are placed into this file, which is included from
/// `Enum.h`.
///
/// Throughout the internal code, macro and template parameters named `EnumType`
/// stand for the class types generated by the `ENUM` macro, while parameters
/// named `EnumValue` stand for the internal C++ enum types. Roughly,
/// `EnumValue == EnumType::_Value`.
///
/// @todo Generating the values array using the `_eat_assign` template is
/// expensive, and the cost seems to be due to the instantiation of
/// compile-time objects, not due to templates. Trying statement expressions
/// (a GNU extension) didn't work, because statement expressions aren't
/// allowed "at file scope" (in this case, within a class type declared at
/// file scope).
/// @todo Compile time is currently dominated by the cost of static
/// instantiation. Try to reduce this cost by statically instantiating data
/// structures for each type, then dynamically passing them to a small
/// number of actual processing functions - which only have to be
/// instantiated once for every different underlying type. Underlying types
/// are very likely to collide.
#pragma once
#include <cstddef> // For size_t.
@ -38,59 +9,14 @@
/// Internal namespace for compile-time and private run-time functions used by
/// the enum class generator.
namespace _enum {
/// Weak symbols to allow the same data structures to be defined statically in
/// multiple translation units, then be collapsed to one definition by the
/// linker.
#define _ENUM_WEAK __attribute__((weak))
/// Template for iterable objects over enum names and values.
///
/// The iterables are intended for use with C++11 `for-each` syntax. They are
/// returned by each enum type's static `names()` and `values()` methods. For
/// example, `EnumType::values()` is an iterable over valid values of type
/// `EnumType`, and allows the following form:
///
/// ~~~{.cc}
/// for (EnumType e : EnumType::values()) {
/// // ...
/// }
/// ~~~
///
/// The iterable class is templated to reuse code between the name and value
/// iterables.
///
/// @tparam Element Type of element returned during iteration: either the enum
/// type (for iterables over `values()`) or `const char*` (for iterables
/// over `names()`).
/// @tparam EnumType The enum type.
/// @tparam ArrayType Type of the array actually being iterated over. The reason
/// this is a type parameter is because for the iterable over `values()`,
/// the underlying array type is `const EnumType::_value * const`, instead
/// of `const EnumType * const`, as one might first expect. Objects of type
/// `EnumType` are constructed on the fly during iteration from values of
/// type `EnumType::_value` (this is a no-op at run-time). For iterables
/// over `names()`, `ArrayType` is simply `const char * const`, as would be
/// expeted.
///
/// @internal
///
/// An `_Iterable` stores a reference to the array (of either names or values)
/// that will be iterated over. `_Iterable::iterator` additionally stores an
/// index into the array. The iterator begins at the first valid index. Each
/// time it is incremented, the iterator advances to the next valid index. The
/// `end()` iterator stores an index equal to the size of the array. Values are
/// considered valid if they are not equal to the bad value, are not below the
/// minimum value, and are not above the maximum value. Names are valid if they
/// are the name of a valid value.
template <typename EnumType, typename Iterator>
class _Iterable;
@ -159,23 +85,6 @@ class _Iterable {
/// Compile-time helper class used to transform expressions of the forms `A` and
/// `A = 42` into values of type `UnderlyingType` that can be used in
/// initializer lists. The `ENUM` macro is passed a mixture of simple enum
/// constants (`A`) and constants with an explicitly-assigned value (`A = 42`).
/// Both must be turned into expressions of type `UnderlyingType` in order to be
/// usable in initializer lists of the values array. This is done by prepending
/// a cast to the expression, as follows:
/// ~~~{.cc}
/// (_eat_assign<UnderlyingType>)A
/// (_eat_assign<UnderlyingType>)A = 42
/// ~~~
/// The second case is the interesting one. At compile time, the value `A` is
/// first converted to an equivalent `_eat_assign<UnderlyingType>` object, that
/// stores the value. This object has an overriden assignment operator, which
/// "eats" the `= 42` and returns the stored value of `A`, which is then used in
/// the initializer list.
/// @tparam UnderlyingType Final type used in the values array.
template <typename UnderlyingType>
class _eat_assign {
private:
@ -189,55 +98,23 @@ class _eat_assign {
constexpr operator UnderlyingType () const { return _value; }
};
/// Prepends its second argument with the cast `(_eat_assign<UnderlyingType>)`
/// in order to make it usable in initializer lists. See `_eat_assign`.
#define _ENUM_EAT_ASSIGN_SINGLE(UnderlyingType, expression) \
((_enum::_eat_assign<UnderlyingType>)UnderlyingType::expression)
/// Prepends each of its arguments with the casts
/// `(_eat_assign<UnderlyingType>)`, creating the elements of an initializer
/// list of objects of type `UnderlyingType`.
#define _ENUM_EAT_ASSIGN(UnderlyingType, ...) \
_ENUM_PP_MAP(_ENUM_EAT_ASSIGN_SINGLE, UnderlyingType, __VA_ARGS__)
/// Stringizes its second argument. The first argument is not used - it is there
/// only because `_ENUM_PP_MAP` expects it.
#define _ENUM_STRINGIZE_SINGLE(ignored, expression) #expression
/// Stringizes each of its arguments.
#define _ENUM_STRINGIZE(...) \
_ENUM_PP_MAP(_ENUM_STRINGIZE_SINGLE, ignored, __VA_ARGS__)
/// Symbols that end a constant name. Constant can be defined in several ways,
/// for example:
/// ~~~{.cc}
/// A
/// A = AnotherConstant
/// A = 42
/// A=42
/// ~~~
/// These definitions are stringized in their entirety by `_ENUM_STRINGIZE`.
/// This means that in addition to the actual constant names, the raw `_names`
/// arrays potentially contain additional trailing symbols. `_ENUM_NAME_ENDERS`
/// defines an array of symbols that would end the part of the string that is
/// the actual constant name. Note that it is important that the null terminator
/// is implicitly present in this array.
#define _ENUM_NAME_ENDERS "= \t\n"
/// Compile-time function that determines whether a character terminates the
/// name portion of an enum constant definition.
///
/// Call as `_endsName(c)`.
///
/// @param c Character to be tested.
/// @param index Current index into the `_ENUM_NAME_ENDERS` array.
/// @return `true` if and only if `c` is one of the characters in
/// `_ENUM_NAME_ENDERS`, including the implicit null terminator in that
/// array.
constexpr bool _endsName(char c, size_t index = 0)
{
return
@ -258,18 +135,6 @@ constexpr char _toLowercaseAscii(char c)
return c >= 0x41 && c <= 0x5A ? c + 0x20 : c;
}
/// Compile-time function that matches a stringized name (with potential
/// trailing spaces and equals signs) against a reference name (a regular
/// null-terminated string).
///
/// Call as `_namesMatch(stringizedName, referenceName)`.
///
/// @param stringizedName A stringized constant name, potentially terminated by
/// one of the symbols in `_ENUM_NAME_ENDERS` instead of a null terminator.
/// @param referenceName A name of interest. Null-terminated.
/// @param index Current index into both names.
/// @return `true` if and only if the portion of `stringizedName` before any of
/// the symbols in `_ENUM_NAME_ENDERS` exactly matches `referenceName`.
constexpr bool _namesMatch(const char *stringizedName,
const char *referenceName,
size_t index = 0)