Enumeration & Programming Languages
by Walter Bright and Matthew Wilson


Listing One
T   ar[]; // Declare the array
for(int i = 0; i < ar.length; ++i)
{
  ar[i]; // Do something with the array element
}

Listing Two
T   ar[100]; // Declare the array
int i;
for(i = 0; i < sizeof(ar) / sizeof(ar[0]); ++i)
{
  ar[i]; // Do something with the array element
}

Listing Three
struct Link
{
  int   value;
  Link  *next;
} *g_head;
struct Link *l;
for(l = g_head; NULL != l; l = l->next)
{
  l->value; // Do something with the list element
}

Listing Four
@allfiles = ...;
foreach $file (@allfiles)
{
  print "File: " . $file . "\n";
}

Listing Five
languages = {}
for language in languages.keys():
    print language

Listing Six
T   ar[]; // Declare the array
foreach(T t; ar)
{
  ar[i]; // Do something with the array element
}

Listing Seven
uint[char[]] aa;    // associative array of uints indexed by a string
 ...
foreach (uint v; aa)
{
  v; // Do something with the value
}
foreach (char[] k; aa.keys)
{
  k; // Do something with the key
}
foreach (uint v, char[] k; aa)
{
  k; // Do something with the key
  v; // Do something with the value
}

Listing Eight
SomeContainerType             cont;
SomeContainerType::iterator   begin = cont.begin();
SomeContainerType::iterator   end   = cont.end();
for(; begin != end; ++begin)
{
  // Do something(s) with the elements
}

Listing Nine
struct IntegerRange
{
  this(int low, int high)
  {
    m_from  = low;
    m_to = high;
  }
  int opApply(int delegate(int value) dg)
  {
    int res;
    for(int i = m_from; i < m_to; ++i)
    {
      if(0 != (res = dg(i)))
      {
        break;
      }
    }
    return res;
  }
}

Listing Ten
public class KeySequence
{
private:
  this(Key key)
  {
    m_key = key;
  }
  invariant
  {
    assert(null !== m_key);
  }
public:
  uint Count()
  {
    return m_key.SubKeyCount();
  }
  Key GetKey(uint index)
  {
    ... // Does something similar to the opApply()
        // method to get hold of the requisite key
  }
  Key opIndex(uint index) // Provides indexing operator []
  {
    return GetKey(index);
  }
public:
  int apply(int delegate(Key key) dg)
  {
    int     result  = 0;
    HKEY    hkey    = m_key.m_hkey;
    DWORD   cSubKeys;
    DWORD   cchSubKeyMaxLen;
    LONG    res     = _Reg_GetNumSubKeys(hkey, cSubKeys, cchSubKeyMaxLen);
    char[]  sName   = new char[1 + cchSubKeyMaxLen];
    for(DWORD index = 0; 0 == result; ++index)
    {
      DWORD   cchName = 1 + cchSubKeyMaxLen;
      LONG    res     = _Reg_EnumKey(hkey, index, sName, cchName);
      if(ERROR_NO_MORE_ITEMS == res)
      {
        // Enumeration complete
      }
      else if(ERROR_SUCCESS == res)
      {
        try
        {
          Key key = m_key.GetKey(sName[0 .. cchName]);
          result = dg(key);
        }
        catch(RegistryException x)
        {
          if(x.Error == ERROR_ACCESS_DENIED)
          {
            // Skip inaccessible keys; they are
            // accessible via the KeyNameSequence
            continue;
          }
          throw x;
        }
      }
      else
      {
        throw new RegistryException("Enumeration incomplete", res);
        break;
      }
    }
    return result;
  }
private:
  Key m_key;
}

Listing Eleven
struct TreeEntry
{
  TreeEntry *m_left;
  TreeEntry *m_right;
  char[]    m_data;
}
struct Tree
{
  TreeEntry *m_root;
  int opApply(int delegate(inout char[] value) dg)
  {
    int traverse(TreeEntry* te)
    {
      int result;
      while(null != te)
      {
        result = dg(te.m_data);
        if(0 != result)
        {
          return result;
        }
        result = traverse(te.m_left);
        if(0 != result)
        {
          return result;
        }
        te = te.m_right;
      }
      return 0;
    }
    return traverse(m_root);
  }
}

Listing Twelve
int sumTree(Tree tree)
{
  int sum = 0;
  foreach(int value; tree)
  {
    sum += value;
  }
  return sum;
}

Listing Thirteen
template sum(R, V)
{
  R sumit(T t)
  {
    R sum;
    foreach (int value; t)
    {
      sum += value;
    }
    return sum;
  }
}






4



