Boost logo

Boost Users :

Subject: [Boost-users] eval_if fails - problem for C++ guru
From: Robert Ramey (ramey_at_[hidden])
Date: 2015-06-06 22:22:48


I've been having a very difficult time with a problem illustrated by the
following program: It looks like the eval_if in line 51 isn't working
correctly. That is, the metafuction get_promotion_policy is being
invoked when both types are not safe types. I've been working on this
for two days and can't see what's going on. Any help from a TMP genious
would be much appreciated.

#include <type_traits>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>

struct safe_tag {};

template<class T, class P = void>
struct safe : public safe_tag {
     T m_t;
     typedef P PromotionPolicy;
};

template<class T>
struct is_safe : public
     //std::is_arithmetic<T>
     std::is_base_of<safe_tag, T>
{};

template<class T, class U>
struct common_policies {
     static_assert(
         boost::mpl::or_<
             is_safe<T>,
             is_safe<U>
>::value,
         "at least one type must be a safe type"
     );

     template<typename Z>
     struct get_promotion_policy {
         static_assert(
             is_safe<Z>::value,
             "only safe types have promotion policies"
         );
         typedef typename Z::PromotionPolicy type;
     };

     // if both types are safe, the policies have to be the same!
     static_assert(
         boost::mpl::eval_if<
             boost::mpl::and_<
                 is_safe<T>,
                 is_safe<U>
>,
             typename std::is_same<
                 typename get_promotion_policy<T>::type,
                 typename get_promotion_policy<U>::type
>::type,
             boost::mpl::identity<boost::mpl::true_>
>::type::value,
         "if both types are safe, the policies have to be the same!"
     );

     // now we've verified that there is no conflict between policies
     // return the one from the first safe type
     typedef typename boost::mpl::if_<
         is_safe<T>,
         T,
     typename boost::mpl::if_<
         is_safe<U>,
         U,
     //
         boost::mpl::void_
>::type
>::type safe_type;

     typedef typename get_promotion_policy<safe_type>::type
promotion_policy;

};

common_policies<int, safe<int> > t;

int main(){
     return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net