updates of manual and examples

This commit is contained in:
Robert Ramey
2015-12-07 21:46:39 -08:00
parent 004149ee1d
commit 96f829bfe4
22 changed files with 279 additions and 391 deletions

View File

@@ -3,10 +3,46 @@
#include <ostream>
#include <iostream>
#include <cxxabi.h>
#include <typeinfo>
#include "../include/safe_range.hpp"
#include "../include/automatic.hpp"
// create an output manipulator which prints variable type and limits
// as well as value
template<typename T>
struct formatted_impl {
const T & m_t;
formatted_impl(const T & t) :
m_t(t)
{}
template <class charT, class Traits>
friend std::basic_ostream<charT,Traits> &
operator<<(
std::basic_ostream<charT,Traits> & os,
const formatted_impl<T> & f
){
int status;
return os
<< "<"
<< abi::__cxa_demangle(
typeid(boost::numeric::base_value(m_t)).name(),0,0,&status
)
<< ">["
<< std::numeric_limits<T>::min() << ","
<< std::numeric_limits<T>::max() << "] = "
<< f.m_t;
}
};
template<typename T>
auto formatted(const T & t){
return formatted_impl<T>(t);
}
// create a type for holding small integers which implement automatic
// type promotion to larger types to guarentee correct results with
// zero runtime overhead !
template <
std::intmax_t Min,
std::intmax_t Max
@@ -17,64 +53,21 @@ using safe_t = boost::numeric::safe_signed_range<
boost::numeric::automatic,
boost::numeric::throw_exception
>;
// I can't figure out how to overload os << for safe_t
// we use the following workaround there
// wrap a safe_t in a "formatted" wrapper
template<typename T>
struct formatted {
using wrapped_type = T;
const T & m_t;
formatted(const T & t) :
m_t(t)
{}
};
template<typename T>
auto make_formatted(const T & t){
return formatted<T>(t);
}
// now (fully) specialize output of safe types wrapped in formatted
template<
class T,
T Min,
T Max,
class P, // promotion polic
class E // exception policy
>
std::ostream & operator<<(
std::ostream & os,
const formatted<boost::numeric::safe_base<T, Min, Max, P, E>> & f
){
using safe_type = typename formatted<boost::numeric::safe_base<T, Min, Max, P, E> >::wrapped_type;
return os
<< "["
<< std::numeric_limits<safe_type>::min() << ","
<< std::numeric_limits<safe_type>::max() << "] = "
<< f.m_t;
}
using small_integer_t = safe_t<-24, 82>;
int main(int argc, const char * argv[]){
// problem: checking of externally produced value can be overlooked
std::cout << "example 8: ";
std::cout << "eliminate runtime overhead"
<< std::endl;
std::cout << "eliminate runtime overhead" << std::endl;
try{
int status;
const safe_t<-64, 63> x(1);
std::cout << abi::__cxa_demangle(typeid(x).name(),0,0,&status) << '\n';
std::cout << "x" << make_formatted(x) << std::endl;
safe_t<-64, 63> y;
y = 2;
std::cout << "y" << make_formatted(y) << std::endl;
auto z = x + y;
std::cout << "(x + y)" << make_formatted(z) << std::endl;
std::cout << "(x - y)" << make_formatted(x - y) << std::endl;
const small_integer_t x(1);
std::cout << "x" << formatted(x) << std::endl;
small_integer_t y = 2;
std::cout << "y" << formatted(y) << std::endl;
auto z = x + y; // zero runtime overhead !
std::cout << "(x + y)" << formatted(z) << std::endl;
std::cout << "(x - y)" << formatted(x - y) << std::endl;
}
catch(std::exception e){
// none of the above should trap. Mark failure if they do