Listing 1: Class parameter_tuple

#include<boost/type_traits/transform_traits.hpp>
#include<boost/type_traits/cv_traits.hpp>

class nil {
public:
  typedef nil element_type;
  typedef nil nested_type;
  nil() {}
  nil(const nil&) {}
  nil(const nil&, const nil&) {}
  nil(const nil&, const nil&, const nil&) {}
  nil(const nil&, const nil&, const nil&, const nil&) {}
  /* EXTEND */
};
  
template<typename FP, int n>
class nth_parameter_type {
public:
  typedef nth_parameter_type<FP::nested_type, n-1>::ret 
    ret;
};

template<typename FP>
class nth_parameter_type<FP, 0> {
public:
  typedef typename FP::element_type ret;
};

// Tag classes for mandatory and default parameters.
class default_parameter_tag{};
class mandatory_parameter_tag{};

// Class parameter_tuple
template<typename Head, typename Tail>
class parameter_tuple {
  typedef typename Head element_type;
  typedef typename Tail nested_type;
  
  typedef boost::add_reference<element_type>::type 
     element_reference_type;

  typedef boost::add_reference<boost::add_const<
    element_type
    >::type>::type  element_const_reference_type;
  
  typedef boost::add_reference<boost::add_const<
    nested_type
    >::type>::type rest_const_reference_type;

  template<int n>
  class nth_parameter_tag{};

public:
  // Constructor from n elements
  parameter_tuple(
    element_const_reference_type elem_0,
    typename boost::add_reference<boost::add_const<
      nth_parameter_type<Tail, 0>::ret
      >::type>::type elem_1 = nil(),
    typename boost::add_reference<boost::add_const<
      nth_parameter_type<Tail, 1>::ret
      >::type>::type elem_2 = nil(),
    typename boost::add_reference<boost::add_const<
      nth_parameter_type<Tail, 2>::ret
      >::type>::type elem_3 = nil()
    /* EXTEND */ ) :
    m_element(elem_0),
    m_rest(elem_1, elem_2, elem_3 /* EXTEND */ ) {}

  // Copy constructor from two function parameter objects, 
  // default implementation: copy element from first arg.
  template<typename Rhs1Head, typename Rhs1Tail, 
           typename Rhs2Head, typename Rhs2Tail>
  parameter_tuple(
    const parameter_tuple<Rhs1Head, Rhs1Tail>& rhs1,
    const parameter_tuple<Rhs2Head, Rhs2Tail>& rhs2
    ) :
    m_element(rhs1.get_element()),
    m_rest(rhs1.get_rest(), rhs2.get_rest()) {}

  // Copy constructor from two function parameter objects,
  // overload when the element type of the first argument
  // is default_parameter: copy element from second arg.
  template<typename Rhs1Tail, typename Rhs2Head, 
           typename Rhs2Tail>
  parameter_tuple(
    const parameter_tuple<
      default_parameter_tag, Rhs1Tail>& rhs1,
    const parameter_tuple<Rhs2Head, Rhs2Tail>& rhs2) :
    m_element(rhs2.get_element()),
    m_rest(rhs1.get_rest(), rhs2.get_rest()) {}
  
  // Get function to retrieve the nth parameter.
  template<int m>
  typename boost::add_reference<
    typename nth_parameter_type<
      parameter_tuple<Head, Tail>, m>::ret>::type 
  get_parameter()
  {return get_parameter_internal(nth_parameter_tag<m>());}

  // Get functions to retrieve the element and the
  // tail. These must be public for the copy constructors.
  element_const_reference_type get_element() const
  { return m_element; }
  //
  rest_const_reference_type get_rest() const
  { return m_rest; }
  
private:
  element_type m_element;
  nested_type m_rest;

  // Get function to retrieve the nth parameter, default
  //  implementation: look in the nested rest object.
  template<int m>
  typename boost::add_reference<
    typename nth_parameter_type<
      parameter_tuple<Head, Tail>, m
      >::ret>::type 
  get_parameter_internal(nth_parameter_tag<m>)
  { return m_rest.get_parameter<m-1>(); };

  // Get function to retrieve the nth parameter, overload
  // for m=0: return the element.
  element_reference_type get_parameter_internal(
    nth_parameter_tag<0>)
  { return m_element; };
  
  // Prevent assignment and copy construction.
  parameter_tuple(const parameter_tuple&);
  parameter_tuple& operator=(const parameter_tuple&);

};

// parameter_tuple type generator
template<typename T1=nil, typename T2=nil, 
         typename T3=nil, typename T4=nil
         /* EXTEND */>
class make_parameter_tuple_type {
public:
  typedef typename parameter_tuple<
    T1, typename make_parameter_tuple_type<
      T2, T3, T4 /* EXTEND */>::ret> ret;
};

// Kicks in for zero arguments passed
template<>
class make_parameter_tuple_type<
  nil, nil, nil, nil /* EXTEND */ >
{
  public:
    typedef typename nil ret;
};