/*
 For more information, please see: http://software.sci.utah.edu

 The MIT License

 Copyright (c) 2012 Scientific Computing and Imaging Institute,
 University of Utah.


 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 */

// This file is automatically generated

#ifndef TUVOK_LUAFUNBINDING_CORE_H_
#define TUVOK_LUAFUNBINDING_CORE_H_

#include <iomanip>
#include <typeinfo>
#include <type_traits>
#include <sstream>

#include "LuaClassInstance.h"
#include "LuaStackRAII.h"

namespace tuvok
{
#ifdef TLUA_VNM
    #error __FILE__ redefines TLUA_VNM
#endif

#ifdef TLUA_M_VNM
    #error __FILE__ redefines TLUA_M_VNM
#endif

// Variable Name
#define TLUA_VNM(x)       x##_v

// Member variable name and definition.
#define TLUA_M_VNM(x)     x##_mv

// Abstract base classed used to push and pull parameters off of internal
// undo/redo stacks.
class LuaCFunAbstract
{
public:
  virtual ~LuaCFunAbstract() {}

  virtual void pushParamsToStack(lua_State* L) const      = 0;

  /// Pulls parameters from the stack, starting at the non-pseudo index si.
  /// Does NOT pop the parameters off the stack.
  virtual void pullParamsFromStack(lua_State* L, int si)  = 0;

  /// Returns a string with the formated parameter values in it
  /// e.g. If there were 3 parameters, a boolean, a string, and an int, then
  /// "true, 'hi', 463" would be a possible result of the function.
  virtual std::string getFormattedParameterValues() const = 0;
};


// LUA C function execution base unspecialized template.
template<typename LuaFunExec>
class LuaCFunExec : public LuaCFunAbstract
{
public:
  // We want to keep the run and getSignature functions static so we don't
  // have to initialize member variables for these common operations
  // (we don't know their types).
  static std::string getSigNoReturn(const std::string& funcName);
  static std::string getSignature(const std::string& funcName);
  static void buildTypeTable(lua_State* L);

  // Pushing and pulling parameters from the stack are used to store parameters
  // on the undo / redo stacks within the program.
  virtual void pushParamsToStack(lua_State* L) const;
  virtual void pullParamsFromStack(lua_State* L, int si); // si = starting
                                                          // stack index
  virtual std::string getFormattedParameterValues() const;
};


//------------------
//
// STATIC FUNCTIONS
//
//------------------

// Are return values useful to store alongside the parameters?

//--------------
// 0 PARAMETERS
//--------------
template<typename Ret>
class LuaCFunExec<Ret (*)()> : public LuaCFunAbstract
{
public:
  typedef Ret returnType;
  typedef Ret (*fpType)();
  static Ret run(lua_State*, int, fpType fp)
  {
    return fp();
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "()";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }
  static void constructTypesTable(lua_State*, int)
  {}

  virtual void pushParamsToStack(lua_State*) const   {}
  virtual void pullParamsFromStack(lua_State*, int)  {}
  virtual std::string getFormattedParameterValues() const
  {
    return "";
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    lua_newtable(L);
  }
#endif

};

#define LUAC_MAX_NUM_PARAMS (10)
//---------------
// 1 PARAMETERS
//---------------
template <typename Ret, typename P1>
class LuaCFunExec<Ret (*)(P1)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    return fp(TLUA_VNM(P1));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr() + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
};

//---------------
// 2 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2>
class LuaCFunExec<Ret (*)(P1, P2)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
};

//---------------
// 3 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3>
class LuaCFunExec<Ret (*)(P1, P2, P3)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
};

//---------------
// 4 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3, typename P4>
class LuaCFunExec<Ret (*)(P1, P2, P3, P4)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3, P4);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
};

//---------------
// 5 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5>
class LuaCFunExec<Ret (*)(P1, P2, P3, P4, P5)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3, P4, P5);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
};

//---------------
// 6 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
class LuaCFunExec<Ret (*)(P1, P2, P3, P4, P5, P6)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3, P4, P5, P6);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
};

//---------------
// 7 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
class LuaCFunExec<Ret (*)(P1, P2, P3, P4, P5, P6, P7)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3, P4, P5, P6, P7);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
};

//---------------
// 8 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
class LuaCFunExec<Ret (*)(P1, P2, P3, P4, P5, P6, P7, P8)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3, P4, P5, P6, P7, P8);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P8>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P8) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
};

//---------------
// 9 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
class LuaCFunExec<Ret (*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    typename LuaStrictStack<P9>::Type TLUA_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8), TLUA_VNM(P9));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ", " + LuaStrictStack<P9>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
    , TLUA_M_VNM(P9)(LuaStrictStack<P9>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
    LuaStrictStack<P9>::push(L, TLUA_M_VNM(P9));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    TLUA_M_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
        + ", " + LuaStrictStack<P9>::getValStr(TLUA_M_VNM(P9))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P9>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P8>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P8) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P9>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P9) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
  typename LuaStrictStack<P9>::Type TLUA_M_VNM(P9);
};

//---------------
// 10 PARAMETERS
//---------------
template <typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
class LuaCFunExec<Ret (*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 0;
  typedef Ret returnType;
  typedef Ret (*fpType)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10);
  static Ret run(lua_State* L, int paramStackIndex, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    typename LuaStrictStack<P9>::Type TLUA_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    typename LuaStrictStack<P10>::Type TLUA_VNM(P10) = LuaStrictStack<P10>::get(L, pos++);
    return fp(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8), TLUA_VNM(P9), TLUA_VNM(P10));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ", " + LuaStrictStack<P9>::getTypeStr()
        + ", " + LuaStrictStack<P10>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
    , TLUA_M_VNM(P9)(LuaStrictStack<P9>::getDefault())
    , TLUA_M_VNM(P10)(LuaStrictStack<P10>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
    LuaStrictStack<P9>::push(L, TLUA_M_VNM(P9));
    LuaStrictStack<P10>::push(L, TLUA_M_VNM(P10));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    TLUA_M_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    TLUA_M_VNM(P10) = LuaStrictStack<P10>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
        + ", " + LuaStrictStack<P9>::getValStr(TLUA_M_VNM(P9))
        + ", " + LuaStrictStack<P10>::getValStr(TLUA_M_VNM(P10))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P9>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P10>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P8>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P8) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P9>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P9) of this function.");
  static_assert(false ==std::is_void<typename LuaStrictStack<P10>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P10) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
  typename LuaStrictStack<P9>::Type TLUA_M_VNM(P9);
  typename LuaStrictStack<P10>::Type TLUA_M_VNM(P10);
};

//------------------
//
// MEMBER FUNCTIONS
//
//------------------

//--------------
// 0 PARAMETERS
//--------------
template<typename T, typename Ret>
class LuaCFunExec<Ret (T::*)()> : public LuaCFunAbstract
{
public:
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)();
  static Ret run(lua_State*, int, T* c, fpType fp)
  {
    return (c->*fp)();
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "()";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  virtual std::string getFormattedParameterValues() const
  {
    return "";
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    lua_newtable(L);
  }
#endif

  virtual void pushParamsToStack(lua_State*) const   {}
  virtual void pullParamsFromStack(lua_State*, int)  {}
};

//---------------
// 1 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1>
class LuaCFunExec<Ret (T::*)(P1)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1));
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
};

//---------------
// 2 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2>
class LuaCFunExec<Ret (T::*)(P1, P2)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
};

//---------------
// 3 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3>
class LuaCFunExec<Ret (T::*)(P1, P2, P3)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
};

//---------------
// 4 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
};

//---------------
// 5 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
};

//---------------
// 6 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
};

//---------------
// 7 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
};

//---------------
// 8 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7, P8)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7, P8);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P8>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P8) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
};

//---------------
// 9 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    typename LuaStrictStack<P9>::Type TLUA_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8), TLUA_VNM(P9));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ", " + LuaStrictStack<P9>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
    , TLUA_M_VNM(P9)(LuaStrictStack<P9>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
    LuaStrictStack<P9>::push(L, TLUA_M_VNM(P9));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    TLUA_M_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
        + ", " + LuaStrictStack<P9>::getValStr(TLUA_M_VNM(P9))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P9>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P8>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P8) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P9>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P9) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
  typename LuaStrictStack<P9>::Type TLUA_M_VNM(P9);
};

//---------------
// 10 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10);
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    typename LuaStrictStack<P9>::Type TLUA_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    typename LuaStrictStack<P10>::Type TLUA_VNM(P10) = LuaStrictStack<P10>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8), TLUA_VNM(P9), TLUA_VNM(P10));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ", " + LuaStrictStack<P9>::getTypeStr()
        + ", " + LuaStrictStack<P10>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
    , TLUA_M_VNM(P9)(LuaStrictStack<P9>::getDefault())
    , TLUA_M_VNM(P10)(LuaStrictStack<P10>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
    LuaStrictStack<P9>::push(L, TLUA_M_VNM(P9));
    LuaStrictStack<P10>::push(L, TLUA_M_VNM(P10));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    TLUA_M_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    TLUA_M_VNM(P10) = LuaStrictStack<P10>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
        + ", " + LuaStrictStack<P9>::getValStr(TLUA_M_VNM(P9))
        + ", " + LuaStrictStack<P10>::getValStr(TLUA_M_VNM(P10))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P9>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P10>(L); lua_settable(L, -3);
  }
#endif

  static_assert(false == std::is_void<typename LuaStrictStack<P1>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P1) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P2>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P2) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P3>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P3) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P4>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P4) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P5>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P5) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P6>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P6) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P7>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P7) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P8>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P8) of this function.");
  static_assert(false == std::is_void<typename LuaStrictStack<P9>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P9) of this function.");
  static_assert(false ==std::is_void<typename LuaStrictStack<P10>::Type>::value,
                "You are missing an overload of LuaStrictStack for the "
                "argument type (P10) of this function.");
  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
  typename LuaStrictStack<P9>::Type TLUA_M_VNM(P9);
  typename LuaStrictStack<P10>::Type TLUA_M_VNM(P10);
};

//------------------
//
// MEMBER FUNCTIONS
//
//------------------

//--------------
// 0 PARAMETERS
//--------------
template<typename T, typename Ret>
class LuaCFunExec<Ret (T::*)() const> : public LuaCFunAbstract
{
public:
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)() const;
  static Ret run(lua_State*, int, T* c, fpType fp)
  {
    return (c->*fp)();
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "()";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  virtual std::string getFormattedParameterValues() const
  {
    return "";
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    lua_newtable(L);
  }
#endif

  virtual void pushParamsToStack(lua_State*) const   {}
  virtual void pullParamsFromStack(lua_State*, int)  {}
};
//---------------
// 1 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1>
class LuaCFunExec<Ret (T::*)(P1) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
};

//---------------
// 2 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2>
class LuaCFunExec<Ret (T::*)(P1, P2) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
};

//---------------
// 3 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3>
class LuaCFunExec<Ret (T::*)(P1, P2, P3) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
};

//---------------
// 4 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
};

//---------------
// 5 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
};

//---------------
// 6 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
};

//---------------
// 7 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
};

//---------------
// 8 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7, P8) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7, P8) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
};

//---------------
// 9 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7, P8, P9) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    typename LuaStrictStack<P9>::Type TLUA_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8), TLUA_VNM(P9));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ", " + LuaStrictStack<P9>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
    , TLUA_M_VNM(P9)(LuaStrictStack<P9>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
    LuaStrictStack<P9>::push(L, TLUA_M_VNM(P9));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    TLUA_M_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
        + ", " + LuaStrictStack<P9>::getValStr(TLUA_M_VNM(P9))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P9>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
  typename LuaStrictStack<P9>::Type TLUA_M_VNM(P9);
};

//---------------
// 10 PARAMETERS
//---------------
template <typename T, typename Ret, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
class LuaCFunExec<Ret (T::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) const> : public LuaCFunAbstract
{
public:
  static const int memberFunc = 1;
  typedef T classType;
  typedef Ret returnType;
  typedef Ret (T::*fpType)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) const;
  static Ret run(lua_State* L, int paramStackIndex, T* c, fpType fp)
  {
    int pos = paramStackIndex;
    typename LuaStrictStack<P1>::Type TLUA_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    typename LuaStrictStack<P2>::Type TLUA_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    typename LuaStrictStack<P3>::Type TLUA_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    typename LuaStrictStack<P4>::Type TLUA_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    typename LuaStrictStack<P5>::Type TLUA_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    typename LuaStrictStack<P6>::Type TLUA_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    typename LuaStrictStack<P7>::Type TLUA_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    typename LuaStrictStack<P8>::Type TLUA_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    typename LuaStrictStack<P9>::Type TLUA_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    typename LuaStrictStack<P10>::Type TLUA_VNM(P10) = LuaStrictStack<P10>::get(L, pos++);
    return (c->*fp)(TLUA_VNM(P1), TLUA_VNM(P2), TLUA_VNM(P3), TLUA_VNM(P4), TLUA_VNM(P5), TLUA_VNM(P6), TLUA_VNM(P7), TLUA_VNM(P8), TLUA_VNM(P9), TLUA_VNM(P10));
  }
  static std::string getSigNoReturn(const std::string& funcName)
  {
    return funcName + "(" + LuaStrictStack<P1>::getTypeStr()
        + ", " + LuaStrictStack<P2>::getTypeStr()
        + ", " + LuaStrictStack<P3>::getTypeStr()
        + ", " + LuaStrictStack<P4>::getTypeStr()
        + ", " + LuaStrictStack<P5>::getTypeStr()
        + ", " + LuaStrictStack<P6>::getTypeStr()
        + ", " + LuaStrictStack<P7>::getTypeStr()
        + ", " + LuaStrictStack<P8>::getTypeStr()
        + ", " + LuaStrictStack<P9>::getTypeStr()
        + ", " + LuaStrictStack<P10>::getTypeStr()
        + ")";
  }
  static std::string getSignature(const std::string& funcName)
  { return LuaStrictStack<Ret>::getTypeStr() + " " + getSigNoReturn(funcName); }

  LuaCFunExec()
    : TLUA_M_VNM(P1)(LuaStrictStack<P1>::getDefault())
    , TLUA_M_VNM(P2)(LuaStrictStack<P2>::getDefault())
    , TLUA_M_VNM(P3)(LuaStrictStack<P3>::getDefault())
    , TLUA_M_VNM(P4)(LuaStrictStack<P4>::getDefault())
    , TLUA_M_VNM(P5)(LuaStrictStack<P5>::getDefault())
    , TLUA_M_VNM(P6)(LuaStrictStack<P6>::getDefault())
    , TLUA_M_VNM(P7)(LuaStrictStack<P7>::getDefault())
    , TLUA_M_VNM(P8)(LuaStrictStack<P8>::getDefault())
    , TLUA_M_VNM(P9)(LuaStrictStack<P9>::getDefault())
    , TLUA_M_VNM(P10)(LuaStrictStack<P10>::getDefault())
  {}

  virtual void pushParamsToStack(lua_State* L) const
  {
    LuaStrictStack<P1>::push(L, TLUA_M_VNM(P1));
    LuaStrictStack<P2>::push(L, TLUA_M_VNM(P2));
    LuaStrictStack<P3>::push(L, TLUA_M_VNM(P3));
    LuaStrictStack<P4>::push(L, TLUA_M_VNM(P4));
    LuaStrictStack<P5>::push(L, TLUA_M_VNM(P5));
    LuaStrictStack<P6>::push(L, TLUA_M_VNM(P6));
    LuaStrictStack<P7>::push(L, TLUA_M_VNM(P7));
    LuaStrictStack<P8>::push(L, TLUA_M_VNM(P8));
    LuaStrictStack<P9>::push(L, TLUA_M_VNM(P9));
    LuaStrictStack<P10>::push(L, TLUA_M_VNM(P10));
}
  virtual void pullParamsFromStack(lua_State* L, int si)
  {
    int pos = si;
    TLUA_M_VNM(P1) = LuaStrictStack<P1>::get(L, pos++);
    TLUA_M_VNM(P2) = LuaStrictStack<P2>::get(L, pos++);
    TLUA_M_VNM(P3) = LuaStrictStack<P3>::get(L, pos++);
    TLUA_M_VNM(P4) = LuaStrictStack<P4>::get(L, pos++);
    TLUA_M_VNM(P5) = LuaStrictStack<P5>::get(L, pos++);
    TLUA_M_VNM(P6) = LuaStrictStack<P6>::get(L, pos++);
    TLUA_M_VNM(P7) = LuaStrictStack<P7>::get(L, pos++);
    TLUA_M_VNM(P8) = LuaStrictStack<P8>::get(L, pos++);
    TLUA_M_VNM(P9) = LuaStrictStack<P9>::get(L, pos++);
    TLUA_M_VNM(P10) = LuaStrictStack<P10>::get(L, pos++);
}

  virtual std::string getFormattedParameterValues() const
  {
    return
                 LuaStrictStack<P1>::getValStr(TLUA_M_VNM(P1))
        + ", " + LuaStrictStack<P2>::getValStr(TLUA_M_VNM(P2))
        + ", " + LuaStrictStack<P3>::getValStr(TLUA_M_VNM(P3))
        + ", " + LuaStrictStack<P4>::getValStr(TLUA_M_VNM(P4))
        + ", " + LuaStrictStack<P5>::getValStr(TLUA_M_VNM(P5))
        + ", " + LuaStrictStack<P6>::getValStr(TLUA_M_VNM(P6))
        + ", " + LuaStrictStack<P7>::getValStr(TLUA_M_VNM(P7))
        + ", " + LuaStrictStack<P8>::getValStr(TLUA_M_VNM(P8))
        + ", " + LuaStrictStack<P9>::getValStr(TLUA_M_VNM(P9))
        + ", " + LuaStrictStack<P10>::getValStr(TLUA_M_VNM(P10))
    ;
  }

#ifdef TUVOK_DEBUG_LUA_USE_RTTI_CHECKS
  static void buildTypeTable(lua_State* L)
  {
    int pos = 0;
    lua_newtable(L);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P1>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P2>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P3>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P4>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P5>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P6>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P7>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P8>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P9>(L); lua_settable(L, -3);
    lua_pushinteger(L, pos++); LSS_pushTypeInfo<P10>(L); lua_settable(L, -3);
  }
#endif

  typename LuaStrictStack<P1>::Type TLUA_M_VNM(P1);
  typename LuaStrictStack<P2>::Type TLUA_M_VNM(P2);
  typename LuaStrictStack<P3>::Type TLUA_M_VNM(P3);
  typename LuaStrictStack<P4>::Type TLUA_M_VNM(P4);
  typename LuaStrictStack<P5>::Type TLUA_M_VNM(P5);
  typename LuaStrictStack<P6>::Type TLUA_M_VNM(P6);
  typename LuaStrictStack<P7>::Type TLUA_M_VNM(P7);
  typename LuaStrictStack<P8>::Type TLUA_M_VNM(P8);
  typename LuaStrictStack<P9>::Type TLUA_M_VNM(P9);
  typename LuaStrictStack<P10>::Type TLUA_M_VNM(P10);
};

#undef TLUA_VNM
#undef TLUA_M_VNM

} /* namespace tuvok */

#endif /* LUAFUNBINDING_H_ */
