txt: ## enumhow.md
  class Metamodel::EnumHOW
  
  Metaobject representing a Raku enum.
  
  ```raku
      class Metamodel::EnumHOW
          does Metamodel::Naming
          does Metamodel::Documenting
          does Metamodel::Stashing
          does Metamodel::AttributeContainer
          does Metamodel::MethodContainer
          does Metamodel::MultiMethodContainer
          does Metamodel::RoleContainer
          does Metamodel::BaseType
          does Metamodel::MROBasedMethodDispatch
          does Metamodel::MROBasedTypeChecking
          does Metamodel::BUILDPLAN
          does Metamodel::BoolificationProtocol
          does Metamodel::REPRComposeProtocol
          does Metamodel::Mixins
              { }
  
  ```
  
  *Warning*: this class is part of the Rakudo implementation, and is not a part of the language specification.
  
  `Metamodel::EnumHOW` is the metaclass behind the `enum` keyword.
  
  ```raku
  enum Numbers <1 2>;
  say Numbers.HOW ~~ Metamodel::EnumHOW; # OUTPUT: «True␤»
  ```
  
  The following enum declaration:
  
  ```raku
  our Int enum Error <Warning Failure Exception Sorrow Panic>;
  ```
  
  Is roughly equivalent to this code using `Metamodel::EnumHOW`'s methods:
  
  ```raku
  BEGIN {
      my constant Error = Metamodel::EnumHOW.new_type: :name<Error>, :base_type(Int);
      Error.^add_role: Enumeration;
      Error.^add_role: NumericEnumeration;
      Error.^compose;
      for <Warning Failure Exception Sorrow Panic>.kv -> Int $v, Str $k {
          # Note: Enumeration.pred and .succ will not work when adding enum
          # values as pairs. They should be instances of the enum itself, but
          # this isn't possible to do without nqp.
          Error.^add_enum_value: $k => $v;
          OUR::{$k} := Error.^enum_from_value: $v;
      }
      Error.^compose_values;
      OUR::<Error> := Error;
  }
  ```
  
  # [Methods](#class_Metamodel::EnumHOW "go to top of document")[§](#Methods "direct link")
  
  ## [method new\_type](#class_Metamodel::EnumHOW "go to top of document")[§](#method_new_type "direct link")
  
  ```raku
  method new_type(:$name!, :$base_type?, :$repr = 'P6opaque', :$is_mixin)
  ```
  
  Creates a new type object for an enum. `$name` is the enum name, `$base_type` is the type given when the enum is declared using a scoped declaration (if any), and `$repr` is the type representation passed to the enum using the `repr` trait. `$is_mixin` is unused.
  
  ## [method add\_parent](#class_Metamodel::EnumHOW "go to top of document")[§](#method_add_parent "direct link")
  
  ```raku
  method add_parent($obj, $parent)
  ```
  
  Sets the base type of an enum. This can only be used if no base type was passed to `.new_type`.
  
  ## [method set\_export\_callback](#class_Metamodel::EnumHOW "go to top of document")[§](#method_set_export_callback "direct link")
  
  ```raku
  method set_export_callback($obj, $callback)
  ```
  
  Sets the enum's export callback, which is invoked when calling `.compose_values`. This is called when applying the `export` trait to an enum. `$callback` should be a routine of some sort, taking no arguments, that handles exporting the enum's values.
  
  ## [method export\_callback](#class_Metamodel::EnumHOW "go to top of document")[§](#method_export_callback "direct link")
  
  ```raku
  method export_callback($obj)
  ```
  
  Returns the export callback set by `.set_export_callback`.
  
  ## [method compose](#class_Metamodel::EnumHOW "go to top of document")[§](#method_compose "direct link")
  
  ```raku
  method compose($obj, :$compiler_services)
  ```
  
  Completes a type object for an enum. This is when any roles done by the enum are mixed in. This needs to be called before any enum values can be added using `.add_enum_value`.
  
  ## [method is\_composed](#class_Metamodel::EnumHOW "go to top of document")[§](#method_is_composed "direct link")
  
  ```raku
  method is_composed($obj)
  ```
  
  Returns 1 if the enum is composed, otherwise returns 0.
  
  ## [method compose\_values](#class_Metamodel::EnumHOW "go to top of document")[§](#method_compose_values "direct link")
  
  ```raku
  method compose_values($obj)
  ```
  
  Calls the export callback set by `.set_export_callback` and removes it from state. This should be called after adding the enum's values using `.add_enum_value`.
  
  ## [method set\_composalizer](#class_Metamodel::EnumHOW "go to top of document")[§](#method_set_composalizer "direct link")
  
  ```raku
  method set_composalizer($c)
  ```
  
  Sets the composalizer for an enum, which produces a type that can be mixed in with another. `$c` should be a routine of some that has the following signature:
  
  ```raku
  :($type, $name, @enum_values)
  ```
  
  ## [method composalizer](#class_Metamodel::EnumHOW "go to top of document")[§](#method_composalizer "direct link")
  
  ```raku
  method composalizer($obj)
  ```
  
  Returns the composalizer set by `.set_composalizer`.
  
  ## [method add\_enum\_value](#class_Metamodel::EnumHOW "go to top of document")[§](#method_add_enum_value "direct link")
  
  ```raku
  method add_enum_value($obj, $value)
  ```
  
  Adds a value to this enum. `$value` should be an instance of the enum itself, as type [`Enumeration`](/type/Enumeration).
  
  ## [method enum\_values](#class_Metamodel::EnumHOW "go to top of document")[§](#method_enum_values "direct link")
  
  ```raku
  method enum_values($obj)
  ```
  
  Returns the values for the enum.
  
  ```raku
  enum Numbers <10 20>;
  say Numbers.^enum_values;                   # OUTPUT: {10 => 0, 20 => 1}
  ```
  
  ## [method elems](#class_Metamodel::EnumHOW "go to top of document")[§](#method_elems "direct link")
  
  ```raku
  method elems($obj)
  ```
  
  Returns the number of values.
  
  ```raku
  enum Numbers <10 20>;
  say Numbers.^elems;                         # OUTPUT: 2
  ```
  
  ## [method enum\_from\_value](#class_Metamodel::EnumHOW "go to top of document")[§](#method_enum_from_value "direct link")
  
  ```raku
  method enum_from_value($obj, $value)
  ```
  
  Given a value of the enum's base type, return the corresponding enum.
  
  ```raku
  enum Numbers <10 20>;
  say Numbers.^enum_from_value(0);            # OUTPUT: 10
  ```
  
  ## [method enum\_value\_list](#class_Metamodel::EnumHOW "go to top of document")[§](#method_enum_value_list "direct link")
  
  ```raku
  method enum_value_list($obj)
  ```
  
  Returns a list of the enum values.
  
  ```raku
  enum Numbers <10 20>;
  say Numbers.^enum_value_list;               # OUTPUT: (10 20)
  ```
  