Tree Structure with recursive variadic template

225 views Asked by At

I'm trying to make a tree structure to manage data whose structure can change depending on the type.

Here is what I did for the base object

//Type1.. are the types of the leaves having Base as common parent
enum class EnumBase{Type1,Type2,Type3};

class Base {
protected:
  EnumBase const _type;
  Base(EnumBase typ) : _type(typ){}
public:
  virtual ~Base() = default;
  Base() = delete;
  EnumBase getType() const {return _type;}
};

while this is to create and get different derived

template<class Leaf>
class Controller {
private:
  std::shared_ptr<Leaf> _pt;
public:
  template<class Derived>
  void create() {
    _pt =  std::make_shared<Derived>();
    return;
  }

  template<class Derived>
  Derived & get(){
    auto pt = std::dynamic_pointer_cast<Derived>(_pt);
    if(!pt){
      throw; //bad cast
    }
    return *pt;
  }
};

The second level of the tree goes like:

enum class Type1Types{T1,T2};

class Type1 : public Base {
protected:
  Type1Types const _type;
  Type1(Type1Types typ) : Base(EnumBase::Type1), _type(typ){}
public:
  virtual ~Type1() = default;
  Type1() = delete;
  Type1Types getType() const {return _type;}
};

class Type2; //...the same with EnumBase::Type2 and Type2Types 

class Type3; //...the same with EnumBase::Type3 and Type3Types

with final implementations which may possibly include Controller for another data type:

class T1 : public Type1 {
public:
  T1() : Type1(Type1Types::T1) {}
  //... data of T1
};

class T2 : public Type1 {
public:
  Controller<Type2> objType2;
  //... other data for T2
};

The idea behind all this is that I can write:

int main(){
  Controller<Type1> obj;
  obj.create<T2>();
  obj.get<T2>().objType2.create<somethinginType2>();
  //...
}

Probably such pattern is overcomplicated (any comment and suggestion is welcomed) but a pattern exists and I believe that it is possible with some template magic and some recursion to write a general templated version of a leaf (Type1, Type2,..) so that I don't have to copy/paste the code and only change the type of the enum for the children (Type1Types) and the type for itself (EnumBase::Type1).

I was thinking of some structure like

template<class Me, class... Parents>
struct MagicStructure{
  //some typedef
  //my type
}

Any idea?

0

There are 0 answers