Mixin layers and cyclic dependencies

Steve Horne stephenwantshornenospam100 at aol.com
Mon Sep 11 16:58:16 PDT 2006


I wrote the following as a quick test if an idea. The idea in itself
worked out fine, but I hit a problem I wasn't expecting. The problem
is that the code tries to set up a cyclic dependency through
templates...

template t_ML_Init (alias FINAL, int p_Leaf_Max, int p_Branch_Max)
{
  alias FINAL  m_Final;

  const int m_Leaf_Max   = p_Leaf_Max;
  const int m_Branch_Max = p_Branch_Max;
  
  struct c_Common_Head
  {
    int m_Size;
    int m_Height;
  }

  struct c_Leaf_Item
  {
  }

  struct c_Branch_Item
  {
    void*  m_Child;
  }

  typedef m_Final.c_Leaf_Item  [m_Leaf_Max  ]  c_Leaf_Items;
  typedef m_Final.c_Branch_Item[m_Branch_Max]  c_Branch_Items;

  struct c_Leaf
  {
    m_Final.c_Common_Head            m_Head;
    m_Final.c_Leaf_Item[m_Leaf_Max]  m_Items;
  }

  struct c_Branch
  {
    m_Final.c_Common_Head               m_Head;
    m_Final.c_Branch_Item[m_Branch_Max] m_Items;
  }
  
  int* Size (m_Final.c_Leaf* p)
  {
    return &((cast(c_Common_Head*) p).m_Size);
  }

  int* Size (m_Final.c_Branch* p)
  {
    return &((cast(c_Common_Head*) p).m_Size);
  }

  int* Height (m_Final.c_Leaf* p)
  {
    return &((cast(c_Common_Head*) p).m_Height);
  }

  int* Height (m_Final.c_Branch* p)
  {
    return &((cast(c_Common_Head*) p).m_Height);
  }
  
  c_Leaf_Items* Items (m_Final.c_Leaf* p)
  {
    return &((cast(c_Leaf*) p).m_Items);
  }

  c_Branch_Items* Items (m_Final.c_Branch* p)
  {
    return &((cast(c_Branch*) p).m_Items);
  }

  void** Child (m_Final.c_Branch_Item* p)
  {
    return &((cast(c_Branch_Item*) p).m_Child);
  }
}

template t_ML_Keys (alias PL, c_Key)
{
  mixin PL;
  
  struct c_Leaf_Item
  {
    PL.c_Leaf_Item  m_Previous;
    c_Key           m_Key;
  }

  struct c_Branch_Item
  {
    PL.c_Branch_Item  m_Previous;
    c_Key             m_Key;
  }

  c_Key* Key (m_Final.c_Leaf_Item* p)
  {
    return &((cast(c_Leaf_Item*) p).m_Key);
  }

  c_Key* Key (m_Final.c_Branch_Item* p)
  {
    return &((cast(c_Branch_Item*) p).m_Key);
  }
}

template t_ML_Data (alias PL, c_Data)
{
  mixin PL;
  
  struct c_Leaf_Item
  {
    PL.c_Leaf_Item  m_Previous;
    c_Data          m_Data;
  }

  c_Data* Data (m_Final.c_Leaf_Item* p)
  {
    return &((cast(c_Leaf_Item*) p).m_Data);
  }
}

//  Shorthand form
template t_ML_Keys_Data(alias PL, c_Key, c_Data)
{
  mixin t_ML_Keys!(t_ML_Data!(PL,c_Data),c_Key);
}

void main (char[][] args)
{
  alias t_ML_Keys_Data!(t_ML_Init!(ti_Test, 4, 4),int,int) ti_Test;
}


I get the error "alias ti_Test recursive alias declaration" - clearly
the cyclic dependency isn't liked.

I also tried to use the C++ form of mix-in layers, using an outer
class as a container for definitions. That didn't work either. It
didn't complain about the cyclic dependency, but it couldn't resolve
it either. Kept complaining about definitions being missing from
FINAL.

Funny how you can get used to an idea, and forget what the compiler is
having to do to handle it. I've been just working on the assumption
that I could do these things in D.

The cyclic dependency thing isn't a fundamental feature of mix-in
layers, and I don't actually need it despite the concept-testing code
above - there are other ways using 'static if' - but I just wanted to
ask if this no-cyclic-dependencies rule is permanent or whether it
might be changed in the future.

-- 
Remove 'wants' and 'nospam' from e-mail.



More information about the Digitalmars-d mailing list