2015-02-23 15 views
5

Così ho la mia propria politica per uint64_t a uint32_t fusione numericoCome si usa una politica numeric_cast?

struct MyOverflowHandlerPolicy 
{ 
    void operator() (boost::numeric::range_check_result) { 
     std::cout << "MyOverflowHandlerPolicy called" << std::endl; 
     throw boost::numeric::positive_overflow(); 
    }; 
} ; 

Come faccio a farlo per essere utilizzati da boost :: numeric_cast?

risposta

6

Per utilizzare numeric_cast, la specializzazione numeric_cast_traits deve essere definita per ogni conversione di tipo. Queste specializzazioni sono già definite con valori predefiniti per i tipi numerici incorporati. È possibile disabilitare la generazione di specializzazioni per i tipi predefiniti definendo BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS (details).

Ecco un piccolo campione in esecuzione.

#include <iostream> 
#include <stdexcept> 

#define BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS 
#include <boost/numeric/conversion/cast.hpp> 

using namespace std; 

struct YourOverflowHandlerPolicy 
{ 
    void operator() (boost::numeric::range_check_result r) { 
     cout << "YourOverflowHandlerPolicy called" << endl; 
     if (r != boost::numeric::cInRange) { 
      throw logic_error("Not in range!"); 
     } 
    }; 
}; 

namespace boost { namespace numeric { 
template <> 
struct numeric_cast_traits<uint32_t, uint64_t> 
{ 
    typedef YourOverflowHandlerPolicy overflow_policy; 
    typedef UseInternalRangeChecker range_checking_policy; 
    typedef Trunc<uint64_t>   rounding_policy; 
}; 

template <> 
struct numeric_cast_traits<uint64_t, uint32_t> 
{ 
    typedef YourOverflowHandlerPolicy overflow_policy; 
    typedef UseInternalRangeChecker range_checking_policy; 
    typedef Trunc<uint32_t>   rounding_policy; 
}; 
}} //namespace boost::numeric; 

int main() 
{ 
    try { 
     cout << boost::numeric_cast<uint32_t>((uint64_t)1) << endl; // OK 
     cout << boost::numeric_cast<uint32_t>((uint64_t)1<<31) << endl; // OK 
     cout << boost::numeric_cast<uint32_t>((uint64_t)1<<32) << endl; // Exception 
    } catch (...) { 
     cout << "exception" << endl; 
    } 

    return 0; 
} 

uscita:

YourOverflowHandlerPolicy called 
1 
YourOverflowHandlerPolicy called 
2147483648 
YourOverflowHandlerPolicy called 
exception 

Nota: Ho rilascio spinta 1.55.0, non so il livello minimo rilascio per farlo compilato ma non viene compilato con 1.46.0. Quindi, controlla la tua versione di boost e aggiorna se necessario.