#include <iostream>

#include <boost/mpl/vector.hpp>
#include <boost/mpl/quote.hpp>
#include <boost/generate_hierarchy.hpp> // my proposal


//
// First a simple spine example
//

struct Foo {
  void hello_foo() {
    std::cout << "Hello from Foo!" << std::endl;
  }
  int foo;
}; 

struct Bar {
  void hello_bar() {
    std::cout << "Hello from Bar!" << std::endl;
  }
  int bar;
};

class FooBar :
  public boost::generate_spine<
    boost::mpl::vector<Foo, Bar>
  > {};

//
// Now a chained example, which requires MPL meta function
// classes
//

template <typename Base>
struct MFooT : Base {
  void hello_foo() { 
    this->bar = 42;
    std::cout << "Hello from Foo, accessing FBar's fields!"
	      << std::endl;
  }
  int foo;
};


struct MFoo {
  template <typename Base>
  struct apply {
    struct type : Base {
      void hello_foo() {
	this->bar = 42;
	std::cout << "Hello from Foo, accessing FBar's fields!"
		  << std::endl;
      }
      int foo;
    };
  };
};

  
struct MBar {
  template <typename Base>
  struct apply {
    struct type : Base {
      void hello_bar() {
	std::cout << "Hello from Bar!" << std::endl;
      }
      int bar;
    };
  };
};

// We show how you can use a raw template, via quoting, and a
// proper meta function class

class MFooBar : public boost::generate_chain<
  boost::mpl::vector<boost::quote_raw1<MFooT>, MBar>
> {};

int main(int argc, char* argv[])
{
  FooBar foobar;
  foobar.hello_foo();
  foobar.hello_bar();
  MFooBar mfoobar;
  mfoobar.hello_foo();
  mfoobar.hello_bar();
}


