Listing 4

template <
  class T, u32 N, u32 MinListIdxN, 
  class MajNListT, class MinNListT>
struct CofactorRecursor
{
  enum {
    eMajIdx = MajNListT::value,
    eMinIdx = NL::NumAt<
      MinNListT, MinListIdxN>::value,

    eNextMinListIdx = MinListIdxN - 1,
  };

  typedef typename NL::Erase<
    MajNListT, eMajIdx>::Result  RemMajNListT;

  typedef typename NL::Erase<
    MinNListT, eMinIdx>::Result  RemMinNListT;

  static T
  Evaluate(const VectT majors[N])
  { 
    T det = CofactorRecursor<
        T,N,eNextMinListIdx,MajNListT,MinNListT
      >::Evaluate(majors);
      
    T minor = DetEvaluator<
        T,N,RemMajNListT,RemMinNListT
      >::Evaluate(majors);

    T prod = (majors[eMajIdx][eMinIdx] * minor);
    
    return ((MinListIdxN % 2) == 1)
      ? (det - prod) : (det + prod);
  }
};

template <
  class T, u32 N,
  class MajNListT, class MinNListT
>
struct CofactorRecursor<
  T,N,0,MajNListT,MinNListT
>
{
  enum {
    eMajIdx = MajNListT::value,
    eMinIdx = NL::NumAt<MinNListT, 0>::value,
  };

  typedef typename NL::Erase<
    MajNListT, eMajIdx>::Result  RemMajNListT;
    
  typedef typename NL::Erase<
    MinNListT, eMinIdx>::Result  RemMinNListT;

  static T
  Evaluate(const VectT majors[N])
  { 
    T minor = DetEvaluator<
        T, N, RemMajNListT, RemMinNListT
      >::Evaluate(majors);

    return majors[eMajIdx][eMinIdx] * minor;
  }
};