Search code examples
c++templatestestingconstantsconst-cast

Testing template based class with const template parameter which has to be varied


I am developing a template based library to support fixed point integers and I came up with this class and now I have to test it for various values of INT_BITS and FRAC_BITS. but since they are const (and they have to be so for a reason), I am unable to initialize objects with variable INT_BITS in a loop and hence it is making testing this library very difficult.

template<int INT_BITS, int FRAC_BITS>
struct fp_int
{
     public:
            static const int BIT_LENGTH = INT_BITS + FRAC_BITS;
            static const int FRAC_BITS_LENGTH = FRAC_BITS;
     private:
            // Value of the Fixed Point Integer 
            ValueType stored_val;
};

I tried a lot of tricks mentioned here , here and here. I tried using a std::vector of const int and const_cast but nothing seems to work.

I was wondering that that how do you test such libraries where the template parameter is a const for a large test values ?


Solution

  • You can simulate a for loop using template meta programming.

    #include <iostream>
    
    typedef int ValueType;
    
    template<int INT_BITS, int FRAC_BITS>
    struct fp_int
    {
       public:
          static const int BIT_LENGTH = INT_BITS + FRAC_BITS;
          static const int FRAC_BITS_LENGTH = FRAC_BITS;
       private:
          // Value of the Fixed Point Integer 
          ValueType stored_val = 0;
    };
    
    template <unsigned int N> struct ForLoop
    {
       static void testFpInt()
       {
          std::cout << "Testing fp_int<" << N << ", 2>\n";
          fp_int<N, 2> x;
          // Use x
    
          // Call the next level
          ForLoop<N-1>::testFpInt();
       }
    };
    
    // Terminating struct.
    template <> struct ForLoop<0>
    {
       static void testFpInt()
       {
          std::cout << "Testing fp_int<" << 0 << ", 2>\n";
          fp_int<0, 2> x;
          // Use x
       }
    };
    
    int main()
    {
       ForLoop<10>::testFpInt();
       return 0;
    }
    

    Output

    Testing fp_int<10, 2>
    Testing fp_int<9, 2>
    Testing fp_int<8, 2>
    Testing fp_int<7, 2>
    Testing fp_int<6, 2>
    Testing fp_int<5, 2>
    Testing fp_int<4, 2>
    Testing fp_int<3, 2>
    Testing fp_int<2, 2>
    Testing fp_int<1, 2>
    Testing fp_int<0, 2>
    

    You can find more information on the web by searching for "for loop using template metaprogramming".