153 lines
3.8 KiB
C++
153 lines
3.8 KiB
C++
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See
|
|
// accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
|
|
|
|
//
|
|
// NOTE: This file is intended to be used ONLY by the test files
|
|
// from the Numeric Conversions Library
|
|
//
|
|
//
|
|
#include <cmath>
|
|
|
|
#include "boost/limits.hpp"
|
|
#include "boost/utility.hpp"
|
|
|
|
#include "boost/test/included/test_exec_monitor.hpp"
|
|
|
|
// Convenience macros to help with compilers which don't parse
|
|
// explicit template function instantiations (MSVC6)
|
|
#define MATCH_FNTPL_ARG(t) t const*
|
|
#define SET_FNTPL_ARG(t) (static_cast< t const* >(0))
|
|
|
|
//
|
|
// *Minimal* example of a User Defined Numeric Type
|
|
//
|
|
//
|
|
namespace MyUDT
|
|
{
|
|
|
|
template<class T>
|
|
struct UDT
|
|
{
|
|
typedef T builtin_type ;
|
|
|
|
UDT ( T v_ ) : v (v_) {}
|
|
|
|
T to_builtin() const { return v ; }
|
|
|
|
friend bool operator == ( UDT const& lhs, UDT const& rhs )
|
|
{ return lhs.to_builtin() == rhs.to_builtin() ; }
|
|
|
|
// NOTE: This operator is *required* by the Numeric Conversion Library
|
|
// if Turnc<> is used as the Float2IntRounder policy.
|
|
friend bool operator < ( UDT const& lhs, UDT const& rhs )
|
|
{ return lhs.to_builtin() < rhs.to_builtin() ; }
|
|
|
|
friend std::ostream& operator << ( std::ostream& os, UDT const& n )
|
|
{ return os << n.to_builtin() ; }
|
|
|
|
T v ;
|
|
} ;
|
|
|
|
typedef UDT<int> MyInt ;
|
|
typedef UDT<double> MyFloat ;
|
|
|
|
//
|
|
// The Float2IntRounder policies *require* a visible 'ceil' or 'floor' math function
|
|
// with standard semantics.
|
|
// In a conformant compiler, ADL can pick these functions even if they are defined
|
|
// within a user namespace, as below.
|
|
//
|
|
inline MyInt ceil ( MyInt const& x ) { return x ; }
|
|
inline MyInt floor ( MyInt const& x ) { return x ; }
|
|
|
|
inline MyFloat floor ( MyFloat const& x )
|
|
{
|
|
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
|
return MyFloat ( std::floor(x.to_builtin()) ) ;
|
|
#else
|
|
return MyFloat ( ::floor(x.to_builtin()) ) ;
|
|
#endif
|
|
}
|
|
|
|
inline MyFloat ceil ( MyFloat const& x )
|
|
{
|
|
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
|
return MyFloat ( std::ceil(x.to_builtin()) ) ;
|
|
#else
|
|
return MyFloat ( ::ceil(x.to_builtin()) ) ;
|
|
#endif
|
|
}
|
|
|
|
} // namespace MyUDT
|
|
|
|
|
|
//
|
|
// The Numeric Conversion Library *requires* User Defined Numeric Types
|
|
// to properly specialize std::numeric_limits<>
|
|
//
|
|
namespace std
|
|
{
|
|
|
|
template<>
|
|
class numeric_limits<MyUDT::MyInt> : public numeric_limits<int>
|
|
{
|
|
public :
|
|
|
|
BOOST_STATIC_CONSTANT(bool, is_specialized = false);
|
|
} ;
|
|
|
|
template<>
|
|
class numeric_limits<MyUDT::MyFloat> : public numeric_limits<double>
|
|
{
|
|
public :
|
|
|
|
BOOST_STATIC_CONSTANT(bool, is_specialized = false);
|
|
} ;
|
|
|
|
} // namespace std
|
|
|
|
|
|
|
|
//
|
|
// The functions floor and ceil defined within namespace MyUDT
|
|
// should be found by koenig loopkup, but some compilers don't do it right
|
|
// so we inyect them into namespace std so ordinary overload resolution
|
|
// can found them.
|
|
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || defined(BOOST_BORLANDC) || defined(__GNUC__)
|
|
namespace std {
|
|
using MyUDT::floor ;
|
|
using MyUDT::ceil ;
|
|
} // namespace std
|
|
#endif
|
|
|
|
|
|
std::string to_string( bool arg )
|
|
{
|
|
return arg ? "true" : "false" ;
|
|
}
|
|
|
|
std::string to_string( ... ) { throw std::runtime_error("to_string() called with wrong type!") ; }
|
|
|
|
//
|
|
// This is used to print 'char' values as numbers instead of characters.
|
|
//
|
|
template<class T> struct printable_number_type { typedef T type ; } ;
|
|
template<> struct printable_number_type<signed char> { typedef int type ; } ;
|
|
template<> struct printable_number_type<unsigned char> { typedef unsigned type ; } ;
|
|
template<> struct printable_number_type<char> { typedef int type ; } ;
|
|
|
|
template<class T>
|
|
inline
|
|
typename printable_number_type<T>::type
|
|
printable( T n ) { return n ; }
|
|
|
|
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|