Jump to content
samng

template class with sc_fixed

Recommended Posts

Hi

 

sc_fixed type looks ahead to the type of the destination variable to pick the right action for quatisation and overflow handling:

 

sc_fixed<6,6> a = 13;

sc_fixed<5,5,SC_RND> b  = a>>1;

 

a become 7.

 

But using sc_fixed in a template class like:

 

template <class T, int N> class Vector {

     T m_array[N];

 

     Vector operator>> (const unisgned int m) const {

          Vector tmp;

          for (int i=0; i<N; i++)

             tmp.m_array = m_array>>m;

     }

};

 

.....

 

Vector <sc_fixed<6,6>,1 > a;

Vector <sc_fixed<5,5,SC_RND>,1 > b = a >> 1;

 

a[0] is now 6 not 7, because the return type of operator >> is still Vector<sc_fixed<6,6>,1 >.

 

Is there anyway to write the template class/operator that can see the type of b so that sc_fixed rounding behaviour can preserved?

 

Thanks

Sam

 

 

 

Share this post


Link to post
Share on other sites

Sam,

 

sc_fixed type looks ahead to the type of the destination variable to pick the right action for quatisation and overflow handling:

 

That's not fully correct.  In C++, you can't (directly) consider the return-type of a function (e.g: for overloading) to adapt the behaviour.  You need to resort to intermediate values instead.  In case of sc_fix(ed)/sc_fxnum, this intermediate value is sc_fxval, a variable-precision fixed-point value.  Objects of this type always carry the required amount of bits during run-time and the assignment to another finite-precision type (sc_fxnum et.al.) handles the quantisation and overflow.

 

Is there anyway to write the template class/operator that can see the type of b so that sc_fixed rounding behaviour can preserved?

 

AFAICS, you want to build a container class template for arithmetic types that provides element-wise operators.  In order to deal with such intermediate values, there are several options depending on the level of generality you need to achieve and the constraints on the C++ language features, you can rely on.  Disclaimer: The following snippets are fully untested.

 

Simplest solution: Return a Vector<sc_fxval> instead (and provide an appropriate assignment operator/conversion constructor):

     Vector<sc_fxval,N> operator>> (unsigned m) const {
          Vector<sc_fxval,N> tmp;
          for (int i=0; i<N; i++)
             tmp.m_array[i] = m_array[i]>>m;
          return tmp;
     }

Of course, this will limit the use of this shift operator in your Vector template to classes, where the result of the  shift operator on the elements can be reasonably converted to sc_fxval.

 

As a second option, you can use C++11's  decltype and new function declaration syntax:

 

     auto operator>> (unsigned m) const -> Vector< decltype(T() >> m), N > {
          typedef decltype( T() >> m ) return_type;
          Vector<return_type,N> tmp;
          for (int i=0; i<N; i++)
             tmp.m_array[i] = m_array[i]>>m;
          return tmp;
     }

This should work correctly for arbitrary shift operators and return an array of shift results.

Since your compiler may not support these shiny new features of C++11, you can use a traits class with (partial) specialisation:

 

template< typename T > struct vector_element_traits;

// partial specialisation for sc_fixed
template< int WordLength, int IntegerWordLength, sc_o_mode Overflow, sc_q_mode Quantization >
struct vector_element_traits< sc_fixed<WordLength, IntegerWordLength, Overflow, Quantization > >
{
  typedef sc_fxval right_shift_result;
};

// ...

Vector<typename vector_element_traits<T>::right_shift_result,N> operator>> (unsigned m) const {
    Vector<typename vector_element_traits<T>::right_shift_result,N> > tmp;
    for (int i=0; i<N; i++)
        tmp.m_array[i] = m_array[i]>>m;
    return tmp;
}

 

Last but not least, you can defer the evaluation of the element-wise operator by using expression templates to the implementation of the assignment operator of the vector.  But this may be a bit too advanced for tonight. ;-)

 

Greetings from Oldenburg,
  Philipp

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×