4

In the following code from Boost library:

template<class T , class Enabler = void >
struct get_unit_value_impl
{
    static T value(const T &t)
    {
        return t;
    }
    typedef T result_type;
};

...

template<class T>
typename detail::get_unit_value_impl<T>::result_type get_unit_value(const T &t)
{
    return detail::get_unit_value_impl<T>::value(t);
}

The role of get_unit_value is unclear to me. What does it do? we pass something to it and it returns the same value. Why should someone wrap it into a structure? Does it do anything except for slowing down the run time?

This code is called from here:

template< class Fac1 = double >
struct rel_error
{
    const Fac1 m_eps_abs , m_eps_rel , m_a_x , m_a_dxdt;

    rel_error( Fac1 eps_abs , Fac1 eps_rel , Fac1 a_x , Fac1 a_dxdt )
    : m_eps_abs( eps_abs ) , m_eps_rel( eps_rel ) , m_a_x( a_x ) , m_a_dxdt( a_dxdt ) { }


    template< class T1 , class T2 , class T3 >
    void operator()( T3 &t3 , const T1 &t1 , const T2 &t2 ) const
    {
        using std::abs;
        set_unit_value( t3 , abs( get_unit_value( t3 ) ) / ( m_eps_abs + m_eps_rel * ( m_a_x * abs( get_unit_value( t1 ) ) + m_a_dxdt * abs( get_unit_value( t2 ) ) ) ) );
    }

    typedef void result_type;
};
torbani
  • 85
  • 5

1 Answers1

2

You forgot to copy one of the specializations:

template<class T , class Enabler = void >
struct get_unit_value_impl
{
    static T value(const T &t)
    {
        return t;
    }
    typedef T result_type;
};

#ifndef __CUDACC__
template<class Unit , class T>
struct get_unit_value_impl< boost::units::quantity< Unit , T> >
{
    static T value( const boost::units::quantity< Unit , T> &t )
    {
        return t.value();
    }
    typedef T result_type;
};
#endif

The point get_unit_value() is to take in either a value and return it, or a boost::unit::quantity<Unit, T> and return the value off of it. That way, the caller doesn't need to worry about if t is just an int or something more complicated:

int x = 7;
quantity<length> L = 2.0*meters;

get_unit_value(x); // 7
get_unit_value(L); // 2.0
Barry
  • 247,587
  • 26
  • 487
  • 819
  • Thank you very much. Now, I understand the purpose better. Still it is not fully clear. What I perceived from the that is if there is no CUDA ACCelerator, then take `value` of the argument? But if there is CUDA ACC dont do that? but why? – torbani Feb 10 '15 at 12:16
  • @torbani That I cannot say. I don't know anything about CUDA and why that function is unimplemented in that case. I can just say why it exists in general. – Barry Feb 10 '15 at 12:19
  • @torbani The CUDA compiler is notorious for breaking at the sight of any Boost header; I guess somebody tried to be defensive on Boost's side. – DanielKO Feb 10 '15 at 14:48
  • 1
    I don't understand the problem with Cuda. Can you explained it in more detail if there is a problem. Barry is right, we only introduced it, to ensure compatibility with Boost.Units. – headmyshoulder Feb 10 '15 at 14:54