ocean.core.Enum

Mixin for an enum class with the following basic features: * Contains an enum, called E, with members specified by an associative array passed to the mixin. * Implements an interface, IEnum, with common shared methods: * opIndex: look up an enum member's name by its value and vice-versa. * opIn_r: check whether a value (int) or name (char[]) is a member of the enum. * opApply: iteration over over the names & values of the enum's members. * length: returns the number of members in the enum. * min & max: return the minimum/maximum value of the enum's members. * A static opCall() method which returns a singleton instance of the class. This is the most convenient means of calling the methods listed above.

Basic usage example:

// Define enum class by implementing IEnum and mixing in EnumBase with
// an associative array defining the enum members
class Commands : IEnum
{
    // Note: the [] after the first string ensures that the associative
    // array is of type int[char[]], not int[char[3]].
    mixin EnumBase!([
        "Get"[]:1,
        "Put":2,
        "Remove":3
    ]);
}

// Look up enum member names by value. (Note that the singleton instance
// of the enum class is passed, using the static opCall method.)
assert(Commands()["Get"] == 1);

// Look up enum member values by name
assert(Commands()[1] == "Get");

// Check whether a value is in the enum
assert(!(5 in Commands()));

// Check whether a name is in the enum
assert(!("Delete" in Commands()));

// Iterate over enum members
import ocean.io.Stdout;

foreach ( n, v; Commands() )
{
    Stdout.formatln("{}: {}", n, v);
}

The mixin also supports the following more advanced features: * One enum class can be inherited from another, using standard class inheritance. The enum members in a derived enum class extend those of the super class. * The use of normal class inheritance, along with the IEnum interface, allows enum classes to be used abstractly.

Advanced usage example:

import ocean.core.Enum;

// Basic enum class
class BasicCommands : IEnum
{
    mixin EnumBase!([
        "Get"[]:1,
        "Put":2,
        "Remove":3
    ]);
}

// Inherited enum class
class ExtendedCommands : BasicCommands
{
    mixin EnumBase!([
        "GetAll"[]:4,
        "RemoveAll":5
    ]);
}

// Check for a few names.
assert("Get" in BasicCommands());
assert("Get" in ExtendedCommands());
assert(!("GetAll" in BasicCommands()));
assert("GetAll" in ExtendedCommands());

// Example of abstract usage of enum classes
import ocean.io.Stdout;

void printEnumMembers ( IEnum e )
{
    foreach ( n, v; e )
    {
        Stdout.formatln("{}: {}", n, v);
    }
}

printEnumMembers(BasicCommands());
printEnumMembers(ExtendedCommands());

TODO: does it matter that the enum values are always int? We could add a template parameter to specify the base type, but I think it'd be a shame to make things more complex. IEnum would have to become a template then.

Members

Classes

Enum1
class Enum1

Unit test.

Enum2
class Enum2

Unit test.

Functions

checkEnum
void checkEnum(istring[] names, int[] values)

Runs a series of tests to check that the specified enum type contains members with the specified names and values. The name and value lists are assumed to be in the same order (i.e. namesi corresponds to valuesi).

Interfaces

IEnum
interface IEnum

Interface defining the basic functionality of an enum class.

Templates

EnumBase
template EnumBase(T...)

Template mixin to add enum functionality to a class.

EnumValues
template EnumValues(size_t i, T...)

Template which evaluates to a string containing the code for a list of enum members, as specified by the first two members of the passed tuple, which must be an array of strings and an array of integers, respectively. The strings specify the names of the enum members, and the integers their values.

SuperClassIndex
template SuperClassIndex(size_t i, T...)

Template which evaluates to a size_t corresponding to the index in the type tuple T which contains a class implementing the IEnum interface. If no such type exists in T, then the template evaluates to T.length.

Meta

License

Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. Alternatively, this file may be distributed under the terms of the Tango 3-Clause BSD License (see LICENSE_BSD.txt for details).