mirror of
https://github.com/boostorg/numeric_conversion.git
synced 2026-07-21 13:33:43 +00:00
Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 50a1eae942 | |||
| 7c846ddf63 | |||
| 902588b6bd | |||
| 95c9f7f918 | |||
| db44689f4f | |||
| 1bc71b7971 | |||
| f9397e9cba | |||
| ccb153a506 | |||
| 07d5e56494 | |||
| 8c30716176 | |||
| 6c83ad8c57 | |||
| aab2ea1fed | |||
| 1d856f673f | |||
| de92292140 | |||
| 53de752e1f | |||
| a83247065b | |||
| a4d54f8f89 | |||
| a8467a8723 | |||
| 721dc89e7f | |||
| 36f969a4c5 | |||
| b900379a74 | |||
| 8ad516370a | |||
| c993894676 | |||
| 1da5d0d8fe | |||
| 5a45a8d824 | |||
| 3ae7d59e7a | |||
| 54d571dde2 | |||
| 4505bc3808 | |||
| 7f3a74cb74 | |||
| 278025d9c6 | |||
| 7436ca7113 | |||
| ebfded1d7d | |||
| c9d7a49b4a | |||
| 2009f0d4fc | |||
| 736745061d | |||
| 593aafab5a | |||
| a6681748be | |||
| d6ec138927 | |||
| 30d2e6d9f6 | |||
| d76eb6fa72 | |||
| c90517da96 | |||
| 907ae79790 | |||
| f4c6bd9711 | |||
| 86f8af551c | |||
| cda4506afe | |||
| 718767f1e6 | |||
| 26218a6e86 | |||
| 69a46fea8a | |||
| 056045e503 | |||
| d4a8c7049a | |||
| e6fa2c4b6d | |||
| 0fc4c240b9 | |||
| de94a311a3 | |||
| c9e3ffd511 | |||
| e7b5847b5a | |||
| fcb73eb616 | |||
| 238b6ab769 | |||
| 0ab23addef | |||
| 5d344f7463 | |||
| 6bd888475f | |||
| 4c8e454bbb | |||
| 507d157d10 | |||
| 41473987e5 | |||
| 8312050b36 | |||
| 3526c08afc | |||
| 7e74dc080e | |||
| ca4de5c31d | |||
| 3d44e92088 | |||
| fe862ee762 | |||
| 947af90dbf | |||
| d434655b08 | |||
| 5a345e2993 | |||
| 0047a2d734 | |||
| 00311d7276 | |||
| 8a0a8727b9 | |||
| a05ae1dc97 | |||
| dce3963075 | |||
| 20de9917e6 | |||
| e0eee93fa5 | |||
| 3c72670b7f | |||
| d6e932c038 | |||
| 5963a9cb67 | |||
| 79760962d1 | |||
| 67e2ca29bc | |||
| 225b672e44 | |||
| abb1d17829 | |||
| 128e01f1ea | |||
| 6dc956e342 | |||
| daadef8d1a | |||
| ccffeecc40 | |||
| 2994de17ef | |||
| 7435918580 | |||
| 9487756e4b | |||
| 35a5859da6 | |||
| 1ed1b2090e | |||
| 5fb09c0c83 | |||
| 9264998bb1 | |||
| 0f0a2cecd4 | |||
| f88653b718 | |||
| 1e17922c45 | |||
| d2652525b8 | |||
| 62dd549c9e |
@@ -0,0 +1,235 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
|
||||
env:
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
LIBRARY: numeric/conversion
|
||||
|
||||
jobs:
|
||||
posix:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: g++-4.8-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-5
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: g++-5-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-6
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: g++-6-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: g++-7-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-8
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-8-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-9-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-10-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-11
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-20.04
|
||||
install: g++-11-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-12
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install: g++-12-multilib
|
||||
address-model: 32,64
|
||||
- toolset: clang
|
||||
compiler: clang++-3.9
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: clang-3.9
|
||||
- toolset: clang
|
||||
compiler: clang++-4.0
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: clang-4.0
|
||||
- toolset: clang
|
||||
compiler: clang++-5.0
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: clang-5.0
|
||||
- toolset: clang
|
||||
compiler: clang++-6.0
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-20.04
|
||||
install: clang-6.0
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-20.04
|
||||
install: clang-7
|
||||
- toolset: clang
|
||||
compiler: clang++-8
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-20.04
|
||||
install: clang-8
|
||||
- toolset: clang
|
||||
compiler: clang++-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-9
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
compiler: clang++-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
compiler: clang++-12
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
compiler: clang++-13
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install: clang-13
|
||||
- toolset: clang
|
||||
compiler: clang++-14
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install: clang-14
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-11
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
container: ${{matrix.container}}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup container environment
|
||||
if: matrix.container
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get -y install sudo python git g++
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt-get -y install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
- name: Create user-config.jam
|
||||
if: matrix.compiler
|
||||
run: |
|
||||
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.0
|
||||
cxxstd: 14,latest
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.3
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: clang-win
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: gcc
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
addrmd: 64
|
||||
os: windows-2019
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY:/=\%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by `boostdep --cmake numeric~conversion`
|
||||
# Copyright 2020 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(boost_numeric_conversion VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_numeric_conversion INTERFACE)
|
||||
add_library(Boost::numeric_conversion ALIAS boost_numeric_conversion)
|
||||
|
||||
target_include_directories(boost_numeric_conversion INTERFACE include)
|
||||
|
||||
target_link_libraries(boost_numeric_conversion
|
||||
INTERFACE
|
||||
Boost::config
|
||||
Boost::conversion
|
||||
Boost::core
|
||||
Boost::mpl
|
||||
Boost::preprocessor
|
||||
Boost::throw_exception
|
||||
Boost::type_traits
|
||||
)
|
||||
|
||||
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# Boost.NumericConversion
|
||||
|
||||
The Boost Numeric Conversion library is a collection of tools to describe and perform conversions between values of different [numeric types][1].
|
||||
|
||||
The documentation for the library can be found [here][2]
|
||||
|
||||
[1]: http://www.boost.org/doc/libs/release/libs/numeric/conversion/doc/html/boost_numericconversion/definitions.html#boost_numericconversion.definitions.numeric_types
|
||||
[2]: http://www.boost.org/doc/libs/release/libs/numeric/conversion/doc/html/index.html#numeric_conversion.overview
|
||||
@@ -0,0 +1,36 @@
|
||||
# Boost.Numeric/Conversion
|
||||
#
|
||||
# Copyright (c) 2004-2007 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)
|
||||
|
||||
|
||||
# Quickbook
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import quickbook ;
|
||||
|
||||
path-constant images : html ;
|
||||
|
||||
|
||||
xml conversion
|
||||
:
|
||||
conversion.qbk
|
||||
;
|
||||
|
||||
boostbook standalone
|
||||
:
|
||||
conversion
|
||||
:
|
||||
<xsl:param>boost.root=../../../../..
|
||||
<xsl:param>html.stylesheet=boostbook.css
|
||||
<xsl:param>toc.max.depth=2
|
||||
<xsl:param>toc.section.depth=2
|
||||
<xsl:param>chunk.section.depth=1
|
||||
<format>pdf:<xsl:param>img.src.path=$(images)/
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/numeric/conversion/doc/html
|
||||
;
|
||||
|
||||
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - Bounds</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TH VALIGN="top" WIDTH="300">
|
||||
<H3><A HREF="../../../../index.htm"><IMG HEIGHT="86" WIDTH="277"
|
||||
ALT="C++ Boost" SRC="../../../../boost.png" BORDER="0"></A></H3> </TH>
|
||||
<TH VALIGN="top">
|
||||
<H1 ALIGN="center">Boost Numeric Conversion Library</H1>
|
||||
|
||||
<H1><A HREF="http://www.boost.org">Header </A><A
|
||||
HREF="../../../../boost/numeric/conversion/bounds.hpp">boost/numeric/conversion/bounds.hpp</A></H1>
|
||||
</TH>
|
||||
</TR>
|
||||
</TABLE><HR>
|
||||
<H2>Contents</H2>
|
||||
<UL>
|
||||
<LI><A HREF="#introduction">Introduction</A></LI>
|
||||
<LI><A HREF="#bounds"><code>template class bounds<N></CODE></A></LI>
|
||||
<LI><A HREF="#examples">Examples</A></LI>
|
||||
<!--<LI><A HREF="#implementation">Implementation</A></LI>-->
|
||||
<!--<LI><A HREF="#portability">Portability</A></LI>-->
|
||||
</UL> <HR>
|
||||
<H2><A NAME="introduction">Introduction</A></H2>
|
||||
<P>To determine the ranges of numeric types with std:: numeric_limits
|
||||
[18.2.1], different syntax have to be used depending on numeric type.
|
||||
Specifically, numeric_limits<T>::min() for integral types returns the
|
||||
minimum finite value, whereas for floating point types it returns the minimum
|
||||
positive normalized value. The difference in semantics makes client code
|
||||
unnecessarily complex and error prone. <BR> <BR>
|
||||
boost::numeric::bounds<> provides a consistent interface for retrieving
|
||||
the maximum finite value, the minimum finite value and the minimum positive
|
||||
normalized value (0 for integral types) for numeric types. The selection of
|
||||
implementation is performed at compile time, so there is no runtime overhead.
|
||||
<BR>
|
||||
<BR> </P> <HR>
|
||||
<H2><A NAME="bounds"><CODE>traits class bounds<N></CODE></A></H2>
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<PRE>template<class N>
|
||||
struct bounds
|
||||
{
|
||||
static N lowest () { return <i>implementation_defined</i>; }
|
||||
static N highest () { return <i>implementation_defined</i>; }
|
||||
static N smallest() { return <i>implementation_defined</i>; }
|
||||
};</PRE>
|
||||
</BLOCKQUOTE>
|
||||
<H3>Members</H3>
|
||||
<PRE>lowest()</PRE>
|
||||
<P>Returns the minimum finite value, equivalent to
|
||||
numeric_limits<T>::min() when T is an integral type, and to
|
||||
-numeric_limits<T>::max() when T is a floating point type. </P>
|
||||
<PRE>highest()</PRE>
|
||||
<P>Returns the maximum finite value, equivalent to
|
||||
numeric_limits<T>::max(). </P>
|
||||
<PRE>smallest()</PRE>
|
||||
|
||||
<P>Returns the smallest positive normalized value for floating point types with
|
||||
denormalization, or returns 0 for integral types. <BR>
|
||||
<BR>
|
||||
</P> <HR>
|
||||
<H2><A NAME="examples">Examples</A></H2>
|
||||
|
||||
<P>The following example demonstrates the use of numeric::bounds<> and the
|
||||
equivalent code using numeric_limits: </P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<PRE>#include <iostream>
|
||||
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
int main() {
|
||||
|
||||
std::cout << "numeric::bounds versus numeric_limits example.\n";
|
||||
|
||||
std::cout << "The maximum value for float:\n";
|
||||
std::cout << boost::numeric::bounds<float>::highest() << "\n";
|
||||
std::cout << std::numeric_limits<float>::max() << "\n";
|
||||
|
||||
std::cout << "The minimum value for float:\n";
|
||||
std::cout << boost::numeric::bounds<float>::lowest() << "\n";
|
||||
std::cout << -std::numeric_limits<float>::max() << "\n";
|
||||
|
||||
std::cout << "The smallest positive value for float:\n";
|
||||
std::cout << boost::numeric::bounds<float>::smallest() << "\n";
|
||||
std::cout << std::numeric_limits<float>::min() << "\n";
|
||||
|
||||
return 0;
|
||||
}</PRE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<hr>
|
||||
<P>Back to <A HREF="index.html">Numeric Conversion library index</A></P>
|
||||
<HR>
|
||||
<P>Revised 23 June 2004</P>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</BODY>
|
||||
</HTML>
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 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)
|
||||
]
|
||||
|
||||
[section bounds<> traits class]
|
||||
|
||||
[section Introduction]
|
||||
|
||||
To determine the ranges of numeric types with `std::numeric_limits` \[18.2.1\],
|
||||
different syntax have to be used depending on numeric type. Specifically,
|
||||
`numeric_limits<T>::min()` for integral types returns the minimum finite value,
|
||||
whereas for floating point types it returns the minimum positive normalized
|
||||
value. The difference in semantics makes client code unnecessarily complex
|
||||
and error prone.
|
||||
|
||||
`boost::numeric::bounds<>` provides a consistent interface for retrieving the
|
||||
maximum finite value, the minimum finite value and the minimum positive normalized
|
||||
value (0 for integral types) for numeric types. The selection of implementation
|
||||
is performed at compile time, so there is no runtime overhead.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section traits class bounds<N>]
|
||||
|
||||
template<class N>
|
||||
struct bounds
|
||||
{
|
||||
static N lowest () { return implementation_defined; }
|
||||
static N highest () { return implementation_defined; }
|
||||
static N smallest() { return implementation_defined; }
|
||||
};
|
||||
|
||||
[heading Members]
|
||||
|
||||
|
||||
[: `lowest()` ]
|
||||
|
||||
Returns the minimum finite value, equivalent to `numeric_limits<T>::min()` when `T`
|
||||
is an integral type, and to `-numeric_limits<T>::max()` when `T` is a floating point type.
|
||||
|
||||
[: `highest()` ]
|
||||
|
||||
Returns the maximum finite value, equivalent to `numeric_limits<T>::max()`.
|
||||
|
||||
[: `smallest()` ]
|
||||
|
||||
Returns the smallest positive normalized value for floating point types with
|
||||
denormalization, or returns 0 for integral types.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
|
||||
The following example demonstrates the use of `numeric::bounds<>` and the
|
||||
equivalent code using `numeric_limits`:
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
int main() {
|
||||
|
||||
std::cout << "numeric::bounds versus numeric_limits example.\n";
|
||||
|
||||
std::cout << "The maximum value for float:\n";
|
||||
std::cout << boost::numeric::bounds<float>::highest() << "\n";
|
||||
std::cout << std::numeric_limits<float>::max() << "\n";
|
||||
|
||||
std::cout << "The minimum value for float:\n";
|
||||
std::cout << boost::numeric::bounds<float>::lowest() << "\n";
|
||||
std::cout << -std::numeric_limits<float>::max() << "\n";
|
||||
|
||||
std::cout << "The smallest positive value for float:\n";
|
||||
std::cout << boost::numeric::bounds<float>::smallest() << "\n";
|
||||
std::cout << std::numeric_limits<float>::min() << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
[library Boost.NumericConversion
|
||||
[quickbook 1.4]
|
||||
[authors [Cacciola Carballal, Fernando Luis]]
|
||||
[copyright 2004-2007 Fernando Luis Cacciola Carballal]
|
||||
[category numerics]
|
||||
[id numeric_conversion]
|
||||
[dirname numeric_conversion]
|
||||
[purpose
|
||||
Optimized Policy-based Numeric Conversions
|
||||
]
|
||||
[source-mode c++]
|
||||
[license
|
||||
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])
|
||||
]
|
||||
]
|
||||
|
||||
[/ Macros will be used for links so we have a central place to change them ]
|
||||
|
||||
|
||||
[/ Cited Boost resources ]
|
||||
|
||||
[def __MPL_INTEGRAL_CONSTANT__ [@../../../../mpl/doc/refmanual/integral-constant.html MPL's Integral Constant] ]
|
||||
|
||||
|
||||
|
||||
[/ Other web resources ]
|
||||
|
||||
[def __SGI_UNARY_FUNCTION__ [@http://www.sgi.com/tech/stl/UnaryFunction.html Unary Function Object]]
|
||||
|
||||
[/ Icons ]
|
||||
|
||||
[def __NOTE__ [$images/note.png]]
|
||||
[def __ALERT__ [$images/caution.png]]
|
||||
[def __DETAIL__ [$images/note.png]]
|
||||
[def __TIP__ [$images/tip.png]]
|
||||
[def __QUESTION_MARK__ [$images/question.png]]
|
||||
[def __SPACE__ [$images/space.png]]
|
||||
[def __GO_TO__ [$images/callouts/R.png]]
|
||||
|
||||
|
||||
|
||||
|
||||
[section Overview]
|
||||
|
||||
The Boost Numeric Conversion library is a collection of tools to describe and
|
||||
perform conversions between values of different
|
||||
[link boost_numericconversion.definitions.numeric_types numeric types].
|
||||
|
||||
The library includes a special alternative for a subset of `std::numeric_limits<>`,
|
||||
the [link boost_numericconversion.bounds___traits_class bounds<>] traits class, which provides
|
||||
a consistent way to obtain the [link boost_numericconversion.definitions.range_and_precision boundary]
|
||||
values for the [link boost_numericconversion.definitions.range_and_precision range] of a numeric type.
|
||||
|
||||
It also includes a set of [link boost_numericconversion.conversion_traits___traits_class trait classes]
|
||||
which describes the compile-time
|
||||
properties of a conversion from a source to a target numeric type.
|
||||
Both [link boost_numericconversion.definitions.c___arithmetic_types arithmetic] and
|
||||
[link boost_numericconversion.definitions.numeric_types user-defined numeric types] can be used.
|
||||
|
||||
A policy-based [link boost_numericconversion.converter___function_object converter] object which
|
||||
uses `conversion_traits` to select
|
||||
an optimized implementation is supplied. Such implementation uses an optimal
|
||||
range checking code suitable for the source/target combination.
|
||||
|
||||
* The converter's out-of-range behavior can be customized via an
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler OverflowHandler] policy.
|
||||
* For floating-point to integral conversions, the rounding mode can be selected via the
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder Float2IntRounder] policy.
|
||||
* A custom low-level conversion routine (for UDTs for instance) can be passed via a
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter RawConverter] policy.
|
||||
* The optimized automatic range-checking logic can be overridden via a
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker UserRangeChecker] policy.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[include definitions.qbk]
|
||||
[include converter.qbk]
|
||||
[include requirements.qbk]
|
||||
[include bounds.qbk]
|
||||
[include conversion_traits.qbk]
|
||||
[include converter_policies.qbk]
|
||||
[include numeric_cast.qbk]
|
||||
|
||||
|
||||
|
||||
[section History and Acknowledgments]
|
||||
|
||||
|
||||
[heading Pre-formal review]
|
||||
|
||||
* Kevlin Henney, with help from David Abrahams and Beman Dawes, originally contributed
|
||||
the previous version of `numeric_cast<>` which already presented the idea of a runtime
|
||||
range check.
|
||||
|
||||
* Later, Eric Ford, Kevin Lynch and the author spotted some genericity problems with
|
||||
that `numeric_cast<>` which prevented it from being used in a generic layer of math
|
||||
functions.
|
||||
|
||||
* An improved `numeric_cast<>` which properly handled all combinations of arithmetic
|
||||
types was presented.
|
||||
|
||||
* David Abrahams and Beman Dawes acknowledged the need of an improved version of
|
||||
`numeric_cast<>` and supported the submission as originally laid out. Daryl Walker and
|
||||
Darin Adler made some important comments and proposed fixes to the original submission.
|
||||
|
||||
* Special thanks go to Björn Karlsoon who helped the author considerably. Having found the
|
||||
problems with `numeric_cast<>` himself, he revised very carefully the original submission
|
||||
and spot a subtle bug in the range checking implementation. He also wrote part of
|
||||
this documentation and proof-read and corrected other parts. And most importantly:
|
||||
the features now presented here in this library evolved from the original submission as
|
||||
a result of the useful private communications between Björn and the author.
|
||||
|
||||
[heading Post-formal review]
|
||||
|
||||
* Guillaume Melquiond spoted some documentation and code issues, particularly about
|
||||
rounding conversions.
|
||||
|
||||
* The following people contributed an important review of the design, documentation and c
|
||||
ode: Kevin Lynch, Thorsten Ottosen, Paul Bristow, Daryle Walker, Jhon Torjo, Eric Ford,
|
||||
Gennadiy Rozental.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Bibliography]
|
||||
|
||||
* Standard Documents:
|
||||
# ISO/IEC 14882:98 (C++98 Standard)
|
||||
# ISO/IEC 9899:1999 (C99 Standard)
|
||||
# ISO/IEC 10967-1 (Language Independent Arithmetic (LIA), Part I, 1994)
|
||||
# ISO/IEC 2382-1:1993 (Information Technology - Vocabulary - Part I: Fundamental Terms)
|
||||
# ANSI/IEEE 754-1985 [and IEC 60559:1989] (Binary floating-point)
|
||||
# ANSI/IEEE 854-1988 (Radix Independent floating-point)
|
||||
# ANSI X3/TR-1-82 (Dictionary for Information Processing Systems)
|
||||
# ISO/IEC JTC1/SC22/WG14/N753 C9X Revision Proposal: LIA-1 Binding: Rationale
|
||||
* Papers:
|
||||
# David Goldberg What Every Computer Scientist Should Know About Floating-Point Arithmetic
|
||||
# Prof. William Kahan papers on floating-point.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,337 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - Conversion Traits</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000ff" VLINK="#800080">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TH VALIGN="top" WIDTH="300">
|
||||
<H3><A HREF="../../../../index.htm"><IMG HEIGHT="86" WIDTH="277"
|
||||
ALT="C++ Boost" SRC="../../../../boost.png" BORDER="0"></A></H3> </TH>
|
||||
<TH VALIGN="top">
|
||||
<H1 ALIGN="center">Boost Numeric Conversion Library</H1>
|
||||
|
||||
<H1><A HREF="http://www.boost.org">Header </A><A
|
||||
HREF="../../../../boost/numeric/conversion/conversion_traits.hpp">boost/numeric/conversion/conversion_traits.hpp</A></H1>
|
||||
</TH>
|
||||
</TR>
|
||||
</TABLE> <HR>
|
||||
<H2>Contents</H2>
|
||||
<DL CLASS="page-index">
|
||||
<DT><A HREF="#types">Types</A></DT>
|
||||
</DL>
|
||||
<UL>
|
||||
|
||||
<LI><A HREF="#ncm"><CODE>enumeration boost::numeric::int_float_mixture_enum;</CODE></A></LI>
|
||||
<LI><A HREF="#ncsm"><CODE>enumeration boost::numeric::sign_mixture_enum;</CODE></A></LI>
|
||||
<LI><A HREF="#ncum"><CODE>enumeration boost::numeric::udt_builtin_mixture_enum;</CODE></A></LI>
|
||||
<LI><A HREF="#ifm"><CODE>template class boost::numeric::int_float_mixture<T,S></CODE></A></LI>
|
||||
<LI><A HREF="#sm"><CODE>template class boost::numeric::sign_mixture<T,S></CODE></A></LI>
|
||||
<LI><A HREF="#ubm"><CODE>template class boost::numeric::udt_builtin_mixture<T,S></CODE></A></LI>
|
||||
<LI><A HREF="#isr"><CODE>template class boost::numeric::is_subranged<T,S></CODE></A></LI>
|
||||
<LI><A HREF="#nct"><CODE>template class boost::numeric::conversion_traits<T,S></CODE></A></LI>
|
||||
</UL>
|
||||
<DL><DT><A HREF="#examples">Example(s)</A></DT></DL>
|
||||
<HR>
|
||||
|
||||
<H2><A NAME="types"></A>Types</H2>
|
||||
|
||||
<H2><CODE><A NAME="ncm">enumeration int_float_mixture</A>_enum</CODE></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
enum int_float_mixture_enum
|
||||
{
|
||||
integral_to_integral
|
||||
,integral_to_float
|
||||
,float_to_integral
|
||||
,float_to_float
|
||||
} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
</PRE>
|
||||
|
||||
<H2><CODE><A NAME="ncsm">enumeration sign_mixture</A>_enum</CODE></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
enum sign_mixture_enum
|
||||
{
|
||||
unsigned_to_unsigned
|
||||
,signed_to_signed
|
||||
,signed_to_unsigned
|
||||
,unsigned_to_signed
|
||||
} ;
|
||||
|
||||
} } // namespace boost::numeric</PRE>
|
||||
|
||||
<H2><CODE><A NAME="ncum">enumeration udt_builtin_mixture</A>_enum</CODE></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
enum udt_builtin_mixture_enum
|
||||
{
|
||||
builtin_to_builtin
|
||||
,builtin_to_udt
|
||||
,udt_to_builtin
|
||||
,udt_to_udt
|
||||
} ;
|
||||
|
||||
} } // namespace boost::numeric</PRE>
|
||||
|
||||
<hr>
|
||||
|
||||
<H2><A NAME="ifm"><CODE>template class int_float_mixture<></CODE></A></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct int_float_mixture : mpl::integral_c<int_float_mixture_enum, <i>impl-def-value</i>> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
</PRE>
|
||||
<p>Classifying <code>S</code> and <code>T</code> as either <code>integral</code>
|
||||
or <code>float</code>, this <a href="../../../mpl/doc/refmanual/integral-constant.html">MPL's Integral Constant</a>
|
||||
indicates the combination of these attributes. <br>
|
||||
Its <code>::value</code> is of enumeration type <A HREF="#ncm"><CODE>boost::numeric::int_float_mixture_enum</CODE></A>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<H2><A NAME="sm"><CODE>template class sign_mixture<></CODE></A></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct sign_mixture : mpl::integral_c<sign_mixture_enum, <i>impl-def-value</i>> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
</PRE>
|
||||
<p>Classifying <code>S</code> and <code>T</code> as either <code>signed</code>
|
||||
or <code>unsigned</code>, this <a href="../../../mpl/doc/refmanual/integral-constant.html">MPL's Integral Constant</a>
|
||||
indicates the combination of these attributes. <br>
|
||||
Its <code>::value</code> is of enumeration type <A HREF="#ncm"><CODE>boost::numeric::sign_mixture_enum</CODE></A>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<H2><A NAME="ubm"><CODE>template class udt_builtin_mixture<></CODE></A></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct udt_builtin_mixture : mpl::integral_c<udt_builtin__mixture_enum, <i>impl-def-value</i>> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
</PRE>
|
||||
<p>Classifying <code>S</code> and <code>T</code> as either <code>user-defined</code>
|
||||
or <code>builtin</code>, this <a href="../../../mpl/doc/refmanual/integral-constant.html">MPL's Integral Constant</a>
|
||||
indicates the combination of these attributes. <br>
|
||||
Its <code>::value</code> is of enumeration type <A HREF="#ncm"><CODE>boost::numeric::udt_builtin_mixture_enum</CODE></A>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<H2><A NAME="isr"><CODE>template class is_subranged<></CODE></A></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct is_subranged : mpl::bool_<<i>impl-def-value</i>> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
</PRE>
|
||||
<p>Indicates if the range of the target type T is a subset of the range of the source type S.
|
||||
That is: if there are some source values which fall out of the Target type's range.<br>
|
||||
It is a boolean <a href="../../../mpl/doc/refmanual/integral-constant.html">MPL's Integral Constant</a>..<br>
|
||||
It does not indicate if
|
||||
a <i>particular</i> conversion is effectively out of range; it indicates that
|
||||
some conversion <i>might be</i> out of range because not all the source values
|
||||
are representable as Target type.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<H2><A NAME="nct"><CODE>template class conversion_traits<></CODE></A></H2>
|
||||
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
|
||||
template <class T, class S>
|
||||
struct conversion_traits
|
||||
{
|
||||
mpl::integral_c<int_float_mixture_enum , ...> int_float_mixture ;
|
||||
mpl::integral_c<sign_mixture_enum , ...> sign_mixture;
|
||||
mpl::integral_c<udt_builtin_mixture_enum, ...> udt_builtin_mixture ;
|
||||
|
||||
mpl::bool_<...> subranged ;
|
||||
mpl::bool_<...> trivial ;
|
||||
|
||||
typedef T target_type ;
|
||||
typedef S source_type ;
|
||||
typedef ... argument_type ;
|
||||
typedef ... result_type ;
|
||||
typedef ... supertype ;
|
||||
typedef ... subtype ;
|
||||
} ;
|
||||
|
||||
} } // namespace numeric, namespace boost
|
||||
</PRE>
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<P>This traits class indicates some properties of a <i>numeric conversion direction</i>:
|
||||
from a source type <code>S</code> to a target type <code>T</code>. It does not indicate the properties of
|
||||
a <i>specific</i> conversion, but of the conversion <i>direction</i>. See
|
||||
<A href="definitions.html#subranged">Definitions</A> for details.<br>
|
||||
</P>
|
||||
|
||||
<P>The traits class provides the following
|
||||
<a href="../../../mpl/doc/refmanual/integral-constant.html">MPL's Integral Constants</a>
|
||||
of enumeration type. They express the <i>combination</i> of certain attributes of the Source and
|
||||
Target types (thus they are call <i>mixture</i>):</P>
|
||||
<TABLE BORDER="1">
|
||||
<TR>
|
||||
<TD> <CODE><B>int_float_mixture</B></CODE> </TD>
|
||||
|
||||
<TD>
|
||||
<P>Same as given by the traits class <A HREF="#ifm"><CODE>int_float_mixture</CODE></A></P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE><B>sign_mixture</B></CODE> </TD>
|
||||
|
||||
<TD>
|
||||
<P>Same as given by the traits class <A HREF="#sm"><CODE>sign_mixture</CODE></A></P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE><B>udt_builtin_mixture</B></CODE> </TD>
|
||||
|
||||
<TD>
|
||||
<P>Same as given by the traits class <A HREF="#ubm"><CODE>udt_builtin_mixture</CODE></A></P>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<P>The traits class provides the following
|
||||
<a href="../../../mpl/doc/refmanual/integral-constant.html">MPL's Integral Constants</a>
|
||||
of boolean type which indicates indirectly the relation between the Source and Target
|
||||
<i>ranges</i>
|
||||
(see <A href="definitions.html#range">Definitions</A> for details).</P>
|
||||
<TABLE BORDER="1">
|
||||
<TR>
|
||||
<TD> <CODE> <B>subranged</B></CODE> </TD>
|
||||
|
||||
<TD>
|
||||
<P>Same as given by <A HREF="#isr"><CODE>is_subranged</CODE></A></P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE> <B>trivial</B></CODE> </TD>
|
||||
|
||||
<TD>
|
||||
<P>Indicates if both Source and Target, <u>without cv-qualifications</u>, are
|
||||
the same type.<br>
|
||||
Its <code>::value</code> is of boolean type.</P>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<P>The traits class provides the following types. They are the Source and Target
|
||||
types classified and qualified for different purposes.</P>
|
||||
|
||||
<TABLE BORDER="1" width="720">
|
||||
<TR>
|
||||
<TD> <CODE><B>target_type</B></CODE> </TD>
|
||||
<TD>
|
||||
|
||||
<P>The template parameter <CODE>T</CODE><EM> without cv-qualifications</EM></P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE><B>source_type</B></CODE> </TD>
|
||||
<TD>
|
||||
|
||||
<P>The template parameter <CODE>S</CODE><EM> without cv-qualifications</EM></P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE><B>argument_type</B></CODE> </TD>
|
||||
<TD>
|
||||
<P>This type is either <CODE>source_type</CODE> or <CODE>source_type
|
||||
const&</CODE>. <BR> It represents the <I>optimal</I> argument type for the
|
||||
<A HREF="converter.html">converter</A> member functions.<BR>
|
||||
If <CODE>S</CODE> is a built-in type, this is <CODE>source_type</CODE>,
|
||||
otherwise, this is <CODE>source_type const&</CODE>. </P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE><B>result_type</B></CODE></TD>
|
||||
<TD>
|
||||
<P>This type is either <CODE>target_type</CODE> or <CODE>target_type
|
||||
const&</CODE> <BR> It represents the return type of the
|
||||
<A HREF="converter.html">converter</A> member functions.<BR>
|
||||
If <CODE>T==S</CODE>, it is <CODE>target_type const&</CODE>, otherwise,
|
||||
it is <CODE>target_type</CODE>.</P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
|
||||
<TD height="37"> <CODE><B>supertype</B></CODE></TD>
|
||||
|
||||
<TD height="37">
|
||||
<P>If the conversion is <CODE>subranged</CODE>, it is <CODE>source_type</CODE>,
|
||||
otherwise, it is <CODE>target_type</CODE></P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE><B>subtype</B></CODE></TD>
|
||||
<TD height="37">
|
||||
<P>If the conversion is <CODE>subranged</CODE>, it is <CODE>target_type</CODE>,
|
||||
otherwise, it is <CODE>source_type</CODE></P>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE> </BLOCKQUOTE> <HR>
|
||||
|
||||
<H2><A NAME="examples">Examples</A></H2>
|
||||
<BLOCKQUOTE>
|
||||
<PRE>#include <cassert>
|
||||
#include <typeinfo>
|
||||
#include <boost/numeric/conversion/conversion_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// A trivial conversion.
|
||||
typedef boost::numeric::conversion_traits<short,short> Short2Short_Traits ;
|
||||
assert ( Short2Short_Traits::trivial::value ) ;
|
||||
|
||||
// A subranged conversion.
|
||||
typedef boost::numeric::conversion_traits<double,unsigned int> UInt2Double_Traits ;
|
||||
assert ( UInt2Double_Traits::int_float_mixture::value == boost::numeric::integral_to_float ) ;
|
||||
assert ( UInt2Double_Traits::sign_mixture::value == boost::numeric::unsigned_to_signed ) ;
|
||||
assert ( !UInt2Double_Traits::subranged::value ) ;
|
||||
assert ( typeid(UInt2Double_Traits::supertype) == typeid(double) ) ;
|
||||
assert ( typeid(UInt2Double_Traits::subtype) == typeid(unsigned int) ) ;
|
||||
|
||||
// A doubly subranged conversion.
|
||||
assert ( (boost::numeric::conversion_traits<short, unsigned short>::subranged::value) );
|
||||
assert ( (boost::numeric::conversion_traits<unsigned short, short>::subranged::value) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
</PRE>
|
||||
</BLOCKQUOTE>
|
||||
<HR>
|
||||
<P>Back to <A HREF="index.html">Numeric Conversion library index</A></P>
|
||||
<HR>
|
||||
<P>Revised 23 November 2006</P>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,272 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 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)
|
||||
]
|
||||
|
||||
[section conversion_traits<> traits class]
|
||||
|
||||
[section Types]
|
||||
|
||||
[section enumeration int_float_mixture_enum]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
enum int_float_mixture_enum
|
||||
{
|
||||
integral_to_integral
|
||||
,integral_to_float
|
||||
,float_to_integral
|
||||
,float_to_float
|
||||
} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
[endsect]
|
||||
|
||||
[section enumeration sign_mixture_enum]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
enum sign_mixture_enum
|
||||
{
|
||||
unsigned_to_unsigned
|
||||
,signed_to_signed
|
||||
,signed_to_unsigned
|
||||
,unsigned_to_signed
|
||||
} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
[endsect]
|
||||
|
||||
[section enumeration udt_builtin_mixture_enum]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
enum udt_builtin_mixture_enum
|
||||
{
|
||||
builtin_to_builtin
|
||||
,builtin_to_udt
|
||||
,udt_to_builtin
|
||||
,udt_to_udt
|
||||
} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template class int_float_mixture<>]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct int_float_mixture : mpl::integral_c<int_float_mixture_enum, impl-def-value> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
Classifying `S` and `T` as either integral or float, this __MPL_INTEGRAL_CONSTANT__
|
||||
indicates the combination of these attributes.
|
||||
|
||||
Its `::value` is of enumeration type
|
||||
[link boost_numericconversion.conversion_traits___traits_class.types.enumeration_int_float_mixture_enum `boost::numeric::int_float_mixture_enum`]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template class sign_mixture<>]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct sign_mixture : mpl::integral_c<sign_mixture_enum, impl-def-value> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
Classifying `S` and `T` as either signed or unsigned, this __MPL_INTEGRAL_CONSTANT__
|
||||
indicates the combination of these attributes.
|
||||
|
||||
Its `::value` is of enumeration type
|
||||
[link boost_numericconversion.conversion_traits___traits_class.types.enumeration_sign_mixture_enum `boost::numeric::sign_mixture_enum`]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template class udt_builtin_mixture<>]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct udt_builtin_mixture : mpl::integral_c<udt_builtin__mixture_enum, impl-def-value> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
Classifying `S` and `T` as either user-defined or builtin, this __MPL_INTEGRAL_CONSTANT__
|
||||
indicates the combination of these attributes.
|
||||
|
||||
Its `::value` is of enumeration type
|
||||
[link boost_numericconversion.conversion_traits___traits_class.types.enumeration_udt_builtin_mixture_enum `boost::numeric::udt_builtin_mixture_enum`]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template class is_subranged<>]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct is_subranged : mpl::bool_<impl-def-value> {} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
Indicates if the range of the target type `T` is a subset of the range of the source
|
||||
type `S`. That is: if there are some source values which fall out of the
|
||||
Target type's range.
|
||||
|
||||
It is a boolean __MPL_INTEGRAL_CONSTANT__.
|
||||
|
||||
It does not indicate if a particular conversion is effectively out of range;
|
||||
it indicates that some conversion might be out of range because not all the
|
||||
source values are representable as Target type.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template class conversion_traits<>]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
template <class T, class S>
|
||||
struct conversion_traits
|
||||
{
|
||||
mpl::integral_c<int_float_mixture_enum , ...> int_float_mixture ;
|
||||
mpl::integral_c<sign_mixture_enum , ...> sign_mixture;
|
||||
mpl::integral_c<udt_builtin_mixture_enum, ...> udt_builtin_mixture ;
|
||||
|
||||
mpl::bool_<...> subranged ;
|
||||
mpl::bool_<...> trivial ;
|
||||
|
||||
typedef T target_type ;
|
||||
typedef S source_type ;
|
||||
typedef ... argument_type ;
|
||||
typedef ... result_type ;
|
||||
typedef ... supertype ;
|
||||
typedef ... subtype ;
|
||||
} ;
|
||||
|
||||
} } // namespace numeric, namespace boost
|
||||
|
||||
|
||||
This traits class indicates some properties of a ['numeric conversion] direction:
|
||||
from a source type `S` to a target type `T`. It does not indicate the properties
|
||||
of a ['specific] conversion, but of the conversion direction. See
|
||||
[link boost_numericconversion.definitions.subranged_conversion_direction__subtype_and_supertype Definitions] for details.
|
||||
|
||||
The traits class provides the following __MPL_INTEGRAL_CONSTANT__\s of enumeration
|
||||
type. They express the combination of certain attributes of the Source and
|
||||
Target types (thus they are call mixture):
|
||||
|
||||
[table
|
||||
[[ ][ ]]
|
||||
[[[*int_float_mixture ]][
|
||||
Same as given by the traits class
|
||||
[link boost_numericconversion.conversion_traits___traits_class.types.template_class_int_float_mixture__ int_float_mixture]
|
||||
]]
|
||||
[[[*sign_mixture ]][
|
||||
Same as given by the traits class
|
||||
[link boost_numericconversion.conversion_traits___traits_class.types.template_class_sign_mixture__ sign_mixture]
|
||||
]]
|
||||
[[[*udt_builtin_mixture ]]
|
||||
[Same as given by the traits class
|
||||
[link boost_numericconversion.conversion_traits___traits_class.types.template_class_udt_builtin_mixture__ udt_builtin_mixture]
|
||||
]]
|
||||
]
|
||||
|
||||
The traits class provides the following __MPL_INTEGRAL_CONSTANT__\s of boolean type
|
||||
which indicates indirectly the relation between the Source and Target ranges
|
||||
(see [link boost_numericconversion.definitions.range_and_precision Definitions] for details).
|
||||
|
||||
[table
|
||||
[[ ][ ]]
|
||||
[[subranged ][
|
||||
Same as given by [link boost_numericconversion.conversion_traits___traits_class.types.template_class_is_subranged__ is_subranged]
|
||||
]]
|
||||
[[trivial][
|
||||
Indicates if both Source and Target, [_without cv-qualifications], are the same type.
|
||||
|
||||
Its `::value` is of boolean type.
|
||||
]]
|
||||
]
|
||||
|
||||
The traits class provides the following types. They are the Source and Target types classified
|
||||
and qualified for different purposes.
|
||||
|
||||
|
||||
[table
|
||||
[[ ][ ]]
|
||||
[[[*target_type]][
|
||||
The template parameter `T` without cv-qualifications
|
||||
]]
|
||||
[[[*source_type]][
|
||||
The template parameter `S` without cv-qualifications
|
||||
]]
|
||||
[[[*argument_type]][
|
||||
This type is either source_type or `source_type const&`.
|
||||
|
||||
It represents the optimal argument type for the
|
||||
[link boost_numericconversion.converter___function_object converter] member functions.
|
||||
|
||||
If S is a built-in type, this is `source_type`, otherwise, this is `source_type const&`.
|
||||
]]
|
||||
[[[*result_type]][
|
||||
This type is either target_type or target_type const&
|
||||
|
||||
It represents the return type of the
|
||||
[link boost_numericconversion.converter___function_object converter] member functions.
|
||||
|
||||
If `T==S`, it is `target_type const&`, otherwise, it is `target_type`.
|
||||
]]
|
||||
[[[*supertype]][
|
||||
If the conversion is subranged, it is `source_type`, otherwise, it is `target_type`
|
||||
]]
|
||||
[[[*subtype]][
|
||||
If the conversion is subranged, it is `target_type`, otherwise, it is `source_type`
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
|
||||
#include <cassert>
|
||||
#include <typeinfo>
|
||||
#include <boost/numeric/conversion/conversion_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// A trivial conversion.
|
||||
typedef boost::numeric::conversion_traits<short,short> Short2Short_Traits ;
|
||||
assert ( Short2Short_Traits::trivial::value ) ;
|
||||
|
||||
// A subranged conversion.
|
||||
typedef boost::numeric::conversion_traits<double,unsigned int> UInt2Double_Traits ;
|
||||
assert ( UInt2Double_Traits::int_float_mixture::value == boost::numeric::integral_to_float ) ;
|
||||
assert ( UInt2Double_Traits::sign_mixture::value == boost::numeric::unsigned_to_signed ) ;
|
||||
assert ( !UInt2Double_Traits::subranged::value ) ;
|
||||
assert ( typeid(UInt2Double_Traits::supertype) == typeid(double) ) ;
|
||||
assert ( typeid(UInt2Double_Traits::subtype) == typeid(unsigned int) ) ;
|
||||
|
||||
// A doubly subranged conversion.
|
||||
assert ( (boost::numeric::conversion_traits<short, unsigned short>::subranged::value) );
|
||||
assert ( (boost::numeric::conversion_traits<unsigned short, short>::subranged::value) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -1,279 +0,0 @@
|
||||
<HTML>
|
||||
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - Policy-based Converter</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000ff" VLINK="#800080">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TD VALIGN="top" WIDTH="300"> <H3><A HREF="http://www.boost.org"><IMG
|
||||
HEIGHT="86" WIDTH="277" ALT="C++ Boost" SRC="../../../../boost.png"
|
||||
BORDER="0"></A> </H3>
|
||||
</TD>
|
||||
<TD VALIGN="top"> <H1 ALIGN="center">Boost Numeric Conversion Library</H1>
|
||||
<H1><A HREF="http://www.boost.org">Header </A><A
|
||||
HREF="../../../../boost/numeric/conversion/converter.hpp">boost/numeric/conversion/converter.hpp</A></H1>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<HR>
|
||||
<H2>Contents</H2>
|
||||
<DT><A HREF="#synopsis">Synopsis</A></DT>
|
||||
<DT><A HREF="requirements.html">User Defined Types support</A></DT>
|
||||
<DT><A HREF="#rchklogic">Range Checking Logic</A></DT>
|
||||
<DT><A HREF="#examples">Examples</A></DT>
|
||||
|
||||
<HR>
|
||||
<H2><A NAME="synopsis">Synopsis</A></H2>
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
|
||||
template<class T,
|
||||
class S,
|
||||
class Traits, = conversion_traits<T,S>
|
||||
class OverflowHandler = def_overflow_handler,
|
||||
class Float2IntRounder = Trunc< typename Traits::source_type >,
|
||||
class RawConverter = raw_converter<Traits>,
|
||||
class UserRangeChecker = UseInternalRangeChecker
|
||||
>
|
||||
struct converter
|
||||
{
|
||||
typedef Traits traits ;
|
||||
|
||||
typedef typename Traits::source_type source_type ;
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
typedef typename Traits::result_type result_type ;
|
||||
|
||||
static result_type convert ( argument_type s ) ;
|
||||
|
||||
result_type operator() ( argument_type s ) const ;
|
||||
|
||||
// Internal member functions:
|
||||
|
||||
static range_check_result out_of_range ( argument_type s ) ;
|
||||
static void validate_range ( argument_type s ) ;
|
||||
static result_type low_level_convert ( argument_type s ) ;
|
||||
static source_type nearbyint ( argument_type s ) ;
|
||||
|
||||
} ;
|
||||
|
||||
} } // namespace numeric, boost
|
||||
</PRE>
|
||||
|
||||
<P><code>boost::numeric::converter<></code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary Function Object</a>
|
||||
encapsulating the code to perform a numeric conversion with the direction and properties specified
|
||||
by the <CODE>Traits</CODE> template parameter. It can optionally take some
|
||||
<A HREF="converter_policies.html">policies</a>
|
||||
which can be used to customize its behavior. The Traits parameter is not a policy but
|
||||
the parameter that defines the conversion.
|
||||
</P>
|
||||
<hr>
|
||||
<h2>Template parameters:</h2>
|
||||
<TABLE BORDER="1">
|
||||
<TR>
|
||||
<TD> T</TD>
|
||||
<TD> The <A HREF="definitions.html#numtypes">Numeric Type</A> which is
|
||||
the <i>Target</i> of the conversion.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> S</TD>
|
||||
<TD> The <A HREF="definitions.html#numtypes">Numeric Type</A> which is
|
||||
the <i>Source</i> of the conversion.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <CODE>Traits</CODE> </TD>
|
||||
<TD> This must be a conversion traits class with the interface of
|
||||
<A HREF="conversion_traits.html">boost::numeric::conversion_traits</A>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF="converter_policies.html#oh"><CODE>OverflowHandler</CODE></A> </TD>
|
||||
<TD> <B>Stateless Policy</B> called to administrate the result of the
|
||||
range checking.<br>
|
||||
It is a <b>Function Object</b> which receives the result of <CODE>out_of_range()</CODE>
|
||||
and is called inside the <CODE>validate_range()</CODE> static member function
|
||||
exposed by the converter.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF="converter_policies.html#f2i"><CODE>Float2IntRounder</CODE></A> </TD>
|
||||
<TD> <B>Stateless Policy</B> which specifies the rounding mode used for
|
||||
float to integral conversions.<br>
|
||||
It supplies the <CODE>nearbyint()</CODE> static member function exposed
|
||||
by the converter.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF="converter_policies.html#rawc"><CODE>RawConverter</CODE></A> </TD>
|
||||
<TD> <B>Stateless Policy</B> which is used to perform the actual conversion.
|
||||
<br>
|
||||
It supplies the<CODE> low_level_convert()</CODE> static member function
|
||||
exposed by the converter.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF="converter_policies.html#rc"><CODE>UserRangeChecker</CODE></A> </TD>
|
||||
<TD><i>Special and Optional</i> <b>Stateless Policy</b> which can be used to override
|
||||
the internal range checking logic.<br>
|
||||
If given, supplies alternative code for the out_of_range() and validate_range()
|
||||
static member functions exposed by the converter.</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<br>
|
||||
<hr>
|
||||
<h2>Member functions:</h2>
|
||||
<P><CODE>static result_type converter<>::convert ( argument_type s ) ; //
|
||||
throw</CODE></P>
|
||||
<BLOCKQUOTE>
|
||||
<P>This static member function converts an rvalue of type source_type to an rvalue
|
||||
of type target_type.<BR>
|
||||
If the conversion requires it, it performs a range checking before the conversion
|
||||
and passes the result of the check to the overflow handler policy (the default
|
||||
policy throws an exception if out-of-range is detected)<BR>
|
||||
The implementation of this function is actually built from the policies and
|
||||
is basically as follows:</P>
|
||||
<PRE> result_type converter<>::convert ( argument_type s )
|
||||
{
|
||||
validate_range(s); // Implemented by the internal range checking logic
|
||||
// (which also calls the OverflowHandler policy)
|
||||
// or externally supplied by the UserRangeChecker policy.
|
||||
|
||||
s = nearbyint(s); // Externally supplied by the Float2IntRounder policy.
|
||||
// NOTE: This is actually called only for float to int conversions.
|
||||
|
||||
return low_level_convert(s); // Externally supplied by the RawConverter policy.
|
||||
}
|
||||
</PRE>
|
||||
|
||||
<P>"converter<>::operator() const" just calls <CODE>convert()</CODE></P>
|
||||
</BLOCKQUOTE>
|
||||
<P><CODE>static range_check_result numeric_converter<>::out_of_range (
|
||||
argument_type s ) ;</CODE></P>
|
||||
<BLOCKQUOTE>
|
||||
<P>This <A HREF="#int">internal</A> static member function determines if the
|
||||
value 's' can be represented by the target type without overflow. <BR>
|
||||
It does not determine if the conversion is <EM>exact</EM>; that is, it does
|
||||
not detect <i>inexact</i> conversions, only <i>out-of-range</i> conversions
|
||||
(see the <a href="definitions.html#roundoff">Definitions</a> for further details).<BR>
|
||||
The return value is of enum type
|
||||
<A HREF="converter_policies.html#rcr"><CODE>boost::numeric::range_check_result</CODE></A><BR>
|
||||
The actual code for the range checking logic is optimized for the combined
|
||||
properties of the source and target types. For example, a non-subranged conversion
|
||||
(i.e: int->float), requires no range checking, so out_of_range() returns
|
||||
cInRange directly. See the following <A HREF="#rchklogic">table</A> for more
|
||||
details.<br>
|
||||
If the user supplied a <a href="converter_policies.html#rc">UserRangeChecker</a>
|
||||
policy, is this policy which implements this function, so the implementation
|
||||
is user defined, although it is expected to perform the same conceptual check
|
||||
and return the appropriate result.</P>
|
||||
</BLOCKQUOTE>
|
||||
<P><CODE>static void numeric_converter<>::validate_range ( argument_type
|
||||
s ) ; // no throw</CODE></P>
|
||||
<BLOCKQUOTE>
|
||||
<P>This <A HREF="#int">internal</A> static member function calls <CODE>out_of_range(s)</CODE>,
|
||||
and passes the result to the <A
|
||||
HREF="converter_policies.html#oh"><CODE>OverflowHandler</CODE></A> policy class
|
||||
<BR>
|
||||
For those Target/Source combinations which don't require range checking, this
|
||||
is an <U>empty inline function</U>.<br>
|
||||
If the user supplied a <a href="converter_policies.html#rc">UserRangeChecker</a>
|
||||
policy, is this policy which implements this function, so the implementation
|
||||
is user defined, although it is expected to perform the same action as the
|
||||
default. In particular, it is expected to pass the result of the check to
|
||||
the overflow handler.</P>
|
||||
</BLOCKQUOTE>
|
||||
<P><CODE>static result_type numeric_converter<>::low_level_convert (
|
||||
argument_type s ) ;</CODE></P>
|
||||
<BLOCKQUOTE>
|
||||
<P>This <A HREF="#int">internal</A> static member function performs the actual
|
||||
conversion.<BR>
|
||||
This function is externally supplied by the <A
|
||||
HREF="converter_policies.html#rawc"><CODE>RawConverter</CODE></A> policy class.</P>
|
||||
</BLOCKQUOTE>
|
||||
<P><CODE>static source_type converter<>::nearbyint (
|
||||
argument_type s ) ;</CODE></P>
|
||||
<BLOCKQUOTE>
|
||||
<P>This <A HREF="#int">internal</A> static member function, which is <U>only
|
||||
used</U> for float to int conversions, returns an <I>integer value of <U>floating-point
|
||||
type</U></I> according to some rounding direction. <BR>
|
||||
This function is externally supplied by the <A
|
||||
HREF="converter_policies.html#f2i"><CODE>Float2IntRounder</CODE></A> policy class
|
||||
which encapsulates the specific rounding mode.</P>
|
||||
</BLOCKQUOTE>
|
||||
<hr>
|
||||
<P><A NAME="int"><B>Internal Member Functions</B>:</A> These static member functions
|
||||
build the actual conversion code used by <CODE>convert()</CODE>. The user does
|
||||
not have to call these if calling convert(), since convert() calls them infernally,
|
||||
but they can be called separately for specific needs.</P>
|
||||
<hr>
|
||||
<H2><A NAME="rchklogic">Range Checking Logic</A></H2>
|
||||
<P>The Following table summarizes the internal range checking logic performed
|
||||
for each combination of the properties of Source and Target.<br>
|
||||
LowestT/HighestT denotes the highest and lowest values of the Target type, respectively.<br>
|
||||
S(n) is short for "static_cast<S>(n)" (S denotes the Source
|
||||
type).<br>
|
||||
"NONE" indicates that for this case there is no range checking.</P>
|
||||
<Pre> int_to_int |--> sig_to_sig |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
|
|
||||
|--> unsig_to_unsig |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
|
|
||||
|--> sig_to_unsig |--> pos subranged |--> ( s >= S(0) ) && ( s <= S(HighestT) )
|
||||
| |--> not pos subranged |--> ( s >= S(0) )
|
||||
|
|
||||
|--> unsig_to_sig |--> subranged |--> ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
|
||||
int_to_float |--> NONE
|
||||
|
||||
float_to_int |--> round_to_zero |--> ( s > S(LowestT)-S(1) ) && ( s < S(HighestT)+S(1) )
|
||||
|--> round_to_even_nearest |--> ( s >= S(LowestT)-S(0.5) ) && ( s < S(HighestT)+S(0.5) )
|
||||
|--> round_to_infinity |--> ( s > S(LowestT)-S(1) ) && ( s <= S(HighestT) )
|
||||
|--> round_to_neg_infinity |--> ( s >= S(LowestT) ) && ( s < S(HighestT)+S(1) )
|
||||
|
||||
float_to_float |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
|--> not subranged |--> NONE
|
||||
|
||||
</Pre>
|
||||
<HR>
|
||||
<H2><A NAME="examples">Examples</A></H2>
|
||||
<BLOCKQUOTE>
|
||||
<PRE> #include <cassert>
|
||||
#include <boost/numeric/conversion/converter.hpp>
|
||||
|
||||
int main() {
|
||||
|
||||
typedef boost::numeric::converter<int,double> Double2Int ;
|
||||
|
||||
int x = Double2Int::convert(2.0);
|
||||
assert ( x == 2 );
|
||||
|
||||
int y = Double2Int()(3.14); // As a function object.
|
||||
assert ( y == 3 ) ; // The default rounding is trunc.
|
||||
|
||||
try
|
||||
{
|
||||
double m = boost::numeric::bounds<double>::highest();
|
||||
int z = Double2Int::convert(m); // By default throws positive_overflow()
|
||||
}
|
||||
catch ( boost::numeric::positive_overflow const& )
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}</PRE>
|
||||
</BLOCKQUOTE>
|
||||
<HR>
|
||||
<P>Back to <A HREF="index.html">Numeric Conversion library index</A></P>
|
||||
<HR>
|
||||
<P>Revised 16 May 2005</P>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,293 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 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)
|
||||
]
|
||||
|
||||
[section converter<> function object]
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
|
||||
template<class T,
|
||||
class S,
|
||||
class Traits, = conversion_traits<T,S>
|
||||
class OverflowHandler = def_overflow_handler,
|
||||
class Float2IntRounder = Trunc< typename Traits::source_type >,
|
||||
class RawConverter = raw_converter<Traits>,
|
||||
class UserRangeChecker = UseInternalRangeChecker
|
||||
>
|
||||
struct converter
|
||||
{
|
||||
typedef Traits traits ;
|
||||
|
||||
typedef typename Traits::source_type source_type ;
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
typedef typename Traits::result_type result_type ;
|
||||
|
||||
static result_type convert ( argument_type s ) ;
|
||||
|
||||
result_type operator() ( argument_type s ) const ;
|
||||
|
||||
// Internal member functions:
|
||||
|
||||
static range_check_result out_of_range ( argument_type s ) ;
|
||||
static void validate_range ( argument_type s ) ;
|
||||
static result_type low_level_convert ( argument_type s ) ;
|
||||
static source_type nearbyint ( argument_type s ) ;
|
||||
|
||||
} ;
|
||||
|
||||
} } // namespace numeric, boost
|
||||
|
||||
|
||||
`boost::numeric::converter<>` is a __SGI_UNARY_FUNCTION__ encapsulating
|
||||
the code to perform a numeric conversion with the direction and
|
||||
properties specified by the Traits template parameter. It can optionally
|
||||
take some [link boost_numericconversion.numeric_converter_policy_classes policies] which can be used to customize its behavior. The
|
||||
`Traits` parameter is not a policy but the parameter that defines
|
||||
the conversion.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Template parameters]
|
||||
|
||||
[table
|
||||
[[ ][ ]]
|
||||
[[`T`][
|
||||
The [link boost_numericconversion.definitions.numeric_types Numeric Type]
|
||||
which is the ['Target] of the conversion.
|
||||
]]
|
||||
[[`S`][
|
||||
The [link boost_numericconversion.definitions.numeric_types Numeric Type]
|
||||
which is the ['Source] of the conversion.
|
||||
]]
|
||||
[[`Traits`][
|
||||
This must be a conversion traits class with the interface of
|
||||
[link boost_numericconversion.conversion_traits___traits_class `boost::numeric::conversion_traits`]
|
||||
]]
|
||||
[[`OverflowHandler`][
|
||||
[*Stateless Policy] called to administrate the result of the range checking.
|
||||
|
||||
It is a [*Function Object] which receives the result of `out_of_range()`
|
||||
and is called inside the `validate_range()` static member function exposed
|
||||
by the converter.
|
||||
]]
|
||||
[[`Float2IntRounder`][
|
||||
[*Stateless Policy] which specifies the rounding mode used for float to
|
||||
integral conversions.
|
||||
|
||||
It supplies the `nearbyint()` static member function exposed by the converter.
|
||||
]]
|
||||
[[`RawConverter`][
|
||||
[*Stateless Policy] which is used to perform the actual conversion.
|
||||
|
||||
It supplies the `low_level_convert()` static member function exposed
|
||||
by the converter.
|
||||
]]
|
||||
[[`UserRangeChecker`][
|
||||
['Special and Optional] [*Stateless Policy] which can be used to override
|
||||
the internal range checking logic.
|
||||
|
||||
If given, supplies alternative code for the `out_of_range()` and
|
||||
`validate_range()` static member functions exposed by the converter.
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Member functions]
|
||||
|
||||
[: `static result_type converter<>::convert ( argument_type s ) ; // throw
|
||||
`]
|
||||
|
||||
This static member function converts an rvalue of type `source_type` to
|
||||
an rvalue of type `target_type`.
|
||||
|
||||
If the conversion requires it, it performs a range checking before the conversion
|
||||
and passes the result of the check to the overflow handler policy (the default
|
||||
policy throws an exception if out-of-range is detected)
|
||||
|
||||
The implementation of this function is actually built from the policies and is
|
||||
basically as follows:
|
||||
|
||||
result_type converter<>::convert ( argument_type s )
|
||||
{
|
||||
validate_range(s); // Implemented by the internal range checking logic
|
||||
// (which also calls the OverflowHandler policy)
|
||||
// or externally supplied by the UserRangeChecker policy.
|
||||
|
||||
s = nearbyint(s); // Externally supplied by the Float2IntRounder policy.
|
||||
// NOTE: This is actually called only for float to int conversions.
|
||||
|
||||
return low_level_convert(s); // Externally supplied by the RawConverter policy.
|
||||
}
|
||||
|
||||
`converter<>::operator() const` just calls `convert()`
|
||||
|
||||
__SPACE__
|
||||
|
||||
[: `static range_check_result numeric_converter<>::out_of_range ( argument_type s ) ;`]
|
||||
|
||||
This [link numeric_conversion_converter_internal internal] static member function
|
||||
determines if the value `s` can be
|
||||
represented by the target type without overflow.
|
||||
|
||||
It does not determine if the conversion is ['exact]; that is, it does not detect
|
||||
['inexact] conversions, only ['out-of-range] conversions (see the
|
||||
[link boost_numericconversion.definitions.exact__correctly_rounded_and_out_of_range_representations Definitions] for further details).
|
||||
|
||||
The return value is of enum type
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.enum_range_check_result `boost::numeric::range_check_result`]
|
||||
|
||||
The actual code for the range checking logic is optimized for the combined
|
||||
properties of the source and target types. For example, a non-subranged
|
||||
conversion (i.e: `int`->`float`), requires no range checking, so `out_of_range()`
|
||||
returns `cInRange` directly. See the following
|
||||
[link boost_numericconversion.converter___function_object.range_checking_logic table] for more details.
|
||||
|
||||
If the user supplied a
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker UserRangeChecker] policy,
|
||||
is this policy which implements this function, so the implementation is user
|
||||
defined, although it is expected to perform the same conceptual check and
|
||||
return the appropriate result.
|
||||
|
||||
__SPACE__
|
||||
|
||||
[: `static void numeric_converter<>::validate_range ( argument_type s ) ; // no throw
|
||||
`]
|
||||
|
||||
This [link numeric_conversion_converter_internal internal] static member function
|
||||
calls out_of_range(s), and passes the
|
||||
result to the [link boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler OverflowHandler]
|
||||
policy class.
|
||||
|
||||
For those Target/Source combinations which don't require range checking, this
|
||||
is an empty inline function.
|
||||
|
||||
If the user supplied a
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker UserRangeChecker] policy,
|
||||
is this policy which implements this function, so the implementation is user
|
||||
defined, although it is expected to perform the same action as the default.
|
||||
In particular, it is expected to pass the result of the check to the overflow handler.
|
||||
|
||||
__SPACE__
|
||||
|
||||
[: `static result_type numeric_converter<>::low_level_convert ( argument_type s ) ;` ]
|
||||
|
||||
This [link numeric_conversion_converter_internal internal] static member function
|
||||
performs the actual conversion.
|
||||
|
||||
This function is externally supplied by the
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter RawConverter] policy class.
|
||||
|
||||
__SPACE__
|
||||
|
||||
[: `static source_type converter<>::nearbyint ( argument_type s ) ;`]
|
||||
|
||||
This [link numeric_conversion_converter_internal internal] static member function,
|
||||
which is [_only used] for
|
||||
`float` to `int` conversions, returns an ['integer] value of ['[_floating-point
|
||||
type]] according to some rounding direction.
|
||||
|
||||
This function is externally supplied by the
|
||||
[link boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder Float2IntRounder] policy class
|
||||
which encapsulates the specific rounding mode.
|
||||
|
||||
__SPACE__
|
||||
|
||||
[#numeric_conversion_converter_internal]
|
||||
|
||||
[heading Internal Member Functions]
|
||||
|
||||
These static member functions build the actual conversion code used by `convert()`.
|
||||
The user does not have to call these if calling `convert()`, since `convert()` calls
|
||||
them infernally, but they can be called separately for specific needs.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Range Checking Logic]
|
||||
|
||||
The following table summarizes the internal range checking logic performed for
|
||||
each combination of the properties of Source and Target.
|
||||
|
||||
LowestT/HighestT denotes the highest and lowest values of the Target type, respectively.
|
||||
|
||||
`S(n)` is short for `static_cast<S>(n)` (`S` denotes the Source type).
|
||||
|
||||
`NONE` indicates that for this case there is no range checking.
|
||||
|
||||
[pre
|
||||
[^
|
||||
int_to_int |--> sig_to_sig |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
|
|
||||
|--> unsig_to_unsig |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
|
|
||||
|--> sig_to_unsig |--> pos subranged |--> ( s >= S(0) ) && ( s <= S(HighestT) )
|
||||
| |--> not pos subranged |--> ( s >= S(0) )
|
||||
|
|
||||
|--> unsig_to_sig |--> subranged |--> ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
]
|
||||
[^
|
||||
int_to_float |--> NONE
|
||||
]
|
||||
[^
|
||||
float_to_int |--> round_to_zero |--> ( s > S(LowestT)-S(1) ) && ( s < S(HighestT)+S(1) )
|
||||
|--> round_to_even_nearest |--> ( s >= S(LowestT)-S(0.5) ) && ( s < S(HighestT)+S(0.5) )
|
||||
|--> round_to_infinity |--> ( s > S(LowestT)-S(1) ) && ( s <= S(HighestT) )
|
||||
|--> round_to_neg_infinity |--> ( s >= S(LowestT) ) && ( s < S(HighestT)+S(1) )
|
||||
]
|
||||
[^
|
||||
float_to_float |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
|--> not subranged |--> NONE
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
|
||||
#include <cassert>
|
||||
#include <boost/numeric/conversion/converter.hpp>
|
||||
|
||||
int main() {
|
||||
|
||||
typedef boost::numeric::converter<int,double> Double2Int ;
|
||||
|
||||
int x = Double2Int::convert(2.0);
|
||||
assert ( x == 2 );
|
||||
|
||||
int y = Double2Int()(3.14); // As a function object.
|
||||
assert ( y == 3 ) ; // The default rounding is trunc.
|
||||
|
||||
try
|
||||
{
|
||||
double m = boost::numeric::bounds<double>::highest();
|
||||
int z = Double2Int::convert(m); // By default throws positive_overflow()
|
||||
}
|
||||
catch ( boost::numeric::positive_overflow const& )
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
<HTML>
|
||||
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - Converter Policies</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000ff" VLINK="#800080">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TD VALIGN="top" WIDTH="300"> <H3><A HREF="http://www.boost.org"><IMG
|
||||
HEIGHT="86" WIDTH="277" ALT="C++ Boost" SRC="../../../../boost.png"
|
||||
BORDER="0"></A> </H3>
|
||||
</TD>
|
||||
<TD VALIGN="top"> <H1 ALIGN="center">Boost Numeric Conversion Library</H1>
|
||||
<H1><A HREF="http://www.boost.org">Header </A><A
|
||||
HREF="../../../../boost/numeric/conversion/converter_policies.hpp">boost/numeric/conversion/converter_policies.hpp</A></H1>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<HR>
|
||||
<H2>Contents</H2>
|
||||
<ol>
|
||||
<LI><A HREF="#rcr"><CODE>enumeration range_check_result</CODE></A> </LI>
|
||||
<LI><A HREF="#oh"><CODE>Policy OverflowHandler</CODE></A>
|
||||
<UL>
|
||||
<LI>class <A HREF="#oh_silent"><CODE>silent_overflow_handler</CODE></A></LI>
|
||||
<LI>class <A HREF="#oh_def"><CODE>def_overflow_handler</CODE></A> (Default Policy)</LI>
|
||||
<ul>
|
||||
<LI>class <CODE> <A HREF="#bad_numc">bad_numeric_cast</A></CODE> <a href="#x-note">(see IMPORTANT note)</a></LI>
|
||||
<LI>class <A HREF="#negovr"><CODE>negative_overflow</CODE></A></LI>
|
||||
<LI>class <A HREF="#posovr"><CODE>positive_overflow</CODE></A></LI>
|
||||
</ul>
|
||||
</UL>
|
||||
</LI>
|
||||
<LI><A HREF="#f2i"><CODE>Policy FloatToIntRounder</CODE></A> <UL>
|
||||
<LI>class <A HREF="#trunc"><CODE>Trunc<T></CODE></A> (Default Policy)</LI>
|
||||
<LI>class <A HREF="#round"><CODE>RoundEven<T></CODE></A></LI>
|
||||
<LI>class <A HREF="#ceil"><CODE>Ceil<T></CODE></A></LI>
|
||||
<LI>class <A HREF="#floor"><CODE>Floor<T></CODE></A></LI>
|
||||
</UL>
|
||||
</LI>
|
||||
<LI><A HREF="#rawc"><CODE>Policy RawConverter</CODE></A><UL>
|
||||
<LI>class <A HREF="#rawnumc"><CODE>raw_converter class</CODE></A> (Default)</LI>
|
||||
</UL>
|
||||
</LI>
|
||||
<LI><A HREF="#rc"><CODE>Policy UserRangeChecker</CODE></A><UL>
|
||||
<LI>class <A HREF="#int_rc"><CODE>UseInternalRangeChecker class</CODE></A> (Default)</LI>
|
||||
</UL>
|
||||
</LI>
|
||||
</ol>
|
||||
|
||||
<HR>
|
||||
<H2><A NAME="types">Types</A></H2>
|
||||
<H2><A NAME="rcr"><CODE>enum range_check_result</CODE></A></H2>
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
|
||||
enum range_check_result
|
||||
{
|
||||
cInRange ,
|
||||
cNegOverflow ,
|
||||
cPosOverflow
|
||||
} ;
|
||||
|
||||
|
||||
} }</PRE>
|
||||
|
||||
<P>Defines the values returned by <CODE>boost::numeric::converter<>::out_of_range()</CODE>
|
||||
</P>
|
||||
<HR>
|
||||
<H2><A NAME="oh">Policy <CODE>OverflowHandler</CODE></A></H2>
|
||||
<P>This <EM>stateless</EM> non-template policy class must be a <I>function object</I>
|
||||
and is called to administrate the result of the range checking. It can throw
|
||||
an exception if overflow has been detected by the range checking as indicated
|
||||
by its argument. If it throws, is is recommended that it be <CODE>std::bad_cast</CODE>
|
||||
or derived.</P>
|
||||
<P>It must have the following interface (it does not has to be a template class):</P>
|
||||
<PRE> struct YourOverflowHandlerPolicy
|
||||
{
|
||||
void operator() ( boost::range_check_result ) ; // throw bad_cast or derived
|
||||
} ;
|
||||
</PRE>
|
||||
<P>It is called with the result of the converter's <CODE>out_of_range()</CODE>
|
||||
inside <CODE>validate_range()</CODE>.</P>
|
||||
<P>These are the two overflow handler classes provided by the
|
||||
library:</P>
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
|
||||
struct <A NAME="oh_def">def_overflow_handler</a>
|
||||
{
|
||||
void operator() ( range_check_result r ) // throw bad_numeric_conversion derived
|
||||
{
|
||||
if ( r == cNegOverflow )
|
||||
throw negative_overflow() ;
|
||||
else if ( r == cPosOverflow )
|
||||
throw positive_overflow() ;
|
||||
}
|
||||
} ;
|
||||
|
||||
struct <A NAME="oh_silent">silent_overflow_handler</a>
|
||||
{
|
||||
void operator() ( range_check_result ) // no-throw
|
||||
{}
|
||||
} ;
|
||||
|
||||
} }
|
||||
</PRE>
|
||||
|
||||
<P>And these are the Exception Classes thrown by the default
|
||||
overflow handler <a href="#x-note">(see IMPORTANT note)</a></P>
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
|
||||
class <a name="bad_numc">bad_numeric_cast</a> : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char *what() const // throw()
|
||||
{ return "bad numeric conversion: overflow"; }
|
||||
};
|
||||
|
||||
class <a name="negovr">negative_overflow</a> : public bad_numeric_conversion
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char *what() const // throw()
|
||||
{ return "bad numeric conversion: negative overflow"; }
|
||||
};
|
||||
class <a name="posovr">positive_overflow</a> : public bad_numeric_conversion
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char *what() const // throw()
|
||||
{ return "bad numeric conversion: positive overflow"; }
|
||||
};
|
||||
} }
|
||||
</PRE>
|
||||
|
||||
<a name="x-note"><p><b>IMPORTANT RELEASE NOTE for 1.33</b></p></a>
|
||||
<blockquote>
|
||||
<p>Previous to boost version 1.33, the exception class <code>bad_numeric_cast</code> was
|
||||
named <code>bad_numeric_conversion</code>. However, in 1.33, the old function
|
||||
<code>numeric_cast<></code> from <code>boost/cast.hpp</code> was completly replaced by the new
|
||||
<code>numeric_cast<></code> in <code>boost/numeric/conversion/cast.hpp</code>
|
||||
(and <code>boost/cast.hpp</code> is including <code>boost/numeric/conversion/cast.hpp</code> now). That old function which
|
||||
existed in boost for quite some time used the <code>bad_numeric_cast</code> as its
|
||||
exception type so I decided to avoid backward compatibility problems by adopting it (guessing
|
||||
that the user base for the old code is wider than for the new code).</p>
|
||||
</blockquote>
|
||||
|
||||
<HR>
|
||||
<H2><A NAME="f2i">Policy <CODE>FloatToIntRounder</CODE></A></H2>
|
||||
<P>This <EM>stateless</EM> template policy class specifies the rounding mode used
|
||||
for<U> float to integral</U> conversions. It supplies the <CODE>"nearbyint()"</CODE>
|
||||
static member function exposed by the converter, which means that it <U>publicly
|
||||
inherits from this policy.</U></P>
|
||||
<P>The policy must have the following interface:</P>
|
||||
<PRE> template<class S>
|
||||
struct YourFloat2IntRounderPolicy
|
||||
{
|
||||
typedef S source_type ;
|
||||
typedef <I>{S or S const&}</I> argument_type ;
|
||||
|
||||
static source_type nearbyint ( argument_type s ) { ... }
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::<i>round_...</i>> round_style ;
|
||||
} ;
|
||||
</PRE>
|
||||
|
||||
<P>These are the rounder classes provided by the library:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P><EM>NOTE: These classes are not intended to be general purpose rounding functions
|
||||
but specific policies for converter<>. This is why <U>they are not function
|
||||
objects</U>.</EM></P>
|
||||
<P>(only the specific parts are shown, see the general policy form above)</P>
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
<A NAME="trunc"></A>template<class S>
|
||||
struct Trunc
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
using std::floor ;
|
||||
using std::ceil ;
|
||||
return s >= static_cast<S>(0) ? floor(s) : ceil(s) ;
|
||||
}
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_toward_zero> round_style ;
|
||||
} ;
|
||||
</PRE>
|
||||
<PRE> <A NAME="round"></A>template<class S>
|
||||
struct RoundEven
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
return <i>impl-defined-value</i> ;
|
||||
}
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_to_nearest> round_style ;
|
||||
} ;
|
||||
</PRE>
|
||||
<PRE> <A NAME="ceil"></A>template<class S>
|
||||
struct Ceil
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{<br> using std::ceil ;<br> return ceil(s) ;<br> }
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_toward_infinity> round_style ;
|
||||
} ;
|
||||
</PRE>
|
||||
<PRE> <A NAME="floor"></A>template<class S>
|
||||
struct Floor
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{<br> using std::floor ;<br> return floor(s) ;<br> }
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_toward_neg_infinity> round_style ;
|
||||
} ;
|
||||
|
||||
} } // namespace numeric, namespace boost</PRE>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
<H3>Math Functions used by the rounder policies</H3>
|
||||
<P>The rounder policies supplied by this header use math functions floor() and
|
||||
ceil(). The standard versions of these functions are introduced in context by
|
||||
a using directive, so in normal conditions, the standard functions will be used.
|
||||
<br>
|
||||
However, if there are other visible corresponding overloads an ambiguity could
|
||||
arise. In this case, the user can supply her own rounder policy which could,
|
||||
for instance, use a fully qualified call.<br>
|
||||
This technique allows the default rounder policies to be used directly with
|
||||
user defined types. The user only requires that suitable overloads of floor()
|
||||
and ceil() be visible. See also <a HREF="requirements.html">User Defined Numeric Types support</a><br>
|
||||
</P>
|
||||
<HR>
|
||||
<H2><A NAME="rawc">Policy <CODE>RawConverter</CODE></A></H2>
|
||||
<P>This <EM>stateless</EM> template policy class is used to perform the actual
|
||||
conversion from Source to Target. It supplies the <CODE>"low_level_convert()"</CODE>
|
||||
static member function exposed by the converter, which means that it <U>publicly
|
||||
inherits from this policy.</U></P>
|
||||
<P>The policy must have the following interface:</P>
|
||||
<PRE> template<class Traits>
|
||||
struct YourRawConverterPolicy
|
||||
{
|
||||
typedef typename Traits::result_type result_type ;
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
|
||||
static result_type low_level_convert ( argument_type s ) { return <I><impl defined></I> ; }
|
||||
} ;
|
||||
</PRE>
|
||||
|
||||
<P>This policy is mostly provided as a hook for user defined types which don't
|
||||
support <CODE>static_cast<></CODE> conversions to some types</P>
|
||||
|
||||
<P>This is the only raw converter policy class provided
|
||||
by the library:</P>
|
||||
<PRE>namespace boost { namespace numeric {
|
||||
|
||||
|
||||
template<class Traits>
|
||||
struct <A NAME="rawnumc">raw_numeric_converter</A>
|
||||
{
|
||||
typedef typename Traits::result_type result_type ;
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
|
||||
static result_type low_level_convert ( argument_type s )
|
||||
{ return static_cast<result_type>(s) ; }
|
||||
} ;
|
||||
|
||||
}
|
||||
</PRE>
|
||||
|
||||
<HR>
|
||||
<H2><A NAME="rc">Policy <CODE>UserRangeChecker</CODE></A></H2>
|
||||
<P>This <EM>stateless</EM> template policy class is used -<u>only if supplied</u>-
|
||||
to <b>override</b> the internal range checking logic.<br>
|
||||
It supplies the <CODE>"validate_range()"</CODE> static member function
|
||||
exposed by the converter, which means that it <U>publicly inherits from this
|
||||
policy.</U></P>
|
||||
<P>The policy must have the following interface:</P>
|
||||
<PRE> template<class Traits>
|
||||
struct YourRangeCheckerPolicy
|
||||
{
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
|
||||
// Determines if the value 's' fits in the range of the Target type.
|
||||
static range_check_result out_of_range ( argument_type s ) ;
|
||||
|
||||
// Checks whether the value 's' is out_of_range()
|
||||
// and passes the result of the check to the OverflowHandler policy.
|
||||
static void validate_range ( argument_type s )
|
||||
{
|
||||
OverflowHandler()( out_of_range(s) ) ;
|
||||
}
|
||||
} ;
|
||||
</PRE>
|
||||
<P>This policy is <b>only</b> provided as a hook for user defined types which
|
||||
require range checking (which is disabled by default when a UDT is involved).<br>
|
||||
The library provides a class: <A NAME="int_rc"><code>UseInternalRangeChecker{};</code></a> which
|
||||
is a <i>fake</i> RangeChecker policy used to signal the converter to use its
|
||||
internal range checking implementation.
|
||||
</P>
|
||||
<HR>
|
||||
<P>Back to <A HREF="index.html">Numeric Conversion library index</A></P>
|
||||
<HR>
|
||||
<P>Revised 23 June 2004</P>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,311 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 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)
|
||||
]
|
||||
|
||||
[section Numeric Converter Policy Classes]
|
||||
|
||||
|
||||
[section enum range_check_result]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
enum range_check_result
|
||||
{
|
||||
cInRange ,
|
||||
cNegOverflow ,
|
||||
cPosOverflow
|
||||
} ;
|
||||
|
||||
} }
|
||||
|
||||
Defines the values returned by `boost::numeric::converter<>::out_of_range()`
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Policy OverflowHandler]
|
||||
|
||||
This ['stateless] non-template policy class must be a ['function object] and is
|
||||
called to administrate the result of the range checking. It can throw an exception
|
||||
if overflow has been detected by the range checking as indicated by its argument.
|
||||
If it throws, is is recommended that it be `std::bad_cast` or derived.
|
||||
|
||||
It must have the following interface (it does not has to be a template class):
|
||||
|
||||
struct YourOverflowHandlerPolicy
|
||||
{
|
||||
void operator() ( boost::range_check_result ) ; // throw bad_cast or derived
|
||||
} ;
|
||||
|
||||
It is called with the result of the converter's `out_of_range()` inside `validate_range()`.
|
||||
|
||||
These are the two overflow handler classes provided by the library:
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
struct def_overflow_handler
|
||||
{
|
||||
void operator() ( range_check_result r ) // throw bad_numeric_conversion derived
|
||||
{
|
||||
if ( r == cNegOverflow )
|
||||
throw negative_overflow() ;
|
||||
else if ( r == cPosOverflow )
|
||||
throw positive_overflow() ;
|
||||
}
|
||||
} ;
|
||||
|
||||
struct silent_overflow_handler
|
||||
{
|
||||
void operator() ( range_check_result ) // no-throw
|
||||
{}
|
||||
} ;
|
||||
|
||||
} }
|
||||
|
||||
And these are the Exception Classes thrown by the default overflow handler
|
||||
[link numeric_conversion_policy_overflow_handler_important_note (see IMPORTANT note)]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
``[#numeric_conversion_bad_numeric_cast]``
|
||||
class bad_numeric_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const // throw()
|
||||
{
|
||||
return "bad numeric conversion: overflow";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
``[#numeric_conversion_negative_overflow]``
|
||||
class negative_overflow : public bad_numeric_cast
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const // throw()
|
||||
{
|
||||
return "bad numeric conversion: negative overflow";
|
||||
}
|
||||
};
|
||||
|
||||
``[#numeric_conversion_possitive_overflow]``
|
||||
class positive_overflow : public bad_numeric_cast
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const // throw()
|
||||
{
|
||||
return "bad numeric conversion: positive overflow";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} }
|
||||
|
||||
[#numeric_conversion_policy_overflow_handler_important_note]
|
||||
|
||||
[important [*RELEASE NOTE for 1.33]
|
||||
Previous to boost version 1.33, the exception class `bad_numeric_cast` was
|
||||
named `bad_numeric_conversion`. However, in 1.33, the old function
|
||||
`numeric_cast<>` from `boost/cast.hpp` was completly replaced by the
|
||||
new `numeric_cast<>` in `boost/numeric/conversion/cast.hpp`
|
||||
(and `boost/cast.hpp` is including `boost/numeric/conversion/cast.hpp` now).
|
||||
That old function which existed in boost for quite some time used the
|
||||
`bad_numeric_cast` as its exception type so I decided to avoid backward
|
||||
compatibility problems by adopting it (guessing that the user base for
|
||||
the old code is wider than for the new code).
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Policy Float2IntRounder]
|
||||
|
||||
This ['stateless] template policy class specifies the rounding mode used
|
||||
for [_float to integral] conversions. It supplies the `nearbyint()`
|
||||
static member function exposed by the converter, which means that it
|
||||
[_publicly inherits from this policy].
|
||||
|
||||
The policy must have the following interface:
|
||||
|
||||
template<class S>
|
||||
struct YourFloat2IntRounderPolicy
|
||||
{
|
||||
typedef S source_type ;
|
||||
typedef {S or S const&} argument_type ;
|
||||
|
||||
static source_type nearbyint ( argument_type s ) { ... }
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_...> round_style ;
|
||||
|
||||
} ;
|
||||
|
||||
These are the rounder classes provided by the library (only the specific parts are shown,
|
||||
see the general policy form above)
|
||||
|
||||
[note
|
||||
These classes are not intended to be general purpose rounding functions
|
||||
but specific policies for `converter<>`. This is why they are not function objects.
|
||||
]
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
|
||||
template<class S>
|
||||
struct Trunc
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
using std::floor ;
|
||||
using std::ceil ;
|
||||
|
||||
return s >= static_cast<S>(0) ? floor(s) : ceil(s) ;
|
||||
}
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_toward_zero> round_style ;
|
||||
} ;
|
||||
|
||||
|
||||
template<class S>
|
||||
struct RoundEven
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
return impl-defined-value ;
|
||||
}
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_to_nearest> round_style ;
|
||||
} ;
|
||||
|
||||
|
||||
template<class S>
|
||||
struct Ceil
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
using std::ceil ;
|
||||
return ceil(s) ;
|
||||
}
|
||||
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_toward_infinity> round_style ;
|
||||
} ;
|
||||
|
||||
|
||||
template<class S>
|
||||
struct Floor
|
||||
{
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
using std::floor ;
|
||||
return floor(s) ;
|
||||
}
|
||||
typedef mpl::integral_c<std::float_round_style,std::round_toward_neg_infinity> round_style ;
|
||||
} ;
|
||||
|
||||
} } // namespace numeric, namespace boost
|
||||
|
||||
[heading Math Functions used by the rounder policies]
|
||||
|
||||
The rounder policies supplied by this header use math functions `floor()` and `ceil()`.
|
||||
The standard versions of these functions are introduced in context by a using directive,
|
||||
so in normal conditions, the standard functions will be used.
|
||||
|
||||
However, if there are other visible corresponding overloads an ambiguity could arise.
|
||||
In this case, the user can supply her own rounder policy which could, for instance,
|
||||
use a fully qualified call.
|
||||
|
||||
This technique allows the default rounder policies to be used directly with
|
||||
user defined types. The user only requires that suitable overloads of `floor()` and `ceil()`
|
||||
be visible. See also [link boost_numericconversion.type_requirements_and_user_defined_types_support User Defined Numeric Types]
|
||||
support.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Policy RawConverter]
|
||||
|
||||
This ['stateless] template policy class is used to perform the
|
||||
actual conversion from Source to Target. It supplies the
|
||||
`low_level_convert()` static member function exposed by the
|
||||
converter, which means that it publicly inherits from this policy.
|
||||
|
||||
The policy must have the following interface:
|
||||
|
||||
template<class Traits>
|
||||
struct YourRawConverterPolicy
|
||||
{
|
||||
typedef typename Traits::result_type result_type ;
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
|
||||
static result_type low_level_convert ( argument_type s ) { return <impl defined> ; }
|
||||
} ;
|
||||
|
||||
|
||||
This policy is mostly provided as a hook for user defined types which don't support `static_cast<>` conversions to some types
|
||||
|
||||
This is the only raw converter policy class provided by the library:
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
template<class Traits>
|
||||
struct raw_numeric_converter
|
||||
{
|
||||
typedef typename Traits::result_type result_type ;
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
|
||||
static result_type low_level_convert ( argument_type s )
|
||||
{
|
||||
return static_cast<result_type>(s) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
} }
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Policy UserRangeChecker]
|
||||
|
||||
This ['stateless] template policy class is used [_only if supplied]
|
||||
to [*override] the internal range checking logic.
|
||||
|
||||
It supplies the `validate_range()` static member function
|
||||
exposed by the converter, which means that it publicly inherits
|
||||
from this policy.
|
||||
|
||||
The policy must have the following interface:
|
||||
|
||||
template<class Traits>
|
||||
struct YourRangeCheckerPolicy
|
||||
{
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
|
||||
// Determines if the value 's' fits in the range of the Target type.
|
||||
static range_check_result out_of_range ( argument_type s ) ;
|
||||
|
||||
// Checks whether the value 's' is out_of_range()
|
||||
// and passes the result of the check to the OverflowHandler policy.
|
||||
static void validate_range ( argument_type s )
|
||||
{
|
||||
OverflowHandler()( out_of_range(s) ) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
This policy is [*only] provided as a hook for user defined types which require
|
||||
range checking (which is disabled by default when a UDT is involved).
|
||||
The library provides a class: `UseInternalRangeChecker{}`; which is a ['fake]
|
||||
`RangeChecker` policy used to signal the converter to use its internal
|
||||
range checking implementation.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,471 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - Definitions</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000ff" VLINK="#800080">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TH VALIGN="top" WIDTH="300">
|
||||
<H3><A HREF="../../../../index.htm"><IMG HEIGHT="86" WIDTH="277"
|
||||
ALT="C++ Boost" SRC="../../../../boost.png" BORDER="0"></A></H3> </TH>
|
||||
<TH VALIGN="top">
|
||||
<H1 ALIGN="center">Boost Numeric Conversion Library</H1>
|
||||
<H1 ALIGN="center">Definitions</H1>
|
||||
</TH>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<HR>
|
||||
<H2>Contents</H2>
|
||||
<DL CLASS="page-index">
|
||||
<dt><A HREF="#intro">Introduction</A></dt>
|
||||
<dt><A HREF="#typeval">Types and Values</A></dt>
|
||||
<dt><A HREF="#stdtypes">C++ Arithmetic Types</A></dt>
|
||||
<dt><A HREF="#numtypes">Numeric Types</A></dt>
|
||||
<dt><A HREF="#range">Range and Precision</A></dt>
|
||||
<dt><A HREF="#roundoff">Exact, Correctly Rounded and Out-Of-Range Representations</A></dt>
|
||||
<dt><A HREF="#stdconv">Standard (numeric) Conversions</A></dt>
|
||||
<dt><A HREF="#subranged">Subranged Conversion Direction, Subtype and Supertype</A></dt>
|
||||
</DL>
|
||||
|
||||
|
||||
|
||||
<h2><A NAME="intro">Introduction</A></h2>
|
||||
<P>This section provides definitions of terms used in the Numeric Conversion library.</p>
|
||||
<p><b>Notation:</b>
|
||||
<li><u>underlined text</u> denotes terms defined in the C++ standard.</li>
|
||||
<li><b>bold face</b> denotes terms defined here but not in the standard.</li>
|
||||
<p></p>
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><A NAME="typeval">Types and Values</A></h2>
|
||||
<p>As defined by the <u>C++ Object Model</u> (§1.7) the <u>storage</u> or
|
||||
memory on which a C++ program runs is a contiguous sequence of <u>bytes</u>
|
||||
where each byte is a contiguous sequence of <u>bits</u>.<br>
|
||||
An <u>object</u> is a region of storage (§1.8) and has a type (§3.9).<br>
|
||||
A <u>type</u> is a discrete set of values. <br>
|
||||
An object of type T has an <u>object representation</u> which is the sequence
|
||||
of bytes stored in the object (§3.9/4)<br>
|
||||
An object of type T has a <u>value representation</u> which is the set of bits
|
||||
that determine the <i>value</i> of an object of that type (§3.9/4). For
|
||||
<u>POD</u> types (§3.9/10), this bitset is given by the object representation,
|
||||
but not all the bits in the storage need to participate in the value representation
|
||||
(except for character types): for example, some bits might be used for padding
|
||||
or there may be trap-bits.</p>
|
||||
<p>The <b>typed value</b> that is held by an object is
|
||||
the value which is determined by its value representation.<br>
|
||||
An <b>abstract value</b> (untyped) is
|
||||
the conceptual information that is represented in a type
|
||||
(i.e. the number π).<br>
|
||||
The <b>intrinsic value</b> of an object is
|
||||
the binary value of the sequence of unsigned characters which form its object representation.</p>
|
||||
<p><i>Abstract values</i> can be <b>represented</b> in a given type.<br>
|
||||
To <b>represent</b> an abstract value 'V' in a type 'T'
|
||||
is to obtain a typed value 'v' which <i>corresponds</i> to the abstract value 'V'.<br>
|
||||
The operation is denoted using the 'rep()' operator, as in: <code>v=rep(V)</code>.<br>
|
||||
'v' is the <b>representation</b> of 'V' in the type 'T'.<br>
|
||||
For example, the abstract value π can be represented in the type <code>'double'</code> as the
|
||||
'double value M_PI' and in the type <code>'int'</code> as the 'int value 3'</p>
|
||||
<p>Conversely, <i>typed values</i> can be <b>abstracted</b>.<br>
|
||||
To <b>abstract</b> a typed value 'v' of type 'T' is to obtain the
|
||||
abstract value 'V' whose representation in 'T' is 'v'.<br>
|
||||
The operation is denoted using the 'abt()' operator, as in: <code>V=abt(v)</code>.<br>
|
||||
'V' is the <b>abstraction</b> of 'v' of type 'T'.<br>
|
||||
Abstraction is just an abstract operation (you can't do it); but it is defined nevertheless
|
||||
because it will be used to give the definitions in the rest of this document.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><A NAME="stdtypes">C++ Arithmetic Types</A></h2>
|
||||
<P>The C++ language defines <u>fundamental types</u> (§3.9.1). The following
|
||||
subsets of the fundamental types are intended to represent <i>numbers</i>:</p>
|
||||
<li><u>signed integer types</u> (§3.9.1/2):<br>
|
||||
<blockquote>
|
||||
<code>{signed char, signed short int, signed int, signed long int}</code><br>
|
||||
Can be used to represent general integer numbers (both negative and positive).
|
||||
</blockquote>
|
||||
</li>
|
||||
<li><u>unsigned integer types</u> (§3.9.1/3):<br>
|
||||
<blockquote>
|
||||
<code>{unsigned char, unsigned short int, unsigned int, unsigned long int}</code><br>
|
||||
Can be used to represent positive integer numbers <u>with modulo-arithmetic</u>.<br>
|
||||
</blockquote>
|
||||
<li><u>floating-point types</u> (§3.9.1/8):<br>
|
||||
<blockquote>
|
||||
<code>{float,double,long double}</code><br>
|
||||
Can be used to represent real numbers.
|
||||
</blockquote>
|
||||
</li>
|
||||
<li><u>integral or integer types</u> (§3.9.1/7):<br>
|
||||
<blockquote>
|
||||
<code>{{signed integers},{unsigned integers}, bool, char and wchar_t}</code>
|
||||
</blockquote>
|
||||
</li>
|
||||
<li><u>arithmetic types</u> (§3.9.1/8):<br>
|
||||
<blockquote>
|
||||
<code>{{integer types},{floating types}}</code>
|
||||
</blockquote>
|
||||
</li>
|
||||
<P>The integer types are required to have a <i>binary</i> value representation.<br>
|
||||
Additionally, the signed/unsigned integer types of the same base type (short, int or long)
|
||||
are required to have the same value representation, that is:</P>
|
||||
<pre> int i = -3 ; // suppose value representation is: 10011 (sign bit + 4 magnitude bits)
|
||||
unsigned int u = i ; // u is required to have the same 10011 as its value representation.
|
||||
</pre>
|
||||
<P>In other words, the integer types signed/unsigned X use the same value representation
|
||||
but a different <i>interpretation</i> of it; that is, their <i>typed values</i>
|
||||
might differ.<br>
|
||||
Another consequence of this is that the range for signed X is always a smaller subset
|
||||
of the range of unsigned X, as required by §3.9.1/3.</P>
|
||||
<P>Note: always remember that unsigned types, unlike signed types, have modulo-arithmetic;
|
||||
that is, they do not overflow.<br>
|
||||
This means that:
|
||||
<li> Always be extra careful when mixing signed/unsigned types</li>
|
||||
<li> Use unsigned types only when you need modulo arithmetic or very very large numbers.
|
||||
Don't use unsigned types just because you intend to deal with positive values only
|
||||
(you can do this with signed types as well).</li>.
|
||||
<p></P>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><A NAME="numtypes">Numeric Types</A></h2>
|
||||
<p>This section introduces the following definitions intended to integrate arithmetic
|
||||
types with user-defined types which behave like numbers. Some definitions are
|
||||
purposely broad in order to include a vast variety of user-defined number
|
||||
types.</p>
|
||||
<p>Within this library, the term <i>number</i> refers to an abstract numeric value.</p>
|
||||
<p>A type is <b>numeric</b> if:</p>
|
||||
<li>It is an arithmetic type, or,</li>
|
||||
<li>It is a user-defined type which</li>
|
||||
<blockquote>
|
||||
<li>Represents numeric abstract values (i.e. numbers).</li>
|
||||
|
||||
<li>Can be converted (either implicitly or explicitly) to/from at least one
|
||||
arithmetic type.</li>
|
||||
<li>Has <a href="#range">range</a> (possibly unbounded) and <a href="#range">precision</a>
|
||||
(possibly dynamic or unlimited).</li>
|
||||
<li>Provides an specialization of <code>std::numeric_limits</code>.</li>
|
||||
</blockquote>
|
||||
<p></p>
|
||||
<p>A numeric type is <b>signed</b> if the abstract values it represent include negative numbers.<br>
|
||||
A numeric type is <b>unsigned</b> if the abstract values it represent exclude negative numbers.<br>
|
||||
A numeric type is <b>modulo</b> if it has modulo-arithmetic (does not overflow).<br>
|
||||
A numeric type is <b>integer</b> if the abstract values it represent are whole numbers.<br>
|
||||
A numeric type is <b>floating</b> if the abstract values it represent are real numbers.<br>
|
||||
An <b>arithmetic value</b> is the typed value of an arithmetic type<br>
|
||||
A <b>numeric value</b> is the typed value of a numeric type</p>
|
||||
<p></p>
|
||||
<p>These definitions simply generalize the standard notions of arithmetic types
|
||||
and values by introducing a superset called <u>numeric</u>. All arithmetic types
|
||||
and values are numeric types and values, but not vice versa, since user-defined
|
||||
numeric types are not arithmetic types.</p>
|
||||
<p>The following examples clarify the differences between arithmetic and numeric types (and values):</p>
|
||||
<pre>// A numeric type which is not an arithmetic type (is user-defined)
|
||||
// and which is intended to represent integer numbers (i.e., an 'integer' numeric type)
|
||||
class MyInt
|
||||
{
|
||||
MyInt ( long long v ) ;
|
||||
long long to_builtin();
|
||||
} ;
|
||||
namespace std {
|
||||
template<> numeric_limits<MyInt> { ... } ;
|
||||
}
|
||||
|
||||
// A 'floating' numeric type (double) which is also an arithmetic type (built-in),
|
||||
// with a float numeric value.
|
||||
double pi = M_PI ;
|
||||
|
||||
// A 'floating' numeric type with a whole numeric value.
|
||||
// NOTE: numeric values are typed valued, hence, they are, for instance,
|
||||
// integer or floating, despite the value itself being whole or including
|
||||
// a fractional part.
|
||||
double two = 2.0 ;
|
||||
|
||||
// An integer numeric type with an integer numeric value.
|
||||
MyInt i(1234);
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><A NAME="range">Range and Precision</A></h2>
|
||||
<p>Given a number set 'N', some of its elements are representable in a numeric type 'T'.<br>
|
||||
The set of representable values of type 'T', or numeric set of 'T', is a set of numeric values
|
||||
whose elements are the representation of some <i>subset</i> of 'N'.<br>
|
||||
For example, the interval of 'int' values [INT_MIN,INT_MAX] is the set of representable values
|
||||
of type 'int', i.e. the 'int' numeric set, and corresponds to the representation of the elements
|
||||
of the interval of abstract values [abt(INT_MIN),abt(INT_MAX)] from the integer numbers.<br>
|
||||
Similarly, the interval of 'double' values [-DBL_MAX,DBL_MAX] is the 'double' numeric set,
|
||||
which corresponds to the subset of the real numbers from abt(-DBL_MAX) to abt(DBL_MAX).
|
||||
</p>
|
||||
<p>Let <b>next(x)</b> denote the lowest numeric value greater than x.<br>
|
||||
Let <b>prev(x)</b> denote the highest numeric value lower then x.</p>
|
||||
<p>Let <code><b>v=prev(next(V))</b></code> and <code><b>v=next(prev(V))</b></code> be identities that relate a numeric
|
||||
typed value 'v' with a number 'V'.</p>
|
||||
<p>An ordered pair of numeric values <i>x,y</i> s.t. <i>x<y</i> are <b>consecutive</b> iff
|
||||
<code>next(x)==y</code>.</p>
|
||||
<p>The abstract distance between consecutive numeric values is usually referred
|
||||
to as a <u>Unit in the Last Place</u>, or <b>ulp</b> for short. A ulp is a quantity whose abstract
|
||||
magnitude is <i>relative</i> to the numeric values it corresponds to: If the numeric set is not evenly
|
||||
distributed, that is, if the abstract distance between consecutive numeric values varies along the set
|
||||
-as is the case with the floating-point types-, the magnitude of 1ulp after the numeric value x
|
||||
might be (usually is) different from the magnitude of a 1ulp after the numeric value y for x!=y.</p>
|
||||
<p>Since numbers are inherently ordered, a <b>numeric set</b> of type 'T'
|
||||
is an ordered sequence of numeric values (of type 'T') of the form:
|
||||
</p>
|
||||
<p><code>REP(T)={l,next(l),next(next(l)),...,prev(prev(h)),prev(h),h}</code>
|
||||
</p>
|
||||
<p>where 'l' and 'h' are respectively the lowest and highest values of type 'T', called the
|
||||
<b>boundary values</b> of type T.</p>
|
||||
<p>A numeric set is discrete. It has a <b>size</b> which is the number
|
||||
of numeric values in the set, a <b>width</b> which is the abstract difference between
|
||||
the highest and lowest boundary values: [abt(h)-abt(l)], and a <b>density</b>
|
||||
which is the relation between its size and width: 'density=size/width'.<br>
|
||||
The integer types have density 1, which means that there are no unrepresentable integer numbers
|
||||
between abt(l) and abt(h) (i.e. there are no gaps). On the other hand,
|
||||
floating types have density much smaller than 1, which means that there are
|
||||
real numbers unrepresented between consecutive floating values (i.e. there are gaps).
|
||||
</p>
|
||||
<p>The interval of <u>abstract values</u> [abt(l),abt(h)] is the <b>range</b> of the type 'T',
|
||||
denoted 'R(T)'.<br>
|
||||
A range is a set of abstract values and not a set of numeric values. In other
|
||||
documents, such as the C++ standard, the word 'range' is <i>sometimes</i> used
|
||||
as synonym for 'numeric set', that is, as the ordered sequence of numeric values
|
||||
from 'l' to 'h'. In this document, however, a range is an abstract interval
|
||||
which subtends the numeric set.<br>
|
||||
For example, the sequence [-DBL_MAX,DBL_MAX] is the numeric set of the type 'double', and
|
||||
the real interval [abt(-DBL_MAX),abt(DBL_MAX)] is its range.<br>
|
||||
Notice, for instance, that the range of a floating-point type is <i>continuous</i> unlike
|
||||
its numeric set.<br>
|
||||
This definition was chosen because:
|
||||
<li>(a) The discrete set of numeric values is already given by the numeric set.</li>
|
||||
<li>(b) Abstract intervals are easier to compare and overlap since only boundary values
|
||||
need to be considered.</li><br>
|
||||
This definition allows for a concise definition of 'subranged' as given in the last section.<br>
|
||||
The width of a numeric set, as defined, is exactly equivalent to the width of a range.
|
||||
<p></p>
|
||||
<p>The <b>precision</b> of a type is given by the width or density of the numeric set.<br>
|
||||
For integer types, which have density 1, the precision is conceptually equivalent to the range
|
||||
and is determined by the number of bits used in the value representation: The higher the
|
||||
number of bits the bigger the size of the numeric set, the wider the range, and the higher
|
||||
the precision.<br>
|
||||
For floating types, which have density <<1, the precision is given not by the
|
||||
width of the range but by the density. In a typical implementation,
|
||||
the range is determined by the number of bits used in the exponent, and the precision by
|
||||
the number of bits used in the mantissa (giving the maximum number of significant digits
|
||||
that can be exactly represented). The higher the number of exponent bits the
|
||||
wider the range, while the higher the number of mantissa bits, the higher the precision.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><A NAME="roundoff">Exact, Correctly Rounded and Out-Of-Range Representations</A></h2>
|
||||
<p>Given an abstract value 'V' and a type 'T' with its corresponding range [abt(l),abt(h)]:</p>
|
||||
<p>If <code>V < abt(l)</code> or <code>V > abt(h)</code>, 'V' is <b>not representable</b>
|
||||
(cannot be represented) in the type T, or, equivalently, it's representation in the type 'T'
|
||||
is <b>out of range</b>, or <b>overflows</b>.<br>
|
||||
If <code>V < abt(l)</code>, the <b>overflow is negative</b>.<br>
|
||||
If <code>V > abt(h)</code>, the <b>overflow is positive</b>.
|
||||
</p>
|
||||
<p>If <code>V ≥ abt(l)</code> and <code>V ≤ abt(h)</code>,'V' is <b>representable</b>
|
||||
(can be represented) in the type T, or, equivalently, its representation in the type 'T'
|
||||
is in <b>in range</b>, or <b>does not overflow</b>.</p>
|
||||
<p>Notice that a numeric type, such as a C++ unsigned type, can define that any 'V' does not
|
||||
overflow by always representing not 'V' itself but the abstract value <code>U = [ V % (abt(h)+1) ]</code>,
|
||||
which is always in range.</p>
|
||||
<p>Given an abstract value 'V' represented in the type 'T' as 'v', the <b>roundoff</b> error
|
||||
of the representation is the abstract difference: (abt(v)-V).<br>
|
||||
Notice that a representation is an <i>operation</i>, hence, the roundoff error corresponds to
|
||||
the representation operation and not to the numeric value itself (i.e. numeric values do not
|
||||
have any error themselves)<br>
|
||||
If the roundoff is 0, the representation is <b>exact</b>, and 'V' is <b>exactly representable</b>
|
||||
in the type T.<br>
|
||||
If the roundoff is not 0, the representation is <b>inexact</b>, and 'V' is <b>inexactly representable</b>
|
||||
in the type T.</p>
|
||||
<p>Given an abstract value 'V' representable in a type 'T', there are always two consecutive
|
||||
numeric values of type 'T', 'prev' and 'next', such that <code>abt(prev) ≤ V ≤ abt(next)</code>.
|
||||
These are called the <b>adjacents</b> of 'V' in the type 'T'.<br>
|
||||
If a representation 'v' in a type 'T' -either exact or inexact-, is any of the adjacents of 'V'
|
||||
in that type, that is, if <code>v==prev or v==next</code>, the representation is
|
||||
<b>faithfully rounded</b>. If the choice between 'prev' and 'next'
|
||||
matches a given <b>rounding direction</b>, it is <b>correctly rounded</b>.<br>
|
||||
All exact representations are correctly rounded, but not all inexact representations are. In particular,
|
||||
C++ requires numeric conversions (described below) and the result of arithmetic operations
|
||||
(not covered by this document) to be correctly rounded, but batch operations propagate roundoff, thus
|
||||
final results are usually incorrectly rounded, that is, the numeric value 'r' which is the computed
|
||||
result is neither of the adjacents of the abstract value 'R' which is the theoretical result.<br>
|
||||
Because a correctly rounded representation is always one of adjacents of the abstract value being
|
||||
represented, the roundoff is guaranteed to be at most 1ulp.</p>
|
||||
<P>The following examples summarize the given definitions. Consider:</p>
|
||||
<li>A numeric type 'Int' representing integer numbers with a <i>numeric set</i>: {-2,-1,0,1,2}
|
||||
and <i>range</i>: [-2,2]</li>.
|
||||
<li>A numeric type 'Cardinal' representing integer numbers with a <i>numeric set</i>:
|
||||
{0,1,2,3,4,5,6,7,8,9} and <i>range</i>: [0,9] (no modulo-arithmetic here)</li>.
|
||||
<li>A numeric type 'Real' representing real numbers with a <i>numeric set</i>:
|
||||
{-2.0,-1.5,-1.0,-0.5,-0.0,+0.0,+0.5,+1.0,+1.5,+2.0} and <i>range</i>: [-2.0,+2.0]</li>
|
||||
<li>A numeric type 'Whole' representing real numbers with a <i>numeric set</i>:
|
||||
{-2.0,-1.0,0.0,+1.0,+2.0} and <i>range</i>: [-2.0,+2.0]</li>
|
||||
<p>First, notice that the types 'Real' and 'Whole' both represent real numbers, have the
|
||||
same range, but different precision.</p>
|
||||
<p>The integer number 1 (an abstract value) can be exactly represented in any of these types.<br>
|
||||
The integer number -1 can be exactly represented in 'Int', 'Real' and 'Whole', but cannot
|
||||
be represented in 'Cardinal', yielding negative overflow.<br>
|
||||
The real number 1.5 can be exactly represented in 'Real', and inexactly represented in the
|
||||
other types.<br>
|
||||
If 1.5 is represented as either 1 or 2 in any of the types (except Real), the
|
||||
representation is correctly rounded.<br>
|
||||
If 0.5 is represented as +1.5 in the type 'Real', it is incorrectly rounded.<br>
|
||||
(-2.0,-1.5) are the 'Real' adjacents of any real number in the interval [-2.0,-1.5],
|
||||
yet there are no 'Real' adjacents for x < -2.0, nor for x > +2.0.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><A NAME="stdconv">Standard (numeric) Conversions</A></h2>
|
||||
<P>The C++ language defines <u>Standard Conversions</u> (§4) some of which are
|
||||
conversions between arithmetic types.<br>
|
||||
These are <u>Integral promotions</u> (§4.5), <u>Integral conversions</u> (§4.7),
|
||||
<u>Floating point promotions</u> (§4.6), <u>Floating point conversions</u> (§4.8)
|
||||
and <u>Floating-integral conversions</u> (§4.9).<br>
|
||||
In the sequel, integral and floating point promotions are called <b>arithmetic promotions</b>,
|
||||
and these plus integral, floating-point and floating-integral conversions are called
|
||||
<b>arithmetic conversions</b> (i.e, promotions are conversions).
|
||||
</P>
|
||||
<P>Promotions, both Integral and Floating point, are <i>value-preserving</i>, which means
|
||||
that the typed value is not changed with the conversion.</p>
|
||||
<p>In the sequel, consider a source typed value 's' of type 'S', the source abstract value 'N=abt(s)',
|
||||
a destination type 'T'; and whenever possible, a result typed value 't' of type 'T'.</p>
|
||||
<p>Integer to integer conversions are always defined:<br>
|
||||
If 'T' is unsigned, the abstract value which is effectively represented is not 'N' but
|
||||
'M=[ N % ( abt(h) + 1 ) ]', where 'h' is the highest unsigned typed value of type 'T'.<br>
|
||||
If 'T' is signed and 'N' is not directly representable, the result 't' is
|
||||
<u>implementation-defined</u>, which means that the C++ implementation is required to produce
|
||||
a value 't' even if it is totally unrelated to 's'.</p>
|
||||
<p>Floating to Floating conversions are defined only if 'N' is representable;
|
||||
if it is not, the conversion has <u>undefined behavior.</u><br>
|
||||
If 'N' is exactly representable, 't' is required to be the exact representation.<br>
|
||||
If 'N' is inexactly representable, 't' is required to be one of the two adjacents, with
|
||||
an implementation-defined choice of rounding direction; that is, the conversion is required
|
||||
to be correctly rounded.</p>
|
||||
<p>Floating to Integer conversions represent not 'N' but 'M=trunc(N)', were trunc() is to truncate: i.e.
|
||||
to remove the fractional part, if any.<br>
|
||||
If 'M' is not representable in 'T', the conversion has <u>undefined behavior</u>
|
||||
(unless 'T' is bool, see §4.12).</p>
|
||||
<p>Integer to Floating conversions are always defined.<br>
|
||||
If 'N' is exactly representable, 't' is required to be the exact representation.<br>
|
||||
If 'N' is inexactly representable, 't' is required to be one of the two adjacents, with
|
||||
an implementation-defined choice of rounding direction; that is, the conversion is required
|
||||
to be correctly rounded.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><A NAME="subranged">Subranged Conversion Direction, Subtype and Supertype</A></h2>
|
||||
<P>Given a source type 'S' and a destination type 'T', there is a <b>conversion direction</b>
|
||||
denoted: <code>'S->T'</code>.<br>
|
||||
For any two ranges the following <i>range relation</i> can be defined: A range
|
||||
'X' can be <i>entirely contained</i> in a range 'Y', in which case it is said that
|
||||
'X' is enclosed by 'Y'.<br>
|
||||
Formally: R(S) is <b>enclosed</b> by R(T) iif (R(S) intersection R(T)) == R(S).</P>
|
||||
<P>If the source type range, R(S), is <i>not enclosed</i> in the target type range, R(T);
|
||||
that is, if (R(S) & R(T)) != R(S), the conversion direction is said to be <b>subranged</b>,
|
||||
which means that R(S) is not entirely contained in R(T) and therefore there is
|
||||
some portion of the source range which falls outside the target range. In other words,
|
||||
if a conversion direction S->T is subranged, there are values in S which cannot be represented
|
||||
in T because they are out of range.<br>
|
||||
Notice that for S->T, the adjective subranged applies to 'T'.</p>
|
||||
<p>Examples:<br>
|
||||
Given the following numeric types all representing real numbers:<br>
|
||||
<br>
|
||||
X with numeric set {-2.0,-1.0,0.0,+1.0,+2.0} and range [-2.0,+2.0]<br>
|
||||
Y with numeric set {-2.0,-1.5,-1.0,-0.5,0.0,+0.5,+1.0,+1.5,+2.0} and range [-2.0,+2.0]<br>
|
||||
Z with numeric set {-1.0,0.0,+1.0} and range [-1.0,+1.0]<br>
|
||||
<br>
|
||||
For:<br>
|
||||
<br>
|
||||
(a) X->Y:
|
||||
<blockquote>
|
||||
R(X) & R(Y) == R(X), then X->Y is not subranged.
|
||||
Thus, all values of type X are representable in the type Y.
|
||||
</blockquote>
|
||||
(b) Y->X:
|
||||
<blockquote>
|
||||
R(Y) & R(X) == R(Y), then Y->X is not subranged.
|
||||
Thus, all values of type Y are representable in the type X, but in this case, some values
|
||||
are <i>inexactly</i> representable (all the halves).<br>
|
||||
(note: it is to permit this case that a range is an interval of abstract values
|
||||
and not an interval of typed values)
|
||||
</blockquote>
|
||||
(b) X->Z:
|
||||
<blockquote>
|
||||
R(X) & R(Z) != R(X), then X->Z is subranged.
|
||||
Thus, some values of type X are not representable in the type Z, they fall out of range
|
||||
(-2.0 and +2.0)
|
||||
</blockquote>
|
||||
<p></p>
|
||||
<p>It is possible that R(S) is not enclosed by R(T), while neither is R(T) enclosed
|
||||
by R(S); for example, UNSIG=[0,255] is not enclosed by SIG=[-128,127]; neither is SIG
|
||||
enclosed by UNSIG.<br>
|
||||
This implies that is possible that a conversion direction is subranged both
|
||||
ways. This occurs when a mixture of signed/unsigned types are involved and indicates
|
||||
that in both directions there are values which can fall out of range.</P>
|
||||
<P>Given the range relation (subranged or not) of a conversion direction S->T,
|
||||
it is possible to classify 'S' and 'T' as <b>supertype</b> and <b>subtype</b>:<br>
|
||||
If the conversion is subranged, which means that 'T' cannot represent all possible values of type 'S',
|
||||
'S' is the supertype and 'T' the subtype; otherwise, 'T' is the supertype and 'S' the subtype.<br>
|
||||
<br>
|
||||
For example:<br>
|
||||
R(float)=[-FLT_MAX,FLT_MAX] and R(double)=[-DBL_MAX,DBL_MAX].<br>
|
||||
If FLT_MAX < DBL_MAX:<br>
|
||||
'double->float' is subranged and supertype=double, subtype=float.<br>
|
||||
'float->double' is not subranged and supertype=double, subtype=float.<br>
|
||||
Notice that while 'double->float' is subranged, 'float->double' is not,
|
||||
which yields the same supertype,subtype for both directions.<br>
|
||||
<br>
|
||||
Now consider:<br>
|
||||
R(int)=[INT_MIN,INT_MAX] and R(unsigned int)=[0,UINT_MAX].<br>
|
||||
A C++ implementation is required to have UINT_MAX > INT_MAX (§3.9/3), so:<br>
|
||||
'int->unsigned' is subranged (negative values fall out of range) and supertype=int, subtype=unsigned.<br>
|
||||
'unsigned->int' is <em>also</em> subranged (high positive values fall out of range)
|
||||
and supertype=unsigned, subtype=int.<br>
|
||||
In this case, the conversion is subranged in both directions and the supertype,subtype pairs
|
||||
are not invariant (under inversion of direction). This indicates that none of the types can
|
||||
represent all the values of the other.</p>
|
||||
<p>When the supertype is the same for both 'S->T' and 'T->S', it is effectively indicating
|
||||
a type which can represent all the values of the subtype.<br>
|
||||
Consequently, if a conversion X->Y is not subranged, but the opposite (Y->X)
|
||||
is, so that the supertype is always 'Y', it is said that the direction X->Y
|
||||
is <b>correctly rounded value preserving</b>, meaning that all such conversions
|
||||
are guaranteed to produce results in range and correctly rounded (even if inexact).<br>
|
||||
For example, all integer to floating conversions are correctly rounded value preserving.
|
||||
</p>
|
||||
<HR>
|
||||
<P>Back to <A HREF="index.html">Numeric Conversion library index</A></P>
|
||||
<HR>
|
||||
<P>Revised 23 June 2004</P>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</body>
|
||||
</HTML>
|
||||
@@ -0,0 +1,550 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 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)
|
||||
]
|
||||
|
||||
|
||||
[section Definitions]
|
||||
|
||||
[section Introduction]
|
||||
|
||||
This section provides definitions of terms used in the Numeric Conversion library.
|
||||
|
||||
[blurb [*Notation]
|
||||
[_underlined text] denotes terms defined in the C++ standard.
|
||||
|
||||
[*bold face] denotes terms defined here but not in the standard.
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Types and Values]
|
||||
|
||||
As defined by the [_C++ Object Model] (§1.7) the [_storage] or memory on which a
|
||||
C++ program runs is a contiguous sequence of [_bytes] where each byte is a
|
||||
contiguous sequence of bits.
|
||||
|
||||
An [_object] is a region of storage (§1.8) and has a type (§3.9).
|
||||
|
||||
A [_type] is a discrete set of values.
|
||||
|
||||
An object of type `T` has an [_object representation] which is the sequence of
|
||||
bytes stored in the object (§3.9/4)
|
||||
|
||||
An object of type `T` has a [_value representation] which is the set of
|
||||
bits that determine the ['value] of an object of that type (§3.9/4).
|
||||
For [_POD] types (§3.9/10), this bitset is given by the object representation,
|
||||
but not all the bits in the storage need to participate in the value
|
||||
representation (except for character types): for example, some bits might
|
||||
be used for padding or there may be trap-bits.
|
||||
|
||||
__SPACE__
|
||||
|
||||
The [*typed value] that is held by an object is the value which is determined
|
||||
by its value representation.
|
||||
|
||||
An [*abstract value] (untyped) is the conceptual information that is
|
||||
represented in a type (i.e. the number π).
|
||||
|
||||
The [*intrinsic value] of an object is the binary value of the sequence of
|
||||
unsigned characters which form its object representation.
|
||||
|
||||
__SPACE__
|
||||
|
||||
['Abstract] values can be [*represented] in a given type.
|
||||
|
||||
To [*represent] an abstract value `V` in a type `T` is to obtain a typed value
|
||||
`v` which corresponds to the abstract value `V`.
|
||||
|
||||
The operation is denoted using the `rep()` operator, as in: `v=rep(V)`.
|
||||
`v` is the [*representation] of `V` in the type `T`.
|
||||
|
||||
For example, the abstract value π can be represented in the type
|
||||
`double` as the `double value M_PI` and in the type `int` as the
|
||||
`int value 3`
|
||||
|
||||
__SPACE__
|
||||
|
||||
Conversely, ['typed values] can be [*abstracted].
|
||||
|
||||
To [*abstract] a typed value `v` of type `T` is to obtain the abstract value `V`
|
||||
whose representation in `T` is `v`.
|
||||
|
||||
The operation is denoted using the `abt()` operator, as in: `V=abt(v)`.
|
||||
|
||||
`V` is the [*abstraction] of `v` of type `T`.
|
||||
|
||||
Abstraction is just an abstract operation (you can't do it); but it is
|
||||
defined nevertheless because it will be used to give the definitions in the
|
||||
rest of this document.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section C++ Arithmetic Types]
|
||||
|
||||
The C++ language defines [_fundamental types] (§3.9.1). The following subsets of
|
||||
the fundamental types are intended to represent ['numbers]:
|
||||
|
||||
[variablelist
|
||||
[[[_signed integer types] (§3.9.1/2):][
|
||||
`{signed char, signed short int, signed int, signed long int}`
|
||||
Can be used to represent general integer numbers (both negative and positive).
|
||||
]]
|
||||
[[[_unsigned integer types] (§3.9.1/3):][
|
||||
`{unsigned char, unsigned short int, unsigned int, unsigned long int}`
|
||||
Can be used to represent positive integer numbers with modulo-arithmetic.
|
||||
]]
|
||||
[[[_floating-point types] (§3.9.1/8):][
|
||||
`{float,double,long double}`
|
||||
Can be used to represent real numbers.
|
||||
]]
|
||||
[[[_integral or integer types] (§3.9.1/7):][
|
||||
`{{signed integers},{unsigned integers}, bool, char and wchar_t}`
|
||||
]]
|
||||
[[[_arithmetic types] (§3.9.1/8):][
|
||||
`{{integer types},{floating types}}`
|
||||
]]
|
||||
]
|
||||
|
||||
The integer types are required to have a ['binary] value representation.
|
||||
|
||||
Additionally, the signed/unsigned integer types of the same base type
|
||||
(`short`, `int` or `long`) are required to have the same value representation,
|
||||
that is:
|
||||
|
||||
int i = -3 ; // suppose value representation is: 10011 (sign bit + 4 magnitude bits)
|
||||
unsigned int u = i ; // u is required to have the same 10011 as its value representation.
|
||||
|
||||
In other words, the integer types signed/unsigned X use the same value
|
||||
representation but a different ['interpretation] of it; that is, their
|
||||
['typed values] might differ.
|
||||
|
||||
Another consequence of this is that the range for signed X is always a smaller
|
||||
subset of the range of unsigned X, as required by §3.9.1/3.
|
||||
|
||||
[note
|
||||
Always remember that unsigned types, unlike signed types, have modulo-arithmetic;
|
||||
that is, they do not overflow.
|
||||
This means that:
|
||||
|
||||
[*-] Always be extra careful when mixing signed/unsigned types
|
||||
|
||||
[*-] Use unsigned types only when you need modulo arithmetic or very very large
|
||||
numbers. Don't use unsigned types just because you intend to deal with
|
||||
positive values only (you can do this with signed types as well).
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Numeric Types]
|
||||
|
||||
This section introduces the following definitions intended to integrate
|
||||
arithmetic types with user-defined types which behave like numbers.
|
||||
Some definitions are purposely broad in order to include a vast variety of
|
||||
user-defined number types.
|
||||
|
||||
Within this library, the term ['number] refers to an abstract numeric value.
|
||||
|
||||
A type is [*numeric] if:
|
||||
|
||||
* It is an arithmetic type, or,
|
||||
* It is a user-defined type which
|
||||
* Represents numeric abstract values (i.e. numbers).
|
||||
* Can be converted (either implicitly or explicitly) to/from at least one arithmetic type.
|
||||
* Has [link boost_numericconversion.definitions.range_and_precision range] (possibly unbounded)
|
||||
and [link boost_numericconversion.definitions.range_and_precision precision] (possibly dynamic or
|
||||
unlimited).
|
||||
* Provides an specialization of `std::numeric_limits`.
|
||||
|
||||
A numeric type is [*signed] if the abstract values it represent include negative numbers.
|
||||
|
||||
A numeric type is [*unsigned] if the abstract values it represent exclude negative numbers.
|
||||
|
||||
A numeric type is [*modulo] if it has modulo-arithmetic (does not overflow).
|
||||
|
||||
A numeric type is [*integer] if the abstract values it represent are whole numbers.
|
||||
|
||||
A numeric type is [*floating] if the abstract values it represent are real numbers.
|
||||
|
||||
An [*arithmetic value] is the typed value of an arithmetic type
|
||||
|
||||
A [*numeric value] is the typed value of a numeric type
|
||||
|
||||
These definitions simply generalize the standard notions of arithmetic types and
|
||||
values by introducing a superset called [_numeric]. All arithmetic types and values are
|
||||
numeric types and values, but not vice versa, since user-defined numeric types are not
|
||||
arithmetic types.
|
||||
|
||||
The following examples clarify the differences between arithmetic and numeric
|
||||
types (and values):
|
||||
|
||||
|
||||
// A numeric type which is not an arithmetic type (is user-defined)
|
||||
// and which is intended to represent integer numbers (i.e., an 'integer' numeric type)
|
||||
class MyInt
|
||||
{
|
||||
MyInt ( long long v ) ;
|
||||
long long to_builtin();
|
||||
} ;
|
||||
namespace std {
|
||||
template<> numeric_limits<MyInt> { ... } ;
|
||||
}
|
||||
|
||||
// A 'floating' numeric type (double) which is also an arithmetic type (built-in),
|
||||
// with a float numeric value.
|
||||
double pi = M_PI ;
|
||||
|
||||
// A 'floating' numeric type with a whole numeric value.
|
||||
// NOTE: numeric values are typed valued, hence, they are, for instance,
|
||||
// integer or floating, despite the value itself being whole or including
|
||||
// a fractional part.
|
||||
double two = 2.0 ;
|
||||
|
||||
// An integer numeric type with an integer numeric value.
|
||||
MyInt i(1234);
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Range and Precision]
|
||||
|
||||
Given a number set `N`, some of its elements are representable in a numeric type `T`.
|
||||
|
||||
The set of representable values of type `T`, or numeric set of `T`, is a set of numeric
|
||||
values whose elements are the representation of some subset of `N`.
|
||||
|
||||
For example, the interval of `int` values `[INT_MIN,INT_MAX]` is the set of representable
|
||||
values of type `int`, i.e. the `int` numeric set, and corresponds to the representation
|
||||
of the elements of the interval of abstract values `[abt(INT_MIN),abt(INT_MAX)]` from
|
||||
the integer numbers.
|
||||
|
||||
Similarly, the interval of `double` values `[-DBL_MAX,DBL_MAX]` is the `double`
|
||||
numeric set, which corresponds to the subset of the real numbers from `abt(-DBL_MAX)` to
|
||||
`abt(DBL_MAX)`.
|
||||
|
||||
__SPACE__
|
||||
|
||||
Let [*`next(x)`] denote the lowest numeric value greater than x.
|
||||
|
||||
Let [*`prev(x)`] denote the highest numeric value lower then x.
|
||||
|
||||
Let [*`v=prev(next(V))`] and [*`v=next(prev(V))`] be identities that relate a numeric
|
||||
typed value `v` with a number `V`.
|
||||
|
||||
An ordered pair of numeric values `x`,`y` s.t. `x<y` are [*consecutive] iff `next(x)==y`.
|
||||
|
||||
The abstract distance between consecutive numeric values is usually referred to as a
|
||||
[_Unit in the Last Place], or [*ulp] for short. A ulp is a quantity whose abstract
|
||||
magnitude is relative to the numeric values it corresponds to: If the numeric set
|
||||
is not evenly distributed, that is, if the abstract distance between consecutive
|
||||
numeric values varies along the set -as is the case with the floating-point types-,
|
||||
the magnitude of 1ulp after the numeric value `x` might be (usually is) different
|
||||
from the magnitude of a 1ulp after the numeric value y for `x!=y`.
|
||||
|
||||
Since numbers are inherently ordered, a [*numeric set] of type `T` is an ordered sequence
|
||||
of numeric values (of type `T`) of the form:
|
||||
|
||||
REP(T)={l,next(l),next(next(l)),...,prev(prev(h)),prev(h),h}
|
||||
|
||||
where `l` and `h` are respectively the lowest and highest values of type `T`, called
|
||||
the boundary values of type `T`.
|
||||
|
||||
__SPACE__
|
||||
|
||||
A numeric set is discrete. It has a [*size] which is the number of numeric values in the set,
|
||||
a [*width] which is the abstract difference between the highest and lowest boundary values:
|
||||
`[abt(h)-abt(l)]`, and a [*density] which is the relation between its size and width:
|
||||
`density=size/width`.
|
||||
|
||||
The integer types have density 1, which means that there are no unrepresentable integer
|
||||
numbers between `abt(l)` and `abt(h)` (i.e. there are no gaps). On the other hand,
|
||||
floating types have density much smaller than 1, which means that there are real numbers
|
||||
unrepresented between consecutive floating values (i.e. there are gaps).
|
||||
|
||||
__SPACE__
|
||||
|
||||
The interval of [_abstract values] `[abt(l),abt(h)]` is the range of the type `T`,
|
||||
denoted `R(T)`.
|
||||
|
||||
A range is a set of abstract values and not a set of numeric values. In other
|
||||
documents, such as the C++ standard, the word `range` is ['sometimes] used as synonym
|
||||
for `numeric set`, that is, as the ordered sequence of numeric values from `l` to `h`.
|
||||
In this document, however, a range is an abstract interval which subtends the
|
||||
numeric set.
|
||||
|
||||
For example, the sequence `[-DBL_MAX,DBL_MAX]` is the numeric set of the type
|
||||
`double`, and the real interval `[abt(-DBL_MAX),abt(DBL_MAX)]` is its range.
|
||||
|
||||
Notice, for instance, that the range of a floating-point type is ['continuous]
|
||||
unlike its numeric set.
|
||||
|
||||
This definition was chosen because:
|
||||
|
||||
* [*(a)] The discrete set of numeric values is already given by the numeric set.
|
||||
* [*(b)] Abstract intervals are easier to compare and overlap since only boundary
|
||||
values need to be considered.
|
||||
|
||||
This definition allows for a concise definition of `subranged` as given in the last section.
|
||||
|
||||
The width of a numeric set, as defined, is exactly equivalent to the width of a range.
|
||||
|
||||
__SPACE__
|
||||
|
||||
The [*precision] of a type is given by the width or density of the numeric set.
|
||||
|
||||
For integer types, which have density 1, the precision is conceptually equivalent
|
||||
to the range and is determined by the number of bits used in the value representation:
|
||||
The higher the number of bits the bigger the size of the numeric set, the wider the
|
||||
range, and the higher the precision.
|
||||
|
||||
For floating types, which have density <<1, the precision is given not by the width
|
||||
of the range but by the density. In a typical implementation, the range is determined
|
||||
by the number of bits used in the exponent, and the precision by the number of bits
|
||||
used in the mantissa (giving the maximum number of significant digits that can be
|
||||
exactly represented). The higher the number of exponent bits the wider the range,
|
||||
while the higher the number of mantissa bits, the higher the precision.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Exact, Correctly Rounded and Out-Of-Range Representations]
|
||||
|
||||
Given an abstract value `V` and a type `T` with its corresponding range `[abt(l),abt(h)]`:
|
||||
|
||||
If `V < abt(l)` or `V > abt(h)`, `V` is [*not representable] (cannot be represented) in
|
||||
the type `T`, or, equivalently, it's representation in the type `T` is [*out of range],
|
||||
or [*overflows].
|
||||
|
||||
* If `V < abt(l)`, the [*overflow is negative].
|
||||
* If `V > abt(h)`, the [*overflow is positive].
|
||||
|
||||
If `V >= abt(l)` and `V <= abt(h)`, `V` is [*representable] (can be represented) in the
|
||||
type `T`, or, equivalently, its representation in the type `T` is [*in range], or
|
||||
[*does not overflow].
|
||||
|
||||
Notice that a numeric type, such as a C++ unsigned type, can define that any `V` does
|
||||
not overflow by always representing not `V` itself but the abstract value
|
||||
`U = [ V % (abt(h)+1) ]`, which is always in range.
|
||||
|
||||
Given an abstract value `V` represented in the type `T` as `v`, the [*roundoff] error
|
||||
of the representation is the abstract difference: `(abt(v)-V)`.
|
||||
|
||||
Notice that a representation is an ['operation], hence, the roundoff error corresponds
|
||||
to the representation operation and not to the numeric value itself
|
||||
(i.e. numeric values do not have any error themselves)
|
||||
|
||||
* If the roundoff is 0, the representation is [*exact], and `V` is exactly representable
|
||||
in the type `T`.
|
||||
* If the roundoff is not 0, the representation is [*inexact], and `V` is inexactly
|
||||
representable in the type `T`.
|
||||
|
||||
If a representation `v` in a type `T` -either exact or inexact-, is any of the adjacents
|
||||
of `V` in that type, that is, if `v==prev` or `v==next`, the representation is
|
||||
faithfully rounded. If the choice between `prev` and `next` matches a given
|
||||
[*rounding direction], it is [*correctly rounded].
|
||||
|
||||
All exact representations are correctly rounded, but not all inexact representations are.
|
||||
In particular, C++ requires numeric conversions (described below) and the result of
|
||||
arithmetic operations (not covered by this document) to be correctly rounded, but
|
||||
batch operations propagate roundoff, thus final results are usually incorrectly
|
||||
rounded, that is, the numeric value `r` which is the computed result is neither of
|
||||
the adjacents of the abstract value `R` which is the theoretical result.
|
||||
|
||||
Because a correctly rounded representation is always one of adjacents of the abstract
|
||||
value being represented, the roundoff is guaranteed to be at most 1ulp.
|
||||
|
||||
The following examples summarize the given definitions. Consider:
|
||||
|
||||
* A numeric type `Int` representing integer numbers with a
|
||||
['numeric set]: `{-2,-1,0,1,2}` and
|
||||
['range]: `[-2,2]`
|
||||
* A numeric type `Cardinal` representing integer numbers with a
|
||||
['numeric set]: `{0,1,2,3,4,5,6,7,8,9}` and
|
||||
['range]: `[0,9]` (no modulo-arithmetic here)
|
||||
* A numeric type `Real` representing real numbers with a
|
||||
['numeric set]: `{-2.0,-1.5,-1.0,-0.5,-0.0,+0.0,+0.5,+1.0,+1.5,+2.0}` and
|
||||
['range]: `[-2.0,+2.0]`
|
||||
* A numeric type `Whole` representing real numbers with a
|
||||
['numeric set]: `{-2.0,-1.0,0.0,+1.0,+2.0}` and
|
||||
['range]: `[-2.0,+2.0]`
|
||||
|
||||
First, notice that the types `Real` and `Whole` both represent real numbers,
|
||||
have the same range, but different precision.
|
||||
|
||||
* The integer number `1` (an abstract value) can be exactly represented
|
||||
in any of these types.
|
||||
* The integer number `-1` can be exactly represented in `Int`, `Real` and `Whole`,
|
||||
but cannot be represented in `Cardinal`, yielding negative overflow.
|
||||
* The real number `1.5` can be exactly represented in `Real`, and inexactly
|
||||
represented in the other types.
|
||||
* If `1.5` is represented as either `1` or `2` in any of the types (except `Real`),
|
||||
the representation is correctly rounded.
|
||||
* If `0.5` is represented as `+1.5` in the type `Real`, it is incorrectly rounded.
|
||||
* `(-2.0,-1.5)` are the `Real` adjacents of any real number in the interval
|
||||
`[-2.0,-1.5]`, yet there are no `Real` adjacents for `x < -2.0`, nor for `x > +2.0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Standard (numeric) Conversions]
|
||||
|
||||
The C++ language defines [_Standard Conversions] (§4) some of which are conversions
|
||||
between arithmetic types.
|
||||
|
||||
These are [_Integral promotions] (§4.5), [_Integral conversions] (§4.7),
|
||||
[_Floating point promotions] (§4.6), [_Floating point conversions] (§4.8) and
|
||||
[_Floating-integral conversions] (§4.9).
|
||||
|
||||
In the sequel, integral and floating point promotions are called [*arithmetic promotions],
|
||||
and these plus integral, floating-point and floating-integral conversions are called
|
||||
[*arithmetic conversions] (i.e, promotions are conversions).
|
||||
|
||||
Promotions, both Integral and Floating point, are ['value-preserving], which means that
|
||||
the typed value is not changed with the conversion.
|
||||
|
||||
In the sequel, consider a source typed value `s` of type `S`, the source abstract
|
||||
value `N=abt(s)`, a destination type `T`; and whenever possible, a result typed value
|
||||
`t` of type `T`.
|
||||
|
||||
|
||||
Integer to integer conversions are always defined:
|
||||
|
||||
* If `T` is unsigned, the abstract value which is effectively represented is not
|
||||
`N` but `M=[ N % ( abt(h) + 1 ) ]`, where `h` is the highest unsigned typed
|
||||
value of type `T`.
|
||||
* If `T` is signed and `N` is not directly representable, the result `t` is
|
||||
[_implementation-defined], which means that the C++ implementation is required to
|
||||
produce a value `t` even if it is totally unrelated to `s`.
|
||||
|
||||
|
||||
Floating to Floating conversions are defined only if `N` is representable;
|
||||
if it is not, the conversion has [_undefined behavior].
|
||||
|
||||
* If `N` is exactly representable, `t` is required to be the exact representation.
|
||||
* If `N` is inexactly representable, `t` is required to be one of the two
|
||||
adjacents, with an implementation-defined choice of rounding direction;
|
||||
that is, the conversion is required to be correctly rounded.
|
||||
|
||||
|
||||
Floating to Integer conversions represent not `N` but `M=trunc(N)`, were
|
||||
`trunc()` is to truncate: i.e. to remove the fractional part, if any.
|
||||
|
||||
* If `M` is not representable in `T`, the conversion has [_undefined behavior]
|
||||
(unless `T` is `bool`, see §4.12).
|
||||
|
||||
|
||||
Integer to Floating conversions are always defined.
|
||||
|
||||
* If `N` is exactly representable, `t` is required to be the exact representation.
|
||||
* If `N` is inexactly representable, `t` is required to be one of the
|
||||
two adjacents, with an implementation-defined choice of rounding direction;
|
||||
that is, the conversion is required to be correctly rounded.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Subranged Conversion Direction, Subtype and Supertype]
|
||||
|
||||
Given a source type `S` and a destination type `T`, there is a
|
||||
[*conversion direction] denoted: `S->T`.
|
||||
|
||||
For any two ranges the following ['range relation] can be defined:
|
||||
A range `X` can be ['entirely contained] in a range `Y`, in which case
|
||||
it is said that `X` is enclosed by `Y`.
|
||||
|
||||
[: [*Formally:] `R(S)` is enclosed by `R(T)` iif `(R(S) intersection R(T)) == R(S)`.]
|
||||
|
||||
If the source type range, `R(S)`, is not enclosed in the target type range,
|
||||
`R(T)`; that is, if `(R(S) & R(T)) != R(S)`, the conversion direction is said
|
||||
to be [*subranged], which means that `R(S)` is not entirely contained in `R(T)`
|
||||
and therefore there is some portion of the source range which falls outside
|
||||
the target range. In other words, if a conversion direction `S->T` is subranged,
|
||||
there are values in `S` which cannot be represented in `T` because they are
|
||||
out of range.
|
||||
Notice that for `S->T`, the adjective subranged applies to `T`.
|
||||
|
||||
Examples:
|
||||
|
||||
Given the following numeric types all representing real numbers:
|
||||
|
||||
* `X` with numeric set `{-2.0,-1.0,0.0,+1.0,+2.0}` and range `[-2.0,+2.0]`
|
||||
* `Y` with numeric set `{-2.0,-1.5,-1.0,-0.5,0.0,+0.5,+1.0,+1.5,+2.0}` and range `[-2.0,+2.0]`
|
||||
* `Z` with numeric set `{-1.0,0.0,+1.0}` and range `[-1.0,+1.0]`
|
||||
|
||||
For:
|
||||
|
||||
[variablelist
|
||||
[[(a) X->Y:][
|
||||
`R(X) & R(Y) == R(X)`, then `X->Y` is not subranged.
|
||||
Thus, all values of type `X` are representable in the type `Y`.
|
||||
]]
|
||||
[[(b) Y->X:][
|
||||
`R(Y) & R(X) == R(Y)`, then `Y->X` is not subranged.
|
||||
Thus, all values of type `Y` are representable in the type `X`, but in this case,
|
||||
some values are ['inexactly] representable (all the halves).
|
||||
(note: it is to permit this case that a range is an interval of abstract values and
|
||||
not an interval of typed values)
|
||||
]]
|
||||
[[(b) X->Z:][
|
||||
`R(X) & R(Z) != R(X)`, then `X->Z` is subranged.
|
||||
Thus, some values of type `X` are not representable in the type `Z`, they fall
|
||||
out of range `(-2.0 and +2.0)`.
|
||||
]]
|
||||
]
|
||||
|
||||
It is possible that `R(S)` is not enclosed by `R(T)`, while neither is `R(T)` enclosed
|
||||
by `R(S)`; for example, `UNSIG=[0,255]` is not enclosed by `SIG=[-128,127]`;
|
||||
neither is `SIG` enclosed by `UNSIG`.
|
||||
This implies that is possible that a conversion direction is subranged both ways.
|
||||
This occurs when a mixture of signed/unsigned types are involved and indicates that
|
||||
in both directions there are values which can fall out of range.
|
||||
|
||||
Given the range relation (subranged or not) of a conversion direction `S->T`, it
|
||||
is possible to classify `S` and `T` as [*supertype] and [*subtype]:
|
||||
If the conversion is subranged, which means that `T` cannot represent all possible
|
||||
values of type `S`, `S` is the supertype and `T` the subtype; otherwise, `T` is the
|
||||
supertype and `S` the subtype.
|
||||
|
||||
For example:
|
||||
|
||||
[: `R(float)=[-FLT_MAX,FLT_MAX]` and `R(double)=[-DBL_MAX,DBL_MAX]` ]
|
||||
|
||||
If `FLT_MAX < DBL_MAX`:
|
||||
|
||||
* `double->float` is subranged and `supertype=double`, `subtype=float`.
|
||||
* `float->double` is not subranged and `supertype=double`, `subtype=float`.
|
||||
|
||||
Notice that while `double->float` is subranged, `float->double` is not,
|
||||
which yields the same supertype,subtype for both directions.
|
||||
|
||||
Now consider:
|
||||
|
||||
[: `R(int)=[INT_MIN,INT_MAX]` and `R(unsigned int)=[0,UINT_MAX]` ]
|
||||
|
||||
A C++ implementation is required to have `UINT_MAX > INT_MAX` (§3.9/3), so:
|
||||
|
||||
* 'int->unsigned' is subranged (negative values fall out of range)
|
||||
and `supertype=int`, `subtype=unsigned`.
|
||||
* 'unsigned->int' is ['also] subranged (high positive values fall out of range)
|
||||
and `supertype=unsigned`, `subtype=int`.
|
||||
|
||||
In this case, the conversion is subranged in both directions and the
|
||||
supertype,subtype pairs are not invariant (under inversion of direction).
|
||||
This indicates that none of the types can represent all the values of the other.
|
||||
|
||||
When the supertype is the same for both `S->T` and `T->S`, it is effectively
|
||||
indicating a type which can represent all the values of the subtype.
|
||||
Consequently, if a conversion `X->Y` is not subranged, but the opposite `(Y->X)` is,
|
||||
so that the supertype is always `Y`, it is said that the direction `X->Y` is [*correctly
|
||||
rounded value preserving], meaning that all such conversions are guaranteed to
|
||||
produce results in range and correctly rounded (even if inexact).
|
||||
For example, all integer to floating conversions are correctly rounded value preserving.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
index.html
|
||||
boost_numericconversion/definitions.html
|
||||
boost_numericconversion/converter___function_object.html
|
||||
boost_numericconversion/type_requirements_and_user_defined_types_support.html
|
||||
boost_numericconversion/bounds___traits_class.html
|
||||
boost_numericconversion/conversion_traits___traits_class.html
|
||||
boost_numericconversion/numeric_converter_policy_classes.html
|
||||
boost_numericconversion/improved_numeric_cast__.html
|
||||
numeric_conversion/history_and_acknowledgments.html
|
||||
numeric_conversion/bibliography.html
|
||||
@@ -0,0 +1,143 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>bounds<> traits class</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="type_requirements_and_user_defined_types_support.html" title="Type Requirements and User-defined-types support">
|
||||
<link rel="next" href="conversion_traits___traits_class.html" title="conversion_traits<> traits class">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="type_requirements_and_user_defined_types_support.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="conversion_traits___traits_class.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_numericconversion.bounds___traits_class"></a><a class="link" href="bounds___traits_class.html" title="bounds<> traits class">bounds<>
|
||||
traits class</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="bounds___traits_class.html#boost_numericconversion.bounds___traits_class.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="bounds___traits_class.html#boost_numericconversion.bounds___traits_class.traits_class_bounds_n_">traits
|
||||
class bounds<N></a></span></dt>
|
||||
<dt><span class="section"><a href="bounds___traits_class.html#boost_numericconversion.bounds___traits_class.examples">Examples</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.bounds___traits_class.introduction"></a><a class="link" href="bounds___traits_class.html#boost_numericconversion.bounds___traits_class.introduction" title="Introduction">Introduction</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
To determine the ranges of numeric types with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span></code>
|
||||
[18.2.1], different syntax have to be used depending on numeric type. Specifically,
|
||||
<code class="computeroutput"><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">min</span><span class="special">()</span></code> for
|
||||
integral types returns the minimum finite value, whereas for floating point
|
||||
types it returns the minimum positive normalized value. The difference in
|
||||
semantics makes client code unnecessarily complex and error prone.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bounds</span><span class="special"><></span></code>
|
||||
provides a consistent interface for retrieving the maximum finite value,
|
||||
the minimum finite value and the minimum positive normalized value (0 for
|
||||
integral types) for numeric types. The selection of implementation is performed
|
||||
at compile time, so there is no runtime overhead.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.bounds___traits_class.traits_class_bounds_n_"></a><a class="link" href="bounds___traits_class.html#boost_numericconversion.bounds___traits_class.traits_class_bounds_n_" title="traits class bounds<N>">traits
|
||||
class bounds<N></a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">N</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">bounds</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">static</span> <span class="identifier">N</span> <span class="identifier">lowest</span> <span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">implementation_defined</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="keyword">static</span> <span class="identifier">N</span> <span class="identifier">highest</span> <span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">implementation_defined</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="keyword">static</span> <span class="identifier">N</span> <span class="identifier">smallest</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">implementation_defined</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="boost_numericconversion.bounds___traits_class.traits_class_bounds_n_.h0"></a>
|
||||
<span class="phrase"><a name="boost_numericconversion.bounds___traits_class.traits_class_bounds_n_.members"></a></span><a class="link" href="bounds___traits_class.html#boost_numericconversion.bounds___traits_class.traits_class_bounds_n_.members">Members</a>
|
||||
</h5>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">lowest</span><span class="special">()</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
Returns the minimum finite value, equivalent to <code class="computeroutput"><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">min</span><span class="special">()</span></code> when
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> is an integral type, and
|
||||
to <code class="computeroutput"><span class="special">-</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span></code> when
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> is a floating point type.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">highest</span><span class="special">()</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
Returns the maximum finite value, equivalent to <code class="computeroutput"><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span></code>.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">smallest</span><span class="special">()</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
Returns the smallest positive normalized value for floating point types with
|
||||
denormalization, or returns 0 for integral types.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.bounds___traits_class.examples"></a><a class="link" href="bounds___traits_class.html#boost_numericconversion.bounds___traits_class.examples" title="Examples">Examples</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The following example demonstrates the use of <code class="computeroutput"><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bounds</span><span class="special"><></span></code> and the equivalent code using <code class="computeroutput"><span class="identifier">numeric_limits</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">numeric</span><span class="special">/</span><span class="identifier">conversion</span><span class="special">/</span><span class="identifier">bounds</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">limits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"numeric::bounds versus numeric_limits example.\n"</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"The maximum value for float:\n"</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bounds</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">highest</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"The minimum value for float:\n"</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bounds</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">lowest</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"The smallest positive value for float:\n"</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bounds</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">smallest</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">min</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="type_requirements_and_user_defined_types_support.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="conversion_traits___traits_class.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,505 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>conversion_traits<> traits class</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="bounds___traits_class.html" title="bounds<> traits class">
|
||||
<link rel="next" href="numeric_converter_policy_classes.html" title="Numeric Converter Policy Classes">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="bounds___traits_class.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="numeric_converter_policy_classes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class"></a><a class="link" href="conversion_traits___traits_class.html" title="conversion_traits<> traits class">conversion_traits<>
|
||||
traits class</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types">Types</a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.examples">Examples</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types" title="Types">Types</a>
|
||||
</h3></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_int_float_mixture_enum">enumeration
|
||||
int_float_mixture_enum</a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_sign_mixture_enum">enumeration
|
||||
sign_mixture_enum</a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_udt_builtin_mixture_enum">enumeration
|
||||
udt_builtin_mixture_enum</a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_int_float_mixture__">template
|
||||
class int_float_mixture<></a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_sign_mixture__">template
|
||||
class sign_mixture<></a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_udt_builtin_mixture__">template
|
||||
class udt_builtin_mixture<></a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_is_subranged__">template
|
||||
class is_subranged<></a></span></dt>
|
||||
<dt><span class="section"><a href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_conversion_traits__">template
|
||||
class conversion_traits<></a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.enumeration_int_float_mixture_enum"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_int_float_mixture_enum" title="enumeration int_float_mixture_enum">enumeration
|
||||
int_float_mixture_enum</a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">enum</span> <span class="identifier">int_float_mixture_enum</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">integral_to_integral</span>
|
||||
<span class="special">,</span><span class="identifier">integral_to_float</span>
|
||||
<span class="special">,</span><span class="identifier">float_to_integral</span>
|
||||
<span class="special">,</span><span class="identifier">float_to_float</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::numeric</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.enumeration_sign_mixture_enum"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_sign_mixture_enum" title="enumeration sign_mixture_enum">enumeration
|
||||
sign_mixture_enum</a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">enum</span> <span class="identifier">sign_mixture_enum</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">unsigned_to_unsigned</span>
|
||||
<span class="special">,</span><span class="identifier">signed_to_signed</span>
|
||||
<span class="special">,</span><span class="identifier">signed_to_unsigned</span>
|
||||
<span class="special">,</span><span class="identifier">unsigned_to_signed</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::numeric</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.enumeration_udt_builtin_mixture_enum"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_udt_builtin_mixture_enum" title="enumeration udt_builtin_mixture_enum">enumeration
|
||||
udt_builtin_mixture_enum</a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">enum</span> <span class="identifier">udt_builtin_mixture_enum</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">builtin_to_builtin</span>
|
||||
<span class="special">,</span><span class="identifier">builtin_to_udt</span>
|
||||
<span class="special">,</span><span class="identifier">udt_to_builtin</span>
|
||||
<span class="special">,</span><span class="identifier">udt_to_udt</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::numeric</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.template_class_int_float_mixture__"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_int_float_mixture__" title="template class int_float_mixture<>">template
|
||||
class int_float_mixture<></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">int_float_mixture</span> <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">int_float_mixture_enum</span><span class="special">,</span> <span class="identifier">impl</span><span class="special">-</span><span class="identifier">def</span><span class="special">-</span><span class="identifier">value</span><span class="special">></span> <span class="special">{}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::numeric</span>
|
||||
</pre>
|
||||
<p>
|
||||
Classifying <code class="computeroutput"><span class="identifier">S</span></code> and <code class="computeroutput"><span class="identifier">T</span></code> as either integral or float, this
|
||||
<a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">MPL's
|
||||
Integral Constant</a> indicates the combination of these attributes.
|
||||
</p>
|
||||
<p>
|
||||
Its <code class="computeroutput"><span class="special">::</span><span class="identifier">value</span></code>
|
||||
is of enumeration type <a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_int_float_mixture_enum" title="enumeration int_float_mixture_enum"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">int_float_mixture_enum</span></code></a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.template_class_sign_mixture__"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_sign_mixture__" title="template class sign_mixture<>">template
|
||||
class sign_mixture<></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">sign_mixture</span> <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">sign_mixture_enum</span><span class="special">,</span> <span class="identifier">impl</span><span class="special">-</span><span class="identifier">def</span><span class="special">-</span><span class="identifier">value</span><span class="special">></span> <span class="special">{}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::numeric</span>
|
||||
</pre>
|
||||
<p>
|
||||
Classifying <code class="computeroutput"><span class="identifier">S</span></code> and <code class="computeroutput"><span class="identifier">T</span></code> as either signed or unsigned, this
|
||||
<a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">MPL's
|
||||
Integral Constant</a> indicates the combination of these attributes.
|
||||
</p>
|
||||
<p>
|
||||
Its <code class="computeroutput"><span class="special">::</span><span class="identifier">value</span></code>
|
||||
is of enumeration type <a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_sign_mixture_enum" title="enumeration sign_mixture_enum"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">sign_mixture_enum</span></code></a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.template_class_udt_builtin_mixture__"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_udt_builtin_mixture__" title="template class udt_builtin_mixture<>">template
|
||||
class udt_builtin_mixture<></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">udt_builtin_mixture</span> <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">udt_builtin__mixture_enum</span><span class="special">,</span> <span class="identifier">impl</span><span class="special">-</span><span class="identifier">def</span><span class="special">-</span><span class="identifier">value</span><span class="special">></span> <span class="special">{}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::numeric</span>
|
||||
</pre>
|
||||
<p>
|
||||
Classifying <code class="computeroutput"><span class="identifier">S</span></code> and <code class="computeroutput"><span class="identifier">T</span></code> as either user-defined or builtin,
|
||||
this <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">MPL's
|
||||
Integral Constant</a> indicates the combination of these attributes.
|
||||
</p>
|
||||
<p>
|
||||
Its <code class="computeroutput"><span class="special">::</span><span class="identifier">value</span></code>
|
||||
is of enumeration type <a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.enumeration_udt_builtin_mixture_enum" title="enumeration udt_builtin_mixture_enum"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">udt_builtin_mixture_enum</span></code></a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.template_class_is_subranged__"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_is_subranged__" title="template class is_subranged<>">template
|
||||
class is_subranged<></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">is_subranged</span> <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">bool_</span><span class="special"><</span><span class="identifier">impl</span><span class="special">-</span><span class="identifier">def</span><span class="special">-</span><span class="identifier">value</span><span class="special">></span> <span class="special">{}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::numeric</span>
|
||||
</pre>
|
||||
<p>
|
||||
Indicates if the range of the target type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is a subset of the range of the source type <code class="computeroutput"><span class="identifier">S</span></code>.
|
||||
That is: if there are some source values which fall out of the Target type's
|
||||
range.
|
||||
</p>
|
||||
<p>
|
||||
It is a boolean <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">MPL's
|
||||
Integral Constant</a> .
|
||||
</p>
|
||||
<p>
|
||||
It does not indicate if a particular conversion is effectively out of range;
|
||||
it indicates that some conversion might be out of range because not all
|
||||
the source values are representable as Target type.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.types.template_class_conversion_traits__"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_conversion_traits__" title="template class conversion_traits<>">template
|
||||
class conversion_traits<></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">conversion_traits</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">int_float_mixture_enum</span> <span class="special">,</span> <span class="special">...></span> <span class="identifier">int_float_mixture</span> <span class="special">;</span>
|
||||
<span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">sign_mixture_enum</span> <span class="special">,</span> <span class="special">...></span> <span class="identifier">sign_mixture</span><span class="special">;</span>
|
||||
<span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">udt_builtin_mixture_enum</span><span class="special">,</span> <span class="special">...></span> <span class="identifier">udt_builtin_mixture</span> <span class="special">;</span>
|
||||
|
||||
<span class="identifier">mpl</span><span class="special">::</span><span class="identifier">bool_</span><span class="special"><...></span> <span class="identifier">subranged</span> <span class="special">;</span>
|
||||
<span class="identifier">mpl</span><span class="special">::</span><span class="identifier">bool_</span><span class="special"><...></span> <span class="identifier">trivial</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">target_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">S</span> <span class="identifier">source_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="special">...</span> <span class="identifier">argument_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="special">...</span> <span class="identifier">result_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="special">...</span> <span class="identifier">supertype</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="special">...</span> <span class="identifier">subtype</span> <span class="special">;</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace numeric, namespace boost</span>
|
||||
</pre>
|
||||
<p>
|
||||
This traits class indicates some properties of a <span class="emphasis"><em>numeric conversion</em></span>
|
||||
direction: from a source type <code class="computeroutput"><span class="identifier">S</span></code>
|
||||
to a target type <code class="computeroutput"><span class="identifier">T</span></code>. It
|
||||
does not indicate the properties of a <span class="emphasis"><em>specific</em></span> conversion,
|
||||
but of the conversion direction. See <a class="link" href="definitions.html#boost_numericconversion.definitions.subranged_conversion_direction__subtype_and_supertype" title="Subranged Conversion Direction, Subtype and Supertype">Definitions</a>
|
||||
for details.
|
||||
</p>
|
||||
<p>
|
||||
The traits class provides the following <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">MPL's
|
||||
Integral Constant</a> \s of enumeration type. They express the combination
|
||||
of certain attributes of the Source and Target types (thus they are call
|
||||
mixture):
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
</th>
|
||||
<th>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>int_float_mixture </strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Same as given by the traits class <a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_int_float_mixture__" title="template class int_float_mixture<>">int_float_mixture</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>sign_mixture </strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Same as given by the traits class <a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_sign_mixture__" title="template class sign_mixture<>">sign_mixture</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>udt_builtin_mixture </strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Same as given by the traits class <a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_udt_builtin_mixture__" title="template class udt_builtin_mixture<>">udt_builtin_mixture</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
The traits class provides the following <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">MPL's
|
||||
Integral Constant</a> \s of boolean type which indicates indirectly
|
||||
the relation between the Source and Target ranges (see <a class="link" href="definitions.html#boost_numericconversion.definitions.range_and_precision" title="Range and Precision">Definitions</a>
|
||||
for details).
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
</th>
|
||||
<th>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
subranged
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Same as given by <a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types.template_class_is_subranged__" title="template class is_subranged<>">is_subranged</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
trivial
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Indicates if both Source and Target, <span class="underline">without
|
||||
cv-qualifications</span>, are the same type.
|
||||
</p>
|
||||
<p>
|
||||
Its <code class="computeroutput"><span class="special">::</span><span class="identifier">value</span></code>
|
||||
is of boolean type.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
The traits class provides the following types. They are the Source and
|
||||
Target types classified and qualified for different purposes.
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
</th>
|
||||
<th>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>target_type</strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The template parameter <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
without cv-qualifications
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>source_type</strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The template parameter <code class="computeroutput"><span class="identifier">S</span></code>
|
||||
without cv-qualifications
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>argument_type</strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
This type is either source_type or <code class="computeroutput"><span class="identifier">source_type</span>
|
||||
<span class="keyword">const</span><span class="special">&</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
It represents the optimal argument type for the <a class="link" href="converter___function_object.html" title="converter<> function object">converter</a>
|
||||
member functions.
|
||||
</p>
|
||||
<p>
|
||||
If S is a built-in type, this is <code class="computeroutput"><span class="identifier">source_type</span></code>,
|
||||
otherwise, this is <code class="computeroutput"><span class="identifier">source_type</span>
|
||||
<span class="keyword">const</span><span class="special">&</span></code>.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>result_type</strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
This type is either target_type or target_type const&
|
||||
</p>
|
||||
<p>
|
||||
It represents the return type of the <a class="link" href="converter___function_object.html" title="converter<> function object">converter</a>
|
||||
member functions.
|
||||
</p>
|
||||
<p>
|
||||
If <code class="computeroutput"><span class="identifier">T</span><span class="special">==</span><span class="identifier">S</span></code>, it is <code class="computeroutput"><span class="identifier">target_type</span>
|
||||
<span class="keyword">const</span><span class="special">&</span></code>,
|
||||
otherwise, it is <code class="computeroutput"><span class="identifier">target_type</span></code>.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>supertype</strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
If the conversion is subranged, it is <code class="computeroutput"><span class="identifier">source_type</span></code>,
|
||||
otherwise, it is <code class="computeroutput"><span class="identifier">target_type</span></code>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>subtype</strong></span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
If the conversion is subranged, it is <code class="computeroutput"><span class="identifier">target_type</span></code>,
|
||||
otherwise, it is <code class="computeroutput"><span class="identifier">source_type</span></code>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.conversion_traits___traits_class.examples"></a><a class="link" href="conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.examples" title="Examples">Examples</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">typeinfo</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">numeric</span><span class="special">/</span><span class="identifier">conversion</span><span class="special">/</span><span class="identifier">conversion_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
|
||||
<span class="comment">// A trivial conversion.</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">conversion_traits</span><span class="special"><</span><span class="keyword">short</span><span class="special">,</span><span class="keyword">short</span><span class="special">></span> <span class="identifier">Short2Short_Traits</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">Short2Short_Traits</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">value</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// A subranged conversion.</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">conversion_traits</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">UInt2Double_Traits</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">UInt2Double_Traits</span><span class="special">::</span><span class="identifier">int_float_mixture</span><span class="special">::</span><span class="identifier">value</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">integral_to_float</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">UInt2Double_Traits</span><span class="special">::</span><span class="identifier">sign_mixture</span><span class="special">::</span><span class="identifier">value</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">unsigned_to_signed</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">!</span><span class="identifier">UInt2Double_Traits</span><span class="special">::</span><span class="identifier">subranged</span><span class="special">::</span><span class="identifier">value</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">UInt2Double_Traits</span><span class="special">::</span><span class="identifier">supertype</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="keyword">double</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">UInt2Double_Traits</span><span class="special">::</span><span class="identifier">subtype</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// A doubly subranged conversion.</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">conversion_traits</span><span class="special"><</span><span class="keyword">short</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">short</span><span class="special">>::</span><span class="identifier">subranged</span><span class="special">::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">conversion_traits</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">short</span><span class="special">,</span> <span class="keyword">short</span><span class="special">>::</span><span class="identifier">subranged</span><span class="special">::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="bounds___traits_class.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="numeric_converter_policy_classes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,462 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>converter<> function object</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="definitions.html" title="Definitions">
|
||||
<link rel="next" href="type_requirements_and_user_defined_types_support.html" title="Type Requirements and User-defined-types support">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="definitions.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="type_requirements_and_user_defined_types_support.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_numericconversion.converter___function_object"></a><a class="link" href="converter___function_object.html" title="converter<> function object">converter<>
|
||||
function object</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="converter___function_object.html#boost_numericconversion.converter___function_object.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="converter___function_object.html#boost_numericconversion.converter___function_object.template_parameters">Template
|
||||
parameters</a></span></dt>
|
||||
<dt><span class="section"><a href="converter___function_object.html#boost_numericconversion.converter___function_object.member_functions">Member
|
||||
functions</a></span></dt>
|
||||
<dt><span class="section"><a href="converter___function_object.html#boost_numericconversion.converter___function_object.range_checking_logic">Range
|
||||
Checking Logic</a></span></dt>
|
||||
<dt><span class="section"><a href="converter___function_object.html#boost_numericconversion.converter___function_object.examples">Examples</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.converter___function_object.synopsis"></a><a class="link" href="converter___function_object.html#boost_numericconversion.converter___function_object.synopsis" title="Synopsis">Synopsis</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span>
|
||||
<span class="keyword">class</span> <span class="identifier">S</span><span class="special">,</span>
|
||||
<span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="special">=</span> <span class="identifier">conversion_traits</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">OverflowHandler</span> <span class="special">=</span> <span class="identifier">def_overflow_handler</span><span class="special">,</span>
|
||||
<span class="keyword">class</span> <span class="identifier">Float2IntRounder</span> <span class="special">=</span> <span class="identifier">Trunc</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">source_type</span> <span class="special">>,</span>
|
||||
<span class="keyword">class</span> <span class="identifier">RawConverter</span> <span class="special">=</span> <span class="identifier">raw_converter</span><span class="special"><</span><span class="identifier">Traits</span><span class="special">>,</span>
|
||||
<span class="keyword">class</span> <span class="identifier">UserRangeChecker</span> <span class="special">=</span> <span class="identifier">UseInternalRangeChecker</span>
|
||||
<span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">converter</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">Traits</span> <span class="identifier">traits</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">source_type</span> <span class="identifier">source_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">argument_type</span> <span class="identifier">argument_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">result_type</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">result_type</span> <span class="identifier">convert</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// Internal member functions:</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">range_check_result</span> <span class="identifier">out_of_range</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">validate_range</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="keyword">static</span> <span class="identifier">result_type</span> <span class="identifier">low_level_convert</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace numeric, boost</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">converter</span><span class="special"><></span></code>
|
||||
is a <a href="http://www.sgi.com/tech/stl/UnaryFunction.html" target="_top">Unary Function
|
||||
Object</a> encapsulating the code to perform a numeric conversion with
|
||||
the direction and properties specified by the Traits template parameter.
|
||||
It can optionally take some <a class="link" href="numeric_converter_policy_classes.html" title="Numeric Converter Policy Classes">policies</a>
|
||||
which can be used to customize its behavior. The <code class="computeroutput"><span class="identifier">Traits</span></code>
|
||||
parameter is not a policy but the parameter that defines the conversion.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.converter___function_object.template_parameters"></a><a class="link" href="converter___function_object.html#boost_numericconversion.converter___function_object.template_parameters" title="Template parameters">Template
|
||||
parameters</a>
|
||||
</h3></div></div></div>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
</th>
|
||||
<th>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The <a class="link" href="definitions.html#boost_numericconversion.definitions.numeric_types" title="Numeric Types">Numeric
|
||||
Type</a> which is the <span class="emphasis"><em>Target</em></span> of the conversion.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">S</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The <a class="link" href="definitions.html#boost_numericconversion.definitions.numeric_types" title="Numeric Types">Numeric
|
||||
Type</a> which is the <span class="emphasis"><em>Source</em></span> of the conversion.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">Traits</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
This must be a conversion traits class with the interface of <a class="link" href="conversion_traits___traits_class.html" title="conversion_traits<> traits class"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">conversion_traits</span></code></a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">OverflowHandler</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>Stateless Policy</strong></span> called to administrate
|
||||
the result of the range checking.
|
||||
</p>
|
||||
<p>
|
||||
It is a <span class="bold"><strong>Function Object</strong></span> which
|
||||
receives the result of <code class="computeroutput"><span class="identifier">out_of_range</span><span class="special">()</span></code> and is called inside the <code class="computeroutput"><span class="identifier">validate_range</span><span class="special">()</span></code>
|
||||
static member function exposed by the converter.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">Float2IntRounder</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>Stateless Policy</strong></span> which specifies
|
||||
the rounding mode used for float to integral conversions.
|
||||
</p>
|
||||
<p>
|
||||
It supplies the <code class="computeroutput"><span class="identifier">nearbyint</span><span class="special">()</span></code> static member function exposed
|
||||
by the converter.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">RawConverter</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<span class="bold"><strong>Stateless Policy</strong></span> which is used
|
||||
to perform the actual conversion.
|
||||
</p>
|
||||
<p>
|
||||
It supplies the <code class="computeroutput"><span class="identifier">low_level_convert</span><span class="special">()</span></code> static member function exposed
|
||||
by the converter.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">UserRangeChecker</span></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<span class="emphasis"><em>Special and Optional</em></span> <span class="bold"><strong>Stateless
|
||||
Policy</strong></span> which can be used to override the internal range
|
||||
checking logic.
|
||||
</p>
|
||||
<p>
|
||||
If given, supplies alternative code for the <code class="computeroutput"><span class="identifier">out_of_range</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">validate_range</span><span class="special">()</span></code> static member functions exposed
|
||||
by the converter.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.converter___function_object.member_functions"></a><a class="link" href="converter___function_object.html#boost_numericconversion.converter___function_object.member_functions" title="Member functions">Member
|
||||
functions</a>
|
||||
</h3></div></div></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">static</span> <span class="identifier">result_type</span>
|
||||
<span class="identifier">converter</span><span class="special"><>::</span><span class="identifier">convert</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span>
|
||||
<span class="special">)</span> <span class="special">;</span> <span class="comment">// throw</span> </code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
This static member function converts an rvalue of type <code class="computeroutput"><span class="identifier">source_type</span></code>
|
||||
to an rvalue of type <code class="computeroutput"><span class="identifier">target_type</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
If the conversion requires it, it performs a range checking before the conversion
|
||||
and passes the result of the check to the overflow handler policy (the default
|
||||
policy throws an exception if out-of-range is detected)
|
||||
</p>
|
||||
<p>
|
||||
The implementation of this function is actually built from the policies and
|
||||
is basically as follows:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">result_type</span> <span class="identifier">converter</span><span class="special"><>::</span><span class="identifier">convert</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">validate_range</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span> <span class="comment">// Implemented by the internal range checking logic</span>
|
||||
<span class="comment">// (which also calls the OverflowHandler policy)</span>
|
||||
<span class="comment">// or externally supplied by the UserRangeChecker policy.</span>
|
||||
|
||||
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">nearbyint</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span> <span class="comment">// Externally supplied by the Float2IntRounder policy.</span>
|
||||
<span class="comment">// NOTE: This is actually called only for float to int conversions.</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="identifier">low_level_convert</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span> <span class="comment">// Externally supplied by the RawConverter policy.</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">converter</span><span class="special"><>::</span><span class="keyword">operator</span><span class="special">()</span> <span class="keyword">const</span></code> just calls <code class="computeroutput"><span class="identifier">convert</span><span class="special">()</span></code>
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">static</span> <span class="identifier">range_check_result</span>
|
||||
<span class="identifier">numeric_converter</span><span class="special"><>::</span><span class="identifier">out_of_range</span> <span class="special">(</span>
|
||||
<span class="identifier">argument_type</span> <span class="identifier">s</span>
|
||||
<span class="special">)</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
This <a class="link" href="converter___function_object.html#numeric_conversion_converter_internal">internal</a>
|
||||
static member function determines if the value <code class="computeroutput"><span class="identifier">s</span></code>
|
||||
can be represented by the target type without overflow.
|
||||
</p>
|
||||
<p>
|
||||
It does not determine if the conversion is <span class="emphasis"><em>exact</em></span>; that
|
||||
is, it does not detect <span class="emphasis"><em>inexact</em></span> conversions, only <span class="emphasis"><em>out-of-range</em></span>
|
||||
conversions (see the <a class="link" href="definitions.html#boost_numericconversion.definitions.exact__correctly_rounded_and_out_of_range_representations" title="Exact, Correctly Rounded and Out-Of-Range Representations">Definitions</a>
|
||||
for further details).
|
||||
</p>
|
||||
<p>
|
||||
The return value is of enum type <a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.enum_range_check_result" title="enum range_check_result"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">range_check_result</span></code></a>
|
||||
</p>
|
||||
<p>
|
||||
The actual code for the range checking logic is optimized for the combined
|
||||
properties of the source and target types. For example, a non-subranged conversion
|
||||
(i.e: <code class="computeroutput"><span class="keyword">int</span></code>-><code class="computeroutput"><span class="keyword">float</span></code>), requires no range checking, so <code class="computeroutput"><span class="identifier">out_of_range</span><span class="special">()</span></code>
|
||||
returns <code class="computeroutput"><span class="identifier">cInRange</span></code> directly.
|
||||
See the following <a class="link" href="converter___function_object.html#boost_numericconversion.converter___function_object.range_checking_logic" title="Range Checking Logic">table</a>
|
||||
for more details.
|
||||
</p>
|
||||
<p>
|
||||
If the user supplied a <a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker" title="Policy UserRangeChecker">UserRangeChecker</a>
|
||||
policy, is this policy which implements this function, so the implementation
|
||||
is user defined, although it is expected to perform the same conceptual check
|
||||
and return the appropriate result.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">static</span> <span class="keyword">void</span>
|
||||
<span class="identifier">numeric_converter</span><span class="special"><>::</span><span class="identifier">validate_range</span> <span class="special">(</span>
|
||||
<span class="identifier">argument_type</span> <span class="identifier">s</span>
|
||||
<span class="special">)</span> <span class="special">;</span> <span class="comment">// no throw</span> </code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
This <a class="link" href="converter___function_object.html#numeric_conversion_converter_internal">internal</a>
|
||||
static member function calls out_of_range(s), and passes the result to the
|
||||
<a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler" title="Policy OverflowHandler">OverflowHandler</a>
|
||||
policy class.
|
||||
</p>
|
||||
<p>
|
||||
For those Target/Source combinations which don't require range checking,
|
||||
this is an empty inline function.
|
||||
</p>
|
||||
<p>
|
||||
If the user supplied a <a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker" title="Policy UserRangeChecker">UserRangeChecker</a>
|
||||
policy, is this policy which implements this function, so the implementation
|
||||
is user defined, although it is expected to perform the same action as the
|
||||
default. In particular, it is expected to pass the result of the check to
|
||||
the overflow handler.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">static</span> <span class="identifier">result_type</span>
|
||||
<span class="identifier">numeric_converter</span><span class="special"><>::</span><span class="identifier">low_level_convert</span> <span class="special">(</span>
|
||||
<span class="identifier">argument_type</span> <span class="identifier">s</span>
|
||||
<span class="special">)</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
This <a class="link" href="converter___function_object.html#numeric_conversion_converter_internal">internal</a>
|
||||
static member function performs the actual conversion.
|
||||
</p>
|
||||
<p>
|
||||
This function is externally supplied by the <a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter" title="Policy RawConverter">RawConverter</a>
|
||||
policy class.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">static</span> <span class="identifier">source_type</span>
|
||||
<span class="identifier">converter</span><span class="special"><>::</span><span class="identifier">nearbyint</span> <span class="special">(</span>
|
||||
<span class="identifier">argument_type</span> <span class="identifier">s</span>
|
||||
<span class="special">)</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
This <a class="link" href="converter___function_object.html#numeric_conversion_converter_internal">internal</a>
|
||||
static member function, which is <span class="underline">only used</span>
|
||||
for <code class="computeroutput"><span class="keyword">float</span></code> to <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
conversions, returns an <span class="emphasis"><em>integer</em></span> value of <span class="emphasis"><em><span class="underline">floating-point type</span></em></span> according to some
|
||||
rounding direction.
|
||||
</p>
|
||||
<p>
|
||||
This function is externally supplied by the <a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder" title="Policy Float2IntRounder">Float2IntRounder</a>
|
||||
policy class which encapsulates the specific rounding mode.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<a name="numeric_conversion_converter_internal"></a><h5>
|
||||
<a name="boost_numericconversion.converter___function_object.member_functions.h0"></a>
|
||||
<span class="phrase"><a name="boost_numericconversion.converter___function_object.member_functions.internal_member_functions"></a></span><a class="link" href="converter___function_object.html#boost_numericconversion.converter___function_object.member_functions.internal_member_functions">Internal
|
||||
Member Functions</a>
|
||||
</h5>
|
||||
<p>
|
||||
These static member functions build the actual conversion code used by <code class="computeroutput"><span class="identifier">convert</span><span class="special">()</span></code>.
|
||||
The user does not have to call these if calling <code class="computeroutput"><span class="identifier">convert</span><span class="special">()</span></code>, since <code class="computeroutput"><span class="identifier">convert</span><span class="special">()</span></code> calls them infernally, but they can be
|
||||
called separately for specific needs.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.converter___function_object.range_checking_logic"></a><a class="link" href="converter___function_object.html#boost_numericconversion.converter___function_object.range_checking_logic" title="Range Checking Logic">Range
|
||||
Checking Logic</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The following table summarizes the internal range checking logic performed
|
||||
for each combination of the properties of Source and Target.
|
||||
</p>
|
||||
<p>
|
||||
LowestT/HighestT denotes the highest and lowest values of the Target type,
|
||||
respectively.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">S</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span></code> is short
|
||||
for <code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">S</span><span class="special">>(</span><span class="identifier">n</span><span class="special">)</span></code> (<code class="computeroutput"><span class="identifier">S</span></code> denotes the Source type).
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">NONE</span></code> indicates that for this
|
||||
case there is no range checking.
|
||||
</p>
|
||||
<pre class="programlisting"><code class="literal">
|
||||
int_to_int |--> sig_to_sig |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
|
|
||||
|--> unsig_to_unsig |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
|
|
||||
|--> sig_to_unsig |--> pos subranged |--> ( s >= S(0) ) && ( s <= S(HighestT) )
|
||||
| |--> not pos subranged |--> ( s >= S(0) )
|
||||
|
|
||||
|--> unsig_to_sig |--> subranged |--> ( s <= S(HighestT) )
|
||||
| |--> not subranged |--> NONE
|
||||
</code>
|
||||
<code class="literal">
|
||||
int_to_float |--> NONE
|
||||
</code>
|
||||
<code class="literal">
|
||||
float_to_int |--> round_to_zero |--> ( s > S(LowestT)-S(1) ) && ( s < S(HighestT)+S(1) )
|
||||
|--> round_to_even_nearest |--> ( s >= S(LowestT)-S(0.5) ) && ( s < S(HighestT)+S(0.5) )
|
||||
|--> round_to_infinity |--> ( s > S(LowestT)-S(1) ) && ( s <= S(HighestT) )
|
||||
|--> round_to_neg_infinity |--> ( s >= S(LowestT) ) && ( s < S(HighestT)+S(1) )
|
||||
</code>
|
||||
<code class="literal">
|
||||
float_to_float |--> subranged |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) )
|
||||
|--> not subranged |--> NONE
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.converter___function_object.examples"></a><a class="link" href="converter___function_object.html#boost_numericconversion.converter___function_object.examples" title="Examples">Examples</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">numeric</span><span class="special">/</span><span class="identifier">conversion</span><span class="special">/</span><span class="identifier">converter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">converter</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">Double2Int</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Double2Int</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="number">2.0</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">x</span> <span class="special">==</span> <span class="number">2</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">Double2Int</span><span class="special">()(</span><span class="number">3.14</span><span class="special">);</span> <span class="comment">// As a function object.</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">y</span> <span class="special">==</span> <span class="number">3</span> <span class="special">)</span> <span class="special">;</span> <span class="comment">// The default rounding is trunc.</span>
|
||||
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">double</span> <span class="identifier">m</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bounds</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">highest</span><span class="special">();</span>
|
||||
<span class="keyword">int</span> <span class="identifier">z</span> <span class="special">=</span> <span class="identifier">Double2Int</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">m</span><span class="special">);</span> <span class="comment">// By default throws positive_overflow()</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">positive_overflow</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="definitions.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="type_requirements_and_user_defined_types_support.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,974 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Definitions</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="next" href="converter___function_object.html" title="converter<> function object">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="converter___function_object.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_numericconversion.definitions"></a><a class="link" href="definitions.html" title="Definitions">Definitions</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.types_and_values">Types
|
||||
and Values</a></span></dt>
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.c___arithmetic_types">C++
|
||||
Arithmetic Types</a></span></dt>
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.numeric_types">Numeric
|
||||
Types</a></span></dt>
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.range_and_precision">Range
|
||||
and Precision</a></span></dt>
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.exact__correctly_rounded_and_out_of_range_representations">Exact,
|
||||
Correctly Rounded and Out-Of-Range Representations</a></span></dt>
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.standard__numeric__conversions">Standard
|
||||
(numeric) Conversions</a></span></dt>
|
||||
<dt><span class="section"><a href="definitions.html#boost_numericconversion.definitions.subranged_conversion_direction__subtype_and_supertype">Subranged
|
||||
Conversion Direction, Subtype and Supertype</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.introduction"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.introduction" title="Introduction">Introduction</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This section provides definitions of terms used in the Numeric Conversion
|
||||
library.
|
||||
</p>
|
||||
<div class="sidebar">
|
||||
<div class="titlepage"></div>
|
||||
<p>
|
||||
<span class="bold"><strong>Notation</strong></span> <span class="underline">underlined
|
||||
text</span> denotes terms defined in the C++ standard.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>bold face</strong></span> denotes terms defined here but
|
||||
not in the standard.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.types_and_values"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.types_and_values" title="Types and Values">Types
|
||||
and Values</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
As defined by the <span class="underline">C++ Object Model</span>
|
||||
(§1.7) the <span class="underline">storage</span> or memory on which
|
||||
a C++ program runs is a contiguous sequence of <span class="underline">bytes</span>
|
||||
where each byte is a contiguous sequence of bits.
|
||||
</p>
|
||||
<p>
|
||||
An <span class="underline">object</span> is a region of storage (§1.8)
|
||||
and has a type (§3.9).
|
||||
</p>
|
||||
<p>
|
||||
A <span class="underline">type</span> is a discrete set of values.
|
||||
</p>
|
||||
<p>
|
||||
An object of type <code class="computeroutput"><span class="identifier">T</span></code> has an
|
||||
<span class="underline">object representation</span> which is the
|
||||
sequence of bytes stored in the object (§3.9/4)
|
||||
</p>
|
||||
<p>
|
||||
An object of type <code class="computeroutput"><span class="identifier">T</span></code> has a
|
||||
<span class="underline">value representation</span> which is the set
|
||||
of bits that determine the <span class="emphasis"><em>value</em></span> of an object of that
|
||||
type (§3.9/4). For <span class="underline">POD</span> types (§3.9/10),
|
||||
this bitset is given by the object representation, but not all the bits in
|
||||
the storage need to participate in the value representation (except for character
|
||||
types): for example, some bits might be used for padding or there may be
|
||||
trap-bits.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<p>
|
||||
The <span class="bold"><strong>typed value</strong></span> that is held by an object
|
||||
is the value which is determined by its value representation.
|
||||
</p>
|
||||
<p>
|
||||
An <span class="bold"><strong>abstract value</strong></span> (untyped) is the conceptual
|
||||
information that is represented in a type (i.e. the number π).
|
||||
</p>
|
||||
<p>
|
||||
The <span class="bold"><strong>intrinsic value</strong></span> of an object is the
|
||||
binary value of the sequence of unsigned characters which form its object
|
||||
representation.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="emphasis"><em>Abstract</em></span> values can be <span class="bold"><strong>represented</strong></span>
|
||||
in a given type.
|
||||
</p>
|
||||
<p>
|
||||
To <span class="bold"><strong>represent</strong></span> an abstract value <code class="computeroutput"><span class="identifier">V</span></code> in a type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is to obtain a typed value <code class="computeroutput"><span class="identifier">v</span></code>
|
||||
which corresponds to the abstract value <code class="computeroutput"><span class="identifier">V</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The operation is denoted using the <code class="computeroutput"><span class="identifier">rep</span><span class="special">()</span></code> operator, as in: <code class="computeroutput"><span class="identifier">v</span><span class="special">=</span><span class="identifier">rep</span><span class="special">(</span><span class="identifier">V</span><span class="special">)</span></code>. <code class="computeroutput"><span class="identifier">v</span></code> is the <span class="bold"><strong>representation</strong></span>
|
||||
of <code class="computeroutput"><span class="identifier">V</span></code> in the type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
For example, the abstract value π can be represented in the type <code class="computeroutput"><span class="keyword">double</span></code> as the <code class="computeroutput"><span class="keyword">double</span>
|
||||
<span class="identifier">value</span> <span class="identifier">M_PI</span></code>
|
||||
and in the type <code class="computeroutput"><span class="keyword">int</span></code> as the
|
||||
<code class="computeroutput"><span class="keyword">int</span> <span class="identifier">value</span>
|
||||
<span class="number">3</span></code>
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<p>
|
||||
Conversely, <span class="emphasis"><em>typed values</em></span> can be <span class="bold"><strong>abstracted</strong></span>.
|
||||
</p>
|
||||
<p>
|
||||
To <span class="bold"><strong>abstract</strong></span> a typed value <code class="computeroutput"><span class="identifier">v</span></code> of type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is to obtain the abstract value <code class="computeroutput"><span class="identifier">V</span></code>
|
||||
whose representation in <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is <code class="computeroutput"><span class="identifier">v</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The operation is denoted using the <code class="computeroutput"><span class="identifier">abt</span><span class="special">()</span></code> operator, as in: <code class="computeroutput"><span class="identifier">V</span><span class="special">=</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">v</span><span class="special">)</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">V</span></code> is the <span class="bold"><strong>abstraction</strong></span>
|
||||
of <code class="computeroutput"><span class="identifier">v</span></code> of type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Abstraction is just an abstract operation (you can't do it); but it is defined
|
||||
nevertheless because it will be used to give the definitions in the rest
|
||||
of this document.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.c___arithmetic_types"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.c___arithmetic_types" title="C++ Arithmetic Types">C++
|
||||
Arithmetic Types</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The C++ language defines <span class="underline">fundamental types</span>
|
||||
(§3.9.1). The following subsets of the fundamental types are intended to
|
||||
represent <span class="emphasis"><em>numbers</em></span>:
|
||||
</p>
|
||||
<div class="variablelist">
|
||||
<p class="title"><b></b></p>
|
||||
<dl class="variablelist">
|
||||
<dt><span class="term"><span class="underline">signed integer types</span> (§3.9.1/2):</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="special">{</span><span class="keyword">signed</span>
|
||||
<span class="keyword">char</span><span class="special">,</span>
|
||||
<span class="keyword">signed</span> <span class="keyword">short</span>
|
||||
<span class="keyword">int</span><span class="special">,</span>
|
||||
<span class="keyword">signed</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">signed</span> <span class="keyword">long</span> <span class="keyword">int</span><span class="special">}</span></code> Can be used to represent general integer
|
||||
numbers (both negative and positive).
|
||||
</p></dd>
|
||||
<dt><span class="term"><span class="underline">unsigned integer types</span> (§3.9.1/3):</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="special">{</span><span class="keyword">unsigned</span>
|
||||
<span class="keyword">char</span><span class="special">,</span>
|
||||
<span class="keyword">unsigned</span> <span class="keyword">short</span>
|
||||
<span class="keyword">int</span><span class="special">,</span>
|
||||
<span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">unsigned</span>
|
||||
<span class="keyword">long</span> <span class="keyword">int</span><span class="special">}</span></code> Can be used to represent positive
|
||||
integer numbers with modulo-arithmetic.
|
||||
</p></dd>
|
||||
<dt><span class="term"><span class="underline">floating-point types</span> (§3.9.1/8):</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="special">{</span><span class="keyword">float</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">long</span> <span class="keyword">double</span><span class="special">}</span></code>
|
||||
Can be used to represent real numbers.
|
||||
</p></dd>
|
||||
<dt><span class="term"><span class="underline">integral or integer types</span> (§3.9.1/7):</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="special">{{</span><span class="keyword">signed</span>
|
||||
<span class="identifier">integers</span><span class="special">},{</span><span class="keyword">unsigned</span> <span class="identifier">integers</span><span class="special">},</span> <span class="keyword">bool</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">and</span> <span class="keyword">wchar_t</span><span class="special">}</span></code>
|
||||
</p></dd>
|
||||
<dt><span class="term"><span class="underline">arithmetic types</span> (§3.9.1/8):</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="special">{{</span><span class="identifier">integer</span>
|
||||
<span class="identifier">types</span><span class="special">},{</span><span class="identifier">floating</span> <span class="identifier">types</span><span class="special">}}</span></code>
|
||||
</p></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<p>
|
||||
The integer types are required to have a <span class="emphasis"><em>binary</em></span> value
|
||||
representation.
|
||||
</p>
|
||||
<p>
|
||||
Additionally, the signed/unsigned integer types of the same base type (<code class="computeroutput"><span class="keyword">short</span></code>, <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
or <code class="computeroutput"><span class="keyword">long</span></code>) are required to have
|
||||
the same value representation, that is:
|
||||
</p>
|
||||
<pre class="programlisting"> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">-</span><span class="number">3</span> <span class="special">;</span> <span class="comment">// suppose value representation is: 10011 (sign bit + 4 magnitude bits)</span>
|
||||
<span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">u</span> <span class="special">=</span> <span class="identifier">i</span> <span class="special">;</span> <span class="comment">// u is required to have the same 10011 as its value representation.</span>
|
||||
</pre>
|
||||
<p>
|
||||
In other words, the integer types signed/unsigned X use the same value representation
|
||||
but a different <span class="emphasis"><em>interpretation</em></span> of it; that is, their
|
||||
<span class="emphasis"><em>typed values</em></span> might differ.
|
||||
</p>
|
||||
<p>
|
||||
Another consequence of this is that the range for signed X is always a smaller
|
||||
subset of the range of unsigned X, as required by §3.9.1/3.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top">
|
||||
<p>
|
||||
Always remember that unsigned types, unlike signed types, have modulo-arithmetic;
|
||||
that is, they do not overflow. This means that:
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>-</strong></span> Always be extra careful when mixing
|
||||
signed/unsigned types
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>-</strong></span> Use unsigned types only when you need
|
||||
modulo arithmetic or very very large numbers. Don't use unsigned types
|
||||
just because you intend to deal with positive values only (you can do this
|
||||
with signed types as well).
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.numeric_types"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.numeric_types" title="Numeric Types">Numeric
|
||||
Types</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This section introduces the following definitions intended to integrate arithmetic
|
||||
types with user-defined types which behave like numbers. Some definitions
|
||||
are purposely broad in order to include a vast variety of user-defined number
|
||||
types.
|
||||
</p>
|
||||
<p>
|
||||
Within this library, the term <span class="emphasis"><em>number</em></span> refers to an abstract
|
||||
numeric value.
|
||||
</p>
|
||||
<p>
|
||||
A type is <span class="bold"><strong>numeric</strong></span> if:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
It is an arithmetic type, or,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
It is a user-defined type which
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
|
||||
<li class="listitem">
|
||||
Represents numeric abstract values (i.e. numbers).
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Can be converted (either implicitly or explicitly) to/from at least
|
||||
one arithmetic type.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Has <a class="link" href="definitions.html#boost_numericconversion.definitions.range_and_precision" title="Range and Precision">range</a>
|
||||
(possibly unbounded) and <a class="link" href="definitions.html#boost_numericconversion.definitions.range_and_precision" title="Range and Precision">precision</a>
|
||||
(possibly dynamic or unlimited).
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Provides an specialization of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
A numeric type is <span class="bold"><strong>signed</strong></span> if the abstract
|
||||
values it represent include negative numbers.
|
||||
</p>
|
||||
<p>
|
||||
A numeric type is <span class="bold"><strong>unsigned</strong></span> if the abstract
|
||||
values it represent exclude negative numbers.
|
||||
</p>
|
||||
<p>
|
||||
A numeric type is <span class="bold"><strong>modulo</strong></span> if it has modulo-arithmetic
|
||||
(does not overflow).
|
||||
</p>
|
||||
<p>
|
||||
A numeric type is <span class="bold"><strong>integer</strong></span> if the abstract
|
||||
values it represent are whole numbers.
|
||||
</p>
|
||||
<p>
|
||||
A numeric type is <span class="bold"><strong>floating</strong></span> if the abstract
|
||||
values it represent are real numbers.
|
||||
</p>
|
||||
<p>
|
||||
An <span class="bold"><strong>arithmetic value</strong></span> is the typed value of
|
||||
an arithmetic type
|
||||
</p>
|
||||
<p>
|
||||
A <span class="bold"><strong>numeric value</strong></span> is the typed value of a
|
||||
numeric type
|
||||
</p>
|
||||
<p>
|
||||
These definitions simply generalize the standard notions of arithmetic types
|
||||
and values by introducing a superset called <span class="underline">numeric</span>.
|
||||
All arithmetic types and values are numeric types and values, but not vice
|
||||
versa, since user-defined numeric types are not arithmetic types.
|
||||
</p>
|
||||
<p>
|
||||
The following examples clarify the differences between arithmetic and numeric
|
||||
types (and values):
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">// A numeric type which is not an arithmetic type (is user-defined)</span>
|
||||
<span class="comment">// and which is intended to represent integer numbers (i.e., an 'integer' numeric type)</span>
|
||||
<span class="keyword">class</span> <span class="identifier">MyInt</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">MyInt</span> <span class="special">(</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">to_builtin</span><span class="special">();</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
<span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
|
||||
<span class="keyword">template</span><span class="special"><></span> <span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">MyInt</span><span class="special">></span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="comment">// A 'floating' numeric type (double) which is also an arithmetic type (built-in),</span>
|
||||
<span class="comment">// with a float numeric value.</span>
|
||||
<span class="keyword">double</span> <span class="identifier">pi</span> <span class="special">=</span> <span class="identifier">M_PI</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// A 'floating' numeric type with a whole numeric value.</span>
|
||||
<span class="comment">// NOTE: numeric values are typed valued, hence, they are, for instance,</span>
|
||||
<span class="comment">// integer or floating, despite the value itself being whole or including</span>
|
||||
<span class="comment">// a fractional part.</span>
|
||||
<span class="keyword">double</span> <span class="identifier">two</span> <span class="special">=</span> <span class="number">2.0</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// An integer numeric type with an integer numeric value.</span>
|
||||
<span class="identifier">MyInt</span> <span class="identifier">i</span><span class="special">(</span><span class="number">1234</span><span class="special">);</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.range_and_precision"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.range_and_precision" title="Range and Precision">Range
|
||||
and Precision</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Given a number set <code class="computeroutput"><span class="identifier">N</span></code>, some
|
||||
of its elements are representable in a numeric type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The set of representable values of type <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
or numeric set of <code class="computeroutput"><span class="identifier">T</span></code>, is a
|
||||
set of numeric values whose elements are the representation of some subset
|
||||
of <code class="computeroutput"><span class="identifier">N</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
For example, the interval of <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
values <code class="computeroutput"><span class="special">[</span><span class="identifier">INT_MIN</span><span class="special">,</span><span class="identifier">INT_MAX</span><span class="special">]</span></code> is the set of representable values of type
|
||||
<code class="computeroutput"><span class="keyword">int</span></code>, i.e. the <code class="computeroutput"><span class="keyword">int</span></code> numeric set, and corresponds to the representation
|
||||
of the elements of the interval of abstract values <code class="computeroutput"><span class="special">[</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">INT_MIN</span><span class="special">),</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">INT_MAX</span><span class="special">)]</span></code>
|
||||
from the integer numbers.
|
||||
</p>
|
||||
<p>
|
||||
Similarly, the interval of <code class="computeroutput"><span class="keyword">double</span></code>
|
||||
values <code class="computeroutput"><span class="special">[-</span><span class="identifier">DBL_MAX</span><span class="special">,</span><span class="identifier">DBL_MAX</span><span class="special">]</span></code> is the <code class="computeroutput"><span class="keyword">double</span></code>
|
||||
numeric set, which corresponds to the subset of the real numbers from <code class="computeroutput"><span class="identifier">abt</span><span class="special">(-</span><span class="identifier">DBL_MAX</span><span class="special">)</span></code> to <code class="computeroutput"><span class="identifier">abt</span><span class="special">(</span><span class="identifier">DBL_MAX</span><span class="special">)</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<p>
|
||||
Let <span class="bold"><strong><code class="computeroutput"><span class="identifier">next</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code></strong></span>
|
||||
denote the lowest numeric value greater than x.
|
||||
</p>
|
||||
<p>
|
||||
Let <span class="bold"><strong><code class="computeroutput"><span class="identifier">prev</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code></strong></span>
|
||||
denote the highest numeric value lower then x.
|
||||
</p>
|
||||
<p>
|
||||
Let <span class="bold"><strong><code class="computeroutput"><span class="identifier">v</span><span class="special">=</span><span class="identifier">prev</span><span class="special">(</span><span class="identifier">next</span><span class="special">(</span><span class="identifier">V</span><span class="special">))</span></code></strong></span> and <span class="bold"><strong><code class="computeroutput"><span class="identifier">v</span><span class="special">=</span><span class="identifier">next</span><span class="special">(</span><span class="identifier">prev</span><span class="special">(</span><span class="identifier">V</span><span class="special">))</span></code></strong></span>
|
||||
be identities that relate a numeric typed value <code class="computeroutput"><span class="identifier">v</span></code>
|
||||
with a number <code class="computeroutput"><span class="identifier">V</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
An ordered pair of numeric values <code class="computeroutput"><span class="identifier">x</span></code>,<code class="computeroutput"><span class="identifier">y</span></code> s.t. <code class="computeroutput"><span class="identifier">x</span><span class="special"><</span><span class="identifier">y</span></code> are
|
||||
<span class="bold"><strong>consecutive</strong></span> iff <code class="computeroutput"><span class="identifier">next</span><span class="special">(</span><span class="identifier">x</span><span class="special">)==</span><span class="identifier">y</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The abstract distance between consecutive numeric values is usually referred
|
||||
to as a <span class="underline">Unit in the Last Place</span>, or
|
||||
<span class="bold"><strong>ulp</strong></span> for short. A ulp is a quantity whose
|
||||
abstract magnitude is relative to the numeric values it corresponds to: If
|
||||
the numeric set is not evenly distributed, that is, if the abstract distance
|
||||
between consecutive numeric values varies along the set -as is the case with
|
||||
the floating-point types-, the magnitude of 1ulp after the numeric value
|
||||
<code class="computeroutput"><span class="identifier">x</span></code> might be (usually is) different
|
||||
from the magnitude of a 1ulp after the numeric value y for <code class="computeroutput"><span class="identifier">x</span><span class="special">!=</span><span class="identifier">y</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Since numbers are inherently ordered, a <span class="bold"><strong>numeric set</strong></span>
|
||||
of type <code class="computeroutput"><span class="identifier">T</span></code> is an ordered sequence
|
||||
of numeric values (of type <code class="computeroutput"><span class="identifier">T</span></code>)
|
||||
of the form:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">REP</span><span class="special">(</span><span class="identifier">T</span><span class="special">)={</span><span class="identifier">l</span><span class="special">,</span><span class="identifier">next</span><span class="special">(</span><span class="identifier">l</span><span class="special">),</span><span class="identifier">next</span><span class="special">(</span><span class="identifier">next</span><span class="special">(</span><span class="identifier">l</span><span class="special">)),...,</span><span class="identifier">prev</span><span class="special">(</span><span class="identifier">prev</span><span class="special">(</span><span class="identifier">h</span><span class="special">)),</span><span class="identifier">prev</span><span class="special">(</span><span class="identifier">h</span><span class="special">),</span><span class="identifier">h</span><span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
where <code class="computeroutput"><span class="identifier">l</span></code> and <code class="computeroutput"><span class="identifier">h</span></code> are respectively the lowest and highest
|
||||
values of type <code class="computeroutput"><span class="identifier">T</span></code>, called
|
||||
the boundary values of type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<p>
|
||||
A numeric set is discrete. It has a <span class="bold"><strong>size</strong></span>
|
||||
which is the number of numeric values in the set, a <span class="bold"><strong>width</strong></span>
|
||||
which is the abstract difference between the highest and lowest boundary
|
||||
values: <code class="computeroutput"><span class="special">[</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)-</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">l</span><span class="special">)]</span></code>, and a <span class="bold"><strong>density</strong></span>
|
||||
which is the relation between its size and width: <code class="computeroutput"><span class="identifier">density</span><span class="special">=</span><span class="identifier">size</span><span class="special">/</span><span class="identifier">width</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The integer types have density 1, which means that there are no unrepresentable
|
||||
integer numbers between <code class="computeroutput"><span class="identifier">abt</span><span class="special">(</span><span class="identifier">l</span><span class="special">)</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code> (i.e.
|
||||
there are no gaps). On the other hand, floating types have density much smaller
|
||||
than 1, which means that there are real numbers unrepresented between consecutive
|
||||
floating values (i.e. there are gaps).
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<p>
|
||||
The interval of <span class="underline">abstract values</span> <code class="computeroutput"><span class="special">[</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">l</span><span class="special">),</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)]</span></code>
|
||||
is the range of the type <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
denoted <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
A range is a set of abstract values and not a set of numeric values. In other
|
||||
documents, such as the C++ standard, the word <code class="computeroutput"><span class="identifier">range</span></code>
|
||||
is <span class="emphasis"><em>sometimes</em></span> used as synonym for <code class="computeroutput"><span class="identifier">numeric</span>
|
||||
<span class="identifier">set</span></code>, that is, as the ordered sequence
|
||||
of numeric values from <code class="computeroutput"><span class="identifier">l</span></code>
|
||||
to <code class="computeroutput"><span class="identifier">h</span></code>. In this document, however,
|
||||
a range is an abstract interval which subtends the numeric set.
|
||||
</p>
|
||||
<p>
|
||||
For example, the sequence <code class="computeroutput"><span class="special">[-</span><span class="identifier">DBL_MAX</span><span class="special">,</span><span class="identifier">DBL_MAX</span><span class="special">]</span></code>
|
||||
is the numeric set of the type <code class="computeroutput"><span class="keyword">double</span></code>,
|
||||
and the real interval <code class="computeroutput"><span class="special">[</span><span class="identifier">abt</span><span class="special">(-</span><span class="identifier">DBL_MAX</span><span class="special">),</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">DBL_MAX</span><span class="special">)]</span></code>
|
||||
is its range.
|
||||
</p>
|
||||
<p>
|
||||
Notice, for instance, that the range of a floating-point type is <span class="emphasis"><em>continuous</em></span>
|
||||
unlike its numeric set.
|
||||
</p>
|
||||
<p>
|
||||
This definition was chosen because:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>(a)</strong></span> The discrete set of numeric values
|
||||
is already given by the numeric set.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>(b)</strong></span> Abstract intervals are easier to
|
||||
compare and overlap since only boundary values need to be considered.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
This definition allows for a concise definition of <code class="computeroutput"><span class="identifier">subranged</span></code>
|
||||
as given in the last section.
|
||||
</p>
|
||||
<p>
|
||||
The width of a numeric set, as defined, is exactly equivalent to the width
|
||||
of a range.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<p>
|
||||
The <span class="bold"><strong>precision</strong></span> of a type is given by the
|
||||
width or density of the numeric set.
|
||||
</p>
|
||||
<p>
|
||||
For integer types, which have density 1, the precision is conceptually equivalent
|
||||
to the range and is determined by the number of bits used in the value representation:
|
||||
The higher the number of bits the bigger the size of the numeric set, the
|
||||
wider the range, and the higher the precision.
|
||||
</p>
|
||||
<p>
|
||||
For floating types, which have density <<1, the precision is given
|
||||
not by the width of the range but by the density. In a typical implementation,
|
||||
the range is determined by the number of bits used in the exponent, and the
|
||||
precision by the number of bits used in the mantissa (giving the maximum
|
||||
number of significant digits that can be exactly represented). The higher
|
||||
the number of exponent bits the wider the range, while the higher the number
|
||||
of mantissa bits, the higher the precision.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.exact__correctly_rounded_and_out_of_range_representations"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.exact__correctly_rounded_and_out_of_range_representations" title="Exact, Correctly Rounded and Out-Of-Range Representations">Exact,
|
||||
Correctly Rounded and Out-Of-Range Representations</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Given an abstract value <code class="computeroutput"><span class="identifier">V</span></code>
|
||||
and a type <code class="computeroutput"><span class="identifier">T</span></code> with its corresponding
|
||||
range <code class="computeroutput"><span class="special">[</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">l</span><span class="special">),</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)]</span></code>:
|
||||
</p>
|
||||
<p>
|
||||
If <code class="computeroutput"><span class="identifier">V</span> <span class="special"><</span>
|
||||
<span class="identifier">abt</span><span class="special">(</span><span class="identifier">l</span><span class="special">)</span></code> or
|
||||
<code class="computeroutput"><span class="identifier">V</span> <span class="special">></span>
|
||||
<span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>, <code class="computeroutput"><span class="identifier">V</span></code> is <span class="bold"><strong>not representable</strong></span>
|
||||
(cannot be represented) in the type <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
or, equivalently, it's representation in the type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is <span class="bold"><strong>out of range</strong></span>, or <span class="bold"><strong>overflows</strong></span>.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">V</span> <span class="special"><</span>
|
||||
<span class="identifier">abt</span><span class="special">(</span><span class="identifier">l</span><span class="special">)</span></code>,
|
||||
the <span class="bold"><strong>overflow is negative</strong></span>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">V</span> <span class="special">></span>
|
||||
<span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>,
|
||||
the <span class="bold"><strong>overflow is positive</strong></span>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
If <code class="computeroutput"><span class="identifier">V</span> <span class="special">>=</span>
|
||||
<span class="identifier">abt</span><span class="special">(</span><span class="identifier">l</span><span class="special">)</span></code> and
|
||||
<code class="computeroutput"><span class="identifier">V</span> <span class="special"><=</span>
|
||||
<span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>, <code class="computeroutput"><span class="identifier">V</span></code> is <span class="bold"><strong>representable</strong></span>
|
||||
(can be represented) in the type <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
or, equivalently, its representation in the type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is <span class="bold"><strong>in range</strong></span>, or <span class="bold"><strong>does
|
||||
not overflow</strong></span>.
|
||||
</p>
|
||||
<p>
|
||||
Notice that a numeric type, such as a C++ unsigned type, can define that
|
||||
any <code class="computeroutput"><span class="identifier">V</span></code> does not overflow by
|
||||
always representing not <code class="computeroutput"><span class="identifier">V</span></code>
|
||||
itself but the abstract value <code class="computeroutput"><span class="identifier">U</span>
|
||||
<span class="special">=</span> <span class="special">[</span> <span class="identifier">V</span> <span class="special">%</span> <span class="special">(</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)+</span><span class="number">1</span><span class="special">)</span>
|
||||
<span class="special">]</span></code>, which is always in range.
|
||||
</p>
|
||||
<p>
|
||||
Given an abstract value <code class="computeroutput"><span class="identifier">V</span></code>
|
||||
represented in the type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
as <code class="computeroutput"><span class="identifier">v</span></code>, the <span class="bold"><strong>roundoff</strong></span>
|
||||
error of the representation is the abstract difference: <code class="computeroutput"><span class="special">(</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">v</span><span class="special">)-</span><span class="identifier">V</span><span class="special">)</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Notice that a representation is an <span class="emphasis"><em>operation</em></span>, hence,
|
||||
the roundoff error corresponds to the representation operation and not to
|
||||
the numeric value itself (i.e. numeric values do not have any error themselves)
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
If the roundoff is 0, the representation is <span class="bold"><strong>exact</strong></span>,
|
||||
and <code class="computeroutput"><span class="identifier">V</span></code> is exactly representable
|
||||
in the type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the roundoff is not 0, the representation is <span class="bold"><strong>inexact</strong></span>,
|
||||
and <code class="computeroutput"><span class="identifier">V</span></code> is inexactly representable
|
||||
in the type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
If a representation <code class="computeroutput"><span class="identifier">v</span></code> in
|
||||
a type <code class="computeroutput"><span class="identifier">T</span></code> -either exact or
|
||||
inexact-, is any of the adjacents of <code class="computeroutput"><span class="identifier">V</span></code>
|
||||
in that type, that is, if <code class="computeroutput"><span class="identifier">v</span><span class="special">==</span><span class="identifier">prev</span></code>
|
||||
or <code class="computeroutput"><span class="identifier">v</span><span class="special">==</span><span class="identifier">next</span></code>, the representation is faithfully
|
||||
rounded. If the choice between <code class="computeroutput"><span class="identifier">prev</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">next</span></code> matches a given
|
||||
<span class="bold"><strong>rounding direction</strong></span>, it is <span class="bold"><strong>correctly
|
||||
rounded</strong></span>.
|
||||
</p>
|
||||
<p>
|
||||
All exact representations are correctly rounded, but not all inexact representations
|
||||
are. In particular, C++ requires numeric conversions (described below) and
|
||||
the result of arithmetic operations (not covered by this document) to be
|
||||
correctly rounded, but batch operations propagate roundoff, thus final results
|
||||
are usually incorrectly rounded, that is, the numeric value <code class="computeroutput"><span class="identifier">r</span></code> which is the computed result is neither
|
||||
of the adjacents of the abstract value <code class="computeroutput"><span class="identifier">R</span></code>
|
||||
which is the theoretical result.
|
||||
</p>
|
||||
<p>
|
||||
Because a correctly rounded representation is always one of adjacents of
|
||||
the abstract value being represented, the roundoff is guaranteed to be at
|
||||
most 1ulp.
|
||||
</p>
|
||||
<p>
|
||||
The following examples summarize the given definitions. Consider:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
A numeric type <code class="computeroutput"><span class="identifier">Int</span></code> representing
|
||||
integer numbers with a <span class="emphasis"><em>numeric set</em></span>: <code class="computeroutput"><span class="special">{-</span><span class="number">2</span><span class="special">,-</span><span class="number">1</span><span class="special">,</span><span class="number">0</span><span class="special">,</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">}</span></code> and
|
||||
<span class="emphasis"><em>range</em></span>: <code class="computeroutput"><span class="special">[-</span><span class="number">2</span><span class="special">,</span><span class="number">2</span><span class="special">]</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A numeric type <code class="computeroutput"><span class="identifier">Cardinal</span></code>
|
||||
representing integer numbers with a <span class="emphasis"><em>numeric set</em></span>:
|
||||
<code class="computeroutput"><span class="special">{</span><span class="number">0</span><span class="special">,</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">,</span><span class="number">6</span><span class="special">,</span><span class="number">7</span><span class="special">,</span><span class="number">8</span><span class="special">,</span><span class="number">9</span><span class="special">}</span></code> and <span class="emphasis"><em>range</em></span>: <code class="computeroutput"><span class="special">[</span><span class="number">0</span><span class="special">,</span><span class="number">9</span><span class="special">]</span></code> (no
|
||||
modulo-arithmetic here)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A numeric type <code class="computeroutput"><span class="identifier">Real</span></code> representing
|
||||
real numbers with a <span class="emphasis"><em>numeric set</em></span>: <code class="computeroutput"><span class="special">{-</span><span class="number">2.0</span><span class="special">,-</span><span class="number">1.5</span><span class="special">,-</span><span class="number">1.0</span><span class="special">,-</span><span class="number">0.5</span><span class="special">,-</span><span class="number">0.0</span><span class="special">,+</span><span class="number">0.0</span><span class="special">,+</span><span class="number">0.5</span><span class="special">,+</span><span class="number">1.0</span><span class="special">,+</span><span class="number">1.5</span><span class="special">,+</span><span class="number">2.0</span><span class="special">}</span></code> and
|
||||
<span class="emphasis"><em>range</em></span>: <code class="computeroutput"><span class="special">[-</span><span class="number">2.0</span><span class="special">,+</span><span class="number">2.0</span><span class="special">]</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A numeric type <code class="computeroutput"><span class="identifier">Whole</span></code>
|
||||
representing real numbers with a <span class="emphasis"><em>numeric set</em></span>: <code class="computeroutput"><span class="special">{-</span><span class="number">2.0</span><span class="special">,-</span><span class="number">1.0</span><span class="special">,</span><span class="number">0.0</span><span class="special">,+</span><span class="number">1.0</span><span class="special">,+</span><span class="number">2.0</span><span class="special">}</span></code> and
|
||||
<span class="emphasis"><em>range</em></span>: <code class="computeroutput"><span class="special">[-</span><span class="number">2.0</span><span class="special">,+</span><span class="number">2.0</span><span class="special">]</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
First, notice that the types <code class="computeroutput"><span class="identifier">Real</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">Whole</span></code> both represent
|
||||
real numbers, have the same range, but different precision.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
The integer number <code class="computeroutput"><span class="number">1</span></code> (an
|
||||
abstract value) can be exactly represented in any of these types.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The integer number <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
|
||||
can be exactly represented in <code class="computeroutput"><span class="identifier">Int</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">Real</span></code> and <code class="computeroutput"><span class="identifier">Whole</span></code>, but cannot be represented in
|
||||
<code class="computeroutput"><span class="identifier">Cardinal</span></code>, yielding negative
|
||||
overflow.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The real number <code class="computeroutput"><span class="number">1.5</span></code> can be
|
||||
exactly represented in <code class="computeroutput"><span class="identifier">Real</span></code>,
|
||||
and inexactly represented in the other types.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="number">1.5</span></code> is represented as
|
||||
either <code class="computeroutput"><span class="number">1</span></code> or <code class="computeroutput"><span class="number">2</span></code> in any of the types (except <code class="computeroutput"><span class="identifier">Real</span></code>), the representation is correctly
|
||||
rounded.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="number">0.5</span></code> is represented as
|
||||
<code class="computeroutput"><span class="special">+</span><span class="number">1.5</span></code>
|
||||
in the type <code class="computeroutput"><span class="identifier">Real</span></code>, it
|
||||
is incorrectly rounded.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="special">(-</span><span class="number">2.0</span><span class="special">,-</span><span class="number">1.5</span><span class="special">)</span></code>
|
||||
are the <code class="computeroutput"><span class="identifier">Real</span></code> adjacents
|
||||
of any real number in the interval <code class="computeroutput"><span class="special">[-</span><span class="number">2.0</span><span class="special">,-</span><span class="number">1.5</span><span class="special">]</span></code>, yet there are no <code class="computeroutput"><span class="identifier">Real</span></code>
|
||||
adjacents for <code class="computeroutput"><span class="identifier">x</span> <span class="special"><</span>
|
||||
<span class="special">-</span><span class="number">2.0</span></code>,
|
||||
nor for <code class="computeroutput"><span class="identifier">x</span> <span class="special">></span>
|
||||
<span class="special">+</span><span class="number">2.0</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.standard__numeric__conversions"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.standard__numeric__conversions" title="Standard (numeric) Conversions">Standard
|
||||
(numeric) Conversions</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The C++ language defines <span class="underline">Standard Conversions</span>
|
||||
(§4) some of which are conversions between arithmetic types.
|
||||
</p>
|
||||
<p>
|
||||
These are <span class="underline">Integral promotions</span> (§4.5),
|
||||
<span class="underline">Integral conversions</span> (§4.7), <span class="underline">Floating point promotions</span> (§4.6), <span class="underline">Floating point conversions</span> (§4.8) and <span class="underline">Floating-integral conversions</span> (§4.9).
|
||||
</p>
|
||||
<p>
|
||||
In the sequel, integral and floating point promotions are called <span class="bold"><strong>arithmetic promotions</strong></span>, and these plus integral, floating-point
|
||||
and floating-integral conversions are called <span class="bold"><strong>arithmetic
|
||||
conversions</strong></span> (i.e, promotions are conversions).
|
||||
</p>
|
||||
<p>
|
||||
Promotions, both Integral and Floating point, are <span class="emphasis"><em>value-preserving</em></span>,
|
||||
which means that the typed value is not changed with the conversion.
|
||||
</p>
|
||||
<p>
|
||||
In the sequel, consider a source typed value <code class="computeroutput"><span class="identifier">s</span></code>
|
||||
of type <code class="computeroutput"><span class="identifier">S</span></code>, the source abstract
|
||||
value <code class="computeroutput"><span class="identifier">N</span><span class="special">=</span><span class="identifier">abt</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span></code>, a destination type <code class="computeroutput"><span class="identifier">T</span></code>;
|
||||
and whenever possible, a result typed value <code class="computeroutput"><span class="identifier">t</span></code>
|
||||
of type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Integer to integer conversions are always defined:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">T</span></code> is unsigned, the
|
||||
abstract value which is effectively represented is not <code class="computeroutput"><span class="identifier">N</span></code> but <code class="computeroutput"><span class="identifier">M</span><span class="special">=[</span> <span class="identifier">N</span> <span class="special">%</span> <span class="special">(</span> <span class="identifier">abt</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">+</span> <span class="number">1</span>
|
||||
<span class="special">)</span> <span class="special">]</span></code>,
|
||||
where <code class="computeroutput"><span class="identifier">h</span></code> is the highest
|
||||
unsigned typed value of type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">T</span></code> is signed and <code class="computeroutput"><span class="identifier">N</span></code> is not directly representable, the
|
||||
result <code class="computeroutput"><span class="identifier">t</span></code> is <span class="underline">implementation-defined</span>, which means that
|
||||
the C++ implementation is required to produce a value <code class="computeroutput"><span class="identifier">t</span></code>
|
||||
even if it is totally unrelated to <code class="computeroutput"><span class="identifier">s</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Floating to Floating conversions are defined only if <code class="computeroutput"><span class="identifier">N</span></code>
|
||||
is representable; if it is not, the conversion has <span class="underline">undefined
|
||||
behavior</span>.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">N</span></code> is exactly representable,
|
||||
<code class="computeroutput"><span class="identifier">t</span></code> is required to be the
|
||||
exact representation.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">N</span></code> is inexactly representable,
|
||||
<code class="computeroutput"><span class="identifier">t</span></code> is required to be one
|
||||
of the two adjacents, with an implementation-defined choice of rounding
|
||||
direction; that is, the conversion is required to be correctly rounded.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Floating to Integer conversions represent not <code class="computeroutput"><span class="identifier">N</span></code>
|
||||
but <code class="computeroutput"><span class="identifier">M</span><span class="special">=</span><span class="identifier">trunc</span><span class="special">(</span><span class="identifier">N</span><span class="special">)</span></code>, were
|
||||
<code class="computeroutput"><span class="identifier">trunc</span><span class="special">()</span></code>
|
||||
is to truncate: i.e. to remove the fractional part, if any.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">M</span></code> is not representable
|
||||
in <code class="computeroutput"><span class="identifier">T</span></code>, the conversion
|
||||
has <span class="underline">undefined behavior</span> (unless
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="keyword">bool</span></code>,
|
||||
see §4.12).
|
||||
</li></ul></div>
|
||||
<p>
|
||||
Integer to Floating conversions are always defined.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">N</span></code> is exactly representable,
|
||||
<code class="computeroutput"><span class="identifier">t</span></code> is required to be the
|
||||
exact representation.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If <code class="computeroutput"><span class="identifier">N</span></code> is inexactly representable,
|
||||
<code class="computeroutput"><span class="identifier">t</span></code> is required to be one
|
||||
of the two adjacents, with an implementation-defined choice of rounding
|
||||
direction; that is, the conversion is required to be correctly rounded.
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.definitions.subranged_conversion_direction__subtype_and_supertype"></a><a class="link" href="definitions.html#boost_numericconversion.definitions.subranged_conversion_direction__subtype_and_supertype" title="Subranged Conversion Direction, Subtype and Supertype">Subranged
|
||||
Conversion Direction, Subtype and Supertype</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Given a source type <code class="computeroutput"><span class="identifier">S</span></code> and
|
||||
a destination type <code class="computeroutput"><span class="identifier">T</span></code>, there
|
||||
is a <span class="bold"><strong>conversion direction</strong></span> denoted: <code class="computeroutput"><span class="identifier">S</span><span class="special">-></span><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
For any two ranges the following <span class="emphasis"><em>range relation</em></span> can
|
||||
be defined: A range <code class="computeroutput"><span class="identifier">X</span></code> can
|
||||
be <span class="emphasis"><em>entirely contained</em></span> in a range <code class="computeroutput"><span class="identifier">Y</span></code>,
|
||||
in which case it is said that <code class="computeroutput"><span class="identifier">X</span></code>
|
||||
is enclosed by <code class="computeroutput"><span class="identifier">Y</span></code>.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="bold"><strong>Formally:</strong></span> <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span></code>
|
||||
is enclosed by <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code> iif
|
||||
<code class="computeroutput"><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span>
|
||||
<span class="identifier">intersection</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">))</span>
|
||||
<span class="special">==</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span></code>.
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
If the source type range, <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span></code>,
|
||||
is not enclosed in the target type range, <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>;
|
||||
that is, if <code class="computeroutput"><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span>
|
||||
<span class="special">&</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">))</span>
|
||||
<span class="special">!=</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span></code>,
|
||||
the conversion direction is said to be <span class="bold"><strong>subranged</strong></span>,
|
||||
which means that <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span></code> is not
|
||||
entirely contained in <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code> and
|
||||
therefore there is some portion of the source range which falls outside the
|
||||
target range. In other words, if a conversion direction <code class="computeroutput"><span class="identifier">S</span><span class="special">-></span><span class="identifier">T</span></code>
|
||||
is subranged, there are values in <code class="computeroutput"><span class="identifier">S</span></code>
|
||||
which cannot be represented in <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
because they are out of range. Notice that for <code class="computeroutput"><span class="identifier">S</span><span class="special">-></span><span class="identifier">T</span></code>,
|
||||
the adjective subranged applies to <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Examples:
|
||||
</p>
|
||||
<p>
|
||||
Given the following numeric types all representing real numbers:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">X</span></code> with numeric set <code class="computeroutput"><span class="special">{-</span><span class="number">2.0</span><span class="special">,-</span><span class="number">1.0</span><span class="special">,</span><span class="number">0.0</span><span class="special">,+</span><span class="number">1.0</span><span class="special">,+</span><span class="number">2.0</span><span class="special">}</span></code> and
|
||||
range <code class="computeroutput"><span class="special">[-</span><span class="number">2.0</span><span class="special">,+</span><span class="number">2.0</span><span class="special">]</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">Y</span></code> with numeric set <code class="computeroutput"><span class="special">{-</span><span class="number">2.0</span><span class="special">,-</span><span class="number">1.5</span><span class="special">,-</span><span class="number">1.0</span><span class="special">,-</span><span class="number">0.5</span><span class="special">,</span><span class="number">0.0</span><span class="special">,+</span><span class="number">0.5</span><span class="special">,+</span><span class="number">1.0</span><span class="special">,+</span><span class="number">1.5</span><span class="special">,+</span><span class="number">2.0</span><span class="special">}</span></code> and range <code class="computeroutput"><span class="special">[-</span><span class="number">2.0</span><span class="special">,+</span><span class="number">2.0</span><span class="special">]</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">Z</span></code> with numeric set <code class="computeroutput"><span class="special">{-</span><span class="number">1.0</span><span class="special">,</span><span class="number">0.0</span><span class="special">,+</span><span class="number">1.0</span><span class="special">}</span></code> and range <code class="computeroutput"><span class="special">[-</span><span class="number">1.0</span><span class="special">,+</span><span class="number">1.0</span><span class="special">]</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
For:
|
||||
</p>
|
||||
<div class="variablelist">
|
||||
<p class="title"><b></b></p>
|
||||
<dl class="variablelist">
|
||||
<dt><span class="term">(a) X->Y:</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">X</span><span class="special">)</span> <span class="special">&</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">Y</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">X</span><span class="special">)</span></code>,
|
||||
then <code class="computeroutput"><span class="identifier">X</span><span class="special">-></span><span class="identifier">Y</span></code> is not subranged. Thus, all values
|
||||
of type <code class="computeroutput"><span class="identifier">X</span></code> are representable
|
||||
in the type <code class="computeroutput"><span class="identifier">Y</span></code>.
|
||||
</p></dd>
|
||||
<dt><span class="term">(b) Y->X:</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">Y</span><span class="special">)</span> <span class="special">&</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">X</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">Y</span><span class="special">)</span></code>,
|
||||
then <code class="computeroutput"><span class="identifier">Y</span><span class="special">-></span><span class="identifier">X</span></code> is not subranged. Thus, all values
|
||||
of type <code class="computeroutput"><span class="identifier">Y</span></code> are representable
|
||||
in the type <code class="computeroutput"><span class="identifier">X</span></code>, but
|
||||
in this case, some values are <span class="emphasis"><em>inexactly</em></span> representable
|
||||
(all the halves). (note: it is to permit this case that a range is
|
||||
an interval of abstract values and not an interval of typed values)
|
||||
</p></dd>
|
||||
<dt><span class="term">(b) X->Z:</span></dt>
|
||||
<dd><p>
|
||||
<code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">X</span><span class="special">)</span> <span class="special">&</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">Z</span><span class="special">)</span> <span class="special">!=</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">X</span><span class="special">)</span></code>,
|
||||
then <code class="computeroutput"><span class="identifier">X</span><span class="special">-></span><span class="identifier">Z</span></code> is subranged. Thus, some values
|
||||
of type <code class="computeroutput"><span class="identifier">X</span></code> are not representable
|
||||
in the type <code class="computeroutput"><span class="identifier">Z</span></code>, they
|
||||
fall out of range <code class="computeroutput"><span class="special">(-</span><span class="number">2.0</span>
|
||||
<span class="keyword">and</span> <span class="special">+</span><span class="number">2.0</span><span class="special">)</span></code>.
|
||||
</p></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<p>
|
||||
It is possible that <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span></code> is not
|
||||
enclosed by <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>, while
|
||||
neither is <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code> enclosed
|
||||
by <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">S</span><span class="special">)</span></code>; for
|
||||
example, <code class="computeroutput"><span class="identifier">UNSIG</span><span class="special">=[</span><span class="number">0</span><span class="special">,</span><span class="number">255</span><span class="special">]</span></code> is not enclosed by <code class="computeroutput"><span class="identifier">SIG</span><span class="special">=[-</span><span class="number">128</span><span class="special">,</span><span class="number">127</span><span class="special">]</span></code>; neither
|
||||
is <code class="computeroutput"><span class="identifier">SIG</span></code> enclosed by <code class="computeroutput"><span class="identifier">UNSIG</span></code>. This implies that is possible that
|
||||
a conversion direction is subranged both ways. This occurs when a mixture
|
||||
of signed/unsigned types are involved and indicates that in both directions
|
||||
there are values which can fall out of range.
|
||||
</p>
|
||||
<p>
|
||||
Given the range relation (subranged or not) of a conversion direction <code class="computeroutput"><span class="identifier">S</span><span class="special">-></span><span class="identifier">T</span></code>, it is possible to classify <code class="computeroutput"><span class="identifier">S</span></code> and <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
as <span class="bold"><strong>supertype</strong></span> and <span class="bold"><strong>subtype</strong></span>:
|
||||
If the conversion is subranged, which means that <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
cannot represent all possible values of type <code class="computeroutput"><span class="identifier">S</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">S</span></code> is the supertype and <code class="computeroutput"><span class="identifier">T</span></code> the subtype; otherwise, <code class="computeroutput"><span class="identifier">T</span></code> is the supertype and <code class="computeroutput"><span class="identifier">S</span></code>
|
||||
the subtype.
|
||||
</p>
|
||||
<p>
|
||||
For example:
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="keyword">float</span><span class="special">)=[-</span><span class="identifier">FLT_MAX</span><span class="special">,</span><span class="identifier">FLT_MAX</span><span class="special">]</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="keyword">double</span><span class="special">)=[-</span><span class="identifier">DBL_MAX</span><span class="special">,</span><span class="identifier">DBL_MAX</span><span class="special">]</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
If <code class="computeroutput"><span class="identifier">FLT_MAX</span> <span class="special"><</span>
|
||||
<span class="identifier">DBL_MAX</span></code>:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">double</span><span class="special">-></span><span class="keyword">float</span></code> is subranged and <code class="computeroutput"><span class="identifier">supertype</span><span class="special">=</span><span class="keyword">double</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">subtype</span><span class="special">=</span><span class="keyword">float</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">float</span><span class="special">-></span><span class="keyword">double</span></code> is not subranged and <code class="computeroutput"><span class="identifier">supertype</span><span class="special">=</span><span class="keyword">double</span></code>, <code class="computeroutput"><span class="identifier">subtype</span><span class="special">=</span><span class="keyword">float</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Notice that while <code class="computeroutput"><span class="keyword">double</span><span class="special">-></span><span class="keyword">float</span></code> is subranged, <code class="computeroutput"><span class="keyword">float</span><span class="special">-></span><span class="keyword">double</span></code>
|
||||
is not, which yields the same supertype,subtype for both directions.
|
||||
</p>
|
||||
<p>
|
||||
Now consider:
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="keyword">int</span><span class="special">)=[</span><span class="identifier">INT_MIN</span><span class="special">,</span><span class="identifier">INT_MAX</span><span class="special">]</span></code> and <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)=[</span><span class="number">0</span><span class="special">,</span><span class="identifier">UINT_MAX</span><span class="special">]</span></code>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
A C++ implementation is required to have <code class="computeroutput"><span class="identifier">UINT_MAX</span>
|
||||
<span class="special">></span> <span class="identifier">INT_MAX</span></code>
|
||||
(§3.9/3), so:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
'int->unsigned' is subranged (negative values fall out of range) and
|
||||
<code class="computeroutput"><span class="identifier">supertype</span><span class="special">=</span><span class="keyword">int</span></code>, <code class="computeroutput"><span class="identifier">subtype</span><span class="special">=</span><span class="keyword">unsigned</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
'unsigned->int' is <span class="emphasis"><em>also</em></span> subranged (high positive
|
||||
values fall out of range) and <code class="computeroutput"><span class="identifier">supertype</span><span class="special">=</span><span class="keyword">unsigned</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">subtype</span><span class="special">=</span><span class="keyword">int</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
In this case, the conversion is subranged in both directions and the supertype,subtype
|
||||
pairs are not invariant (under inversion of direction). This indicates that
|
||||
none of the types can represent all the values of the other.
|
||||
</p>
|
||||
<p>
|
||||
When the supertype is the same for both <code class="computeroutput"><span class="identifier">S</span><span class="special">-></span><span class="identifier">T</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">T</span><span class="special">-></span><span class="identifier">S</span></code>, it is effectively indicating a type
|
||||
which can represent all the values of the subtype. Consequently, if a conversion
|
||||
<code class="computeroutput"><span class="identifier">X</span><span class="special">-></span><span class="identifier">Y</span></code> is not subranged, but the opposite <code class="computeroutput"><span class="special">(</span><span class="identifier">Y</span><span class="special">-></span><span class="identifier">X</span><span class="special">)</span></code> is,
|
||||
so that the supertype is always <code class="computeroutput"><span class="identifier">Y</span></code>,
|
||||
it is said that the direction <code class="computeroutput"><span class="identifier">X</span><span class="special">-></span><span class="identifier">Y</span></code>
|
||||
is <span class="bold"><strong>correctly rounded value preserving</strong></span>, meaning
|
||||
that all such conversions are guaranteed to produce results in range and
|
||||
correctly rounded (even if inexact). For example, all integer to floating
|
||||
conversions are correctly rounded value preserving.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="converter___function_object.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,212 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Improved numeric_cast<></title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="numeric_converter_policy_classes.html" title="Numeric Converter Policy Classes">
|
||||
<link rel="next" href="../numeric_conversion/history_and_acknowledgments.html" title="History and Acknowledgments">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="numeric_converter_policy_classes.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../numeric_conversion/history_and_acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_numericconversion.improved_numeric_cast__"></a><a class="link" href="improved_numeric_cast__.html" title="Improved numeric_cast<>">Improved
|
||||
numeric_cast<></a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast">numeric_cast</a></span></dt>
|
||||
<dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast_traits">numeric_cast_traits</a></span></dt>
|
||||
<dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.examples">Examples</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.improved_numeric_cast__.introduction"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.introduction" title="Introduction">Introduction</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The lack of preservation of range makes conversions between numeric types
|
||||
error prone. This is true for both implicit conversions and explicit conversions
|
||||
(through <code class="computeroutput"><span class="keyword">static_cast</span></code>). <a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast" title="numeric_cast"><code class="computeroutput"><span class="identifier">numeric_cast</span></code></a> detects loss of range
|
||||
when a numeric type is converted, and throws an exception if the range cannot
|
||||
be preserved.
|
||||
</p>
|
||||
<p>
|
||||
There are several situations where conversions are unsafe:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
Conversions from an integral type with a wider range than the target
|
||||
integral type.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Conversions from unsigned to signed (and vice versa) integral types.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Conversions from floating point types to integral types.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The C++ Standard does not specify the behavior when a numeric type is assigned
|
||||
a value that cannot be represented by the type, except for unsigned integral
|
||||
types [3.9.1.4], which must obey the laws of arithmetic modulo 2n (this implies
|
||||
that the result will be reduced modulo the number that is one greater than
|
||||
the largest value that can be represented). The fact that the behavior for
|
||||
overflow is undefined for all conversions (except the aforementioned unsigned
|
||||
to unsigned) makes any code that may produce positive or negative overflows
|
||||
exposed to portability issues.
|
||||
</p>
|
||||
<p>
|
||||
By default <code class="computeroutput"><span class="identifier">numeric_cast</span></code> adheres
|
||||
to the rules for implicit conversions mandated by the C++ Standard, such
|
||||
as truncating floating point types when converting to integral types. The
|
||||
implementation must guarantee that for a conversion to a type that can hold
|
||||
all possible values of the source type, there will be no runtime overhead.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.improved_numeric_cast__.numeric_cast"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast" title="numeric_cast">numeric_cast</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Target</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Source</span><span class="special">></span> <span class="keyword">inline</span>
|
||||
<span class="identifier">Target</span> <span class="identifier">numeric_cast</span><span class="special">(</span> <span class="identifier">Source</span> <span class="identifier">arg</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">conversion_traits</span><span class="special"><</span><span class="identifier">Target</span><span class="special">,</span> <span class="identifier">Source</span><span class="special">></span> <span class="identifier">conv_traits</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">numeric_cast_traits</span><span class="special"><</span><span class="identifier">Target</span><span class="special">,</span> <span class="identifier">Source</span><span class="special">></span> <span class="identifier">cast_traits</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">converter</span>
|
||||
<span class="special"><</span>
|
||||
<span class="identifier">Target</span><span class="special">,</span>
|
||||
<span class="identifier">Source</span><span class="special">,</span>
|
||||
<span class="identifier">conv_traits</span><span class="special">,</span>
|
||||
<span class="keyword">typename</span> <span class="identifier">cast_traits</span><span class="special">::</span><span class="identifier">overflow_policy</span><span class="special">,</span>
|
||||
<span class="keyword">typename</span> <span class="identifier">cast_traits</span><span class="special">::</span><span class="identifier">rounding_policy</span><span class="special">,</span>
|
||||
<span class="identifier">raw_converter</span><span class="special"><</span><span class="identifier">conv_traits</span><span class="special">>,</span>
|
||||
<span class="keyword">typename</span> <span class="identifier">cast_traits</span><span class="special">::</span><span class="identifier">range_checking_policy</span>
|
||||
<span class="special">></span> <span class="identifier">converter</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">converter</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">arg</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">numeric_cast</span></code> returns the
|
||||
result of converting a value of type Source to a value of type Target. If
|
||||
out-of-range is detected, an overflow policy is executed whose default behavior
|
||||
is to throw an an exception (see <a class="link" href="numeric_converter_policy_classes.html#numeric_conversion_bad_numeric_cast">bad_numeric_cast</a>,
|
||||
<a class="link" href="numeric_converter_policy_classes.html#numeric_conversion_negative_overflow">negative_overflow</a>
|
||||
and <a class="link" href="numeric_converter_policy_classes.html#numeric_conversion_possitive_overflow">positive_overflow</a>
|
||||
).
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.improved_numeric_cast__.numeric_cast_traits"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast_traits" title="numeric_cast_traits">numeric_cast_traits</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Target</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Source</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">EnableIf</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">numeric_cast_traits</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">def_overflow_handler</span> <span class="identifier">overflow_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">UseInternalRangeChecker</span> <span class="identifier">range_checking_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">Trunc</span><span class="special"><</span><span class="identifier">Source</span><span class="special">></span> <span class="identifier">rounding_policy</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
The behavior of <code class="computeroutput"><span class="identifier">numeric_cast</span></code>
|
||||
may be tailored for custom numeric types through the specialization of <code class="computeroutput"><span class="identifier">numeric_cast_traits</span></code>. (see <a class="link" href="type_requirements_and_user_defined_types_support.html" title="Type Requirements and User-defined-types support">User
|
||||
Defined Types</a> for details. )
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.improved_numeric_cast__.examples"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.examples" title="Examples">Examples</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The following example performs some typical conversions between numeric types:
|
||||
</p>
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
include <boost/numeric/conversion/cast.hpp>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
include <iostream>
|
||||
</li>
|
||||
</ol></div>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric_cast</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bad_numeric_cast</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">positive_overflow</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">negative_overflow</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">42</span><span class="special">;</span>
|
||||
<span class="keyword">short</span> <span class="identifier">s</span><span class="special">=</span><span class="identifier">numeric_cast</span><span class="special"><</span><span class="keyword">short</span><span class="special">>(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// This conversion succeeds (is in range)</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">negative_overflow</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">positive_overflow</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">float</span> <span class="identifier">f</span><span class="special">=-</span><span class="number">42.1234</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">// This will cause a boost::numeric::negative_overflow exception to be thrown</span>
|
||||
<span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="identifier">numeric_cast</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">>(</span><span class="identifier">f</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">bad_numeric_cast</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">double</span> <span class="identifier">d</span><span class="special">=</span> <span class="identifier">f</span> <span class="special">+</span> <span class="identifier">numeric_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">123</span><span class="special">);</span> <span class="comment">// int -> double</span>
|
||||
|
||||
<span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="identifier">l</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">long</span><span class="special">>::</span><span class="identifier">max</span><span class="special">();</span>
|
||||
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// This will cause a boost::numeric::positive_overflow exception to be thrown</span>
|
||||
<span class="comment">// NOTE: *operations* on unsigned integral types cannot cause overflow</span>
|
||||
<span class="comment">// but *conversions* to a signed type ARE range checked by numeric_cast.</span>
|
||||
|
||||
<span class="keyword">unsigned</span> <span class="keyword">char</span> <span class="identifier">c</span><span class="special">=</span><span class="identifier">numeric_cast</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">>(</span><span class="identifier">l</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">positive_overflow</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="numeric_converter_policy_classes.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../numeric_conversion/history_and_acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,395 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Numeric Converter Policy Classes</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="conversion_traits___traits_class.html" title="conversion_traits<> traits class">
|
||||
<link rel="next" href="improved_numeric_cast__.html" title="Improved numeric_cast<>">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="conversion_traits___traits_class.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="improved_numeric_cast__.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_numericconversion.numeric_converter_policy_classes"></a><a class="link" href="numeric_converter_policy_classes.html" title="Numeric Converter Policy Classes">Numeric
|
||||
Converter Policy Classes</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.enum_range_check_result">enum
|
||||
range_check_result</a></span></dt>
|
||||
<dt><span class="section"><a href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler">Policy
|
||||
OverflowHandler</a></span></dt>
|
||||
<dt><span class="section"><a href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder">Policy
|
||||
Float2IntRounder</a></span></dt>
|
||||
<dt><span class="section"><a href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter">Policy
|
||||
RawConverter</a></span></dt>
|
||||
<dt><span class="section"><a href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker">Policy
|
||||
UserRangeChecker</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.numeric_converter_policy_classes.enum_range_check_result"></a><a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.enum_range_check_result" title="enum range_check_result">enum
|
||||
range_check_result</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">enum</span> <span class="identifier">range_check_result</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">cInRange</span> <span class="special">,</span>
|
||||
<span class="identifier">cNegOverflow</span> <span class="special">,</span>
|
||||
<span class="identifier">cPosOverflow</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Defines the values returned by <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">converter</span><span class="special"><>::</span><span class="identifier">out_of_range</span><span class="special">()</span></code>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler"></a><a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler" title="Policy OverflowHandler">Policy
|
||||
OverflowHandler</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This <span class="emphasis"><em>stateless</em></span> non-template policy class must be a
|
||||
<span class="emphasis"><em>function object</em></span> and is called to administrate the result
|
||||
of the range checking. It can throw an exception if overflow has been detected
|
||||
by the range checking as indicated by its argument. If it throws, is is recommended
|
||||
that it be <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_cast</span></code> or derived.
|
||||
</p>
|
||||
<p>
|
||||
It must have the following interface (it does not has to be a template class):
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">YourOverflowHandlerPolicy</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">range_check_result</span> <span class="special">)</span> <span class="special">;</span> <span class="comment">// throw bad_cast or derived</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
It is called with the result of the converter's <code class="computeroutput"><span class="identifier">out_of_range</span><span class="special">()</span></code> inside <code class="computeroutput"><span class="identifier">validate_range</span><span class="special">()</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
These are the two overflow handler classes provided by the library:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">def_overflow_handler</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span> <span class="identifier">range_check_result</span> <span class="identifier">r</span> <span class="special">)</span> <span class="comment">// throw bad_numeric_conversion derived</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">r</span> <span class="special">==</span> <span class="identifier">cNegOverflow</span> <span class="special">)</span>
|
||||
<span class="keyword">throw</span> <span class="identifier">negative_overflow</span><span class="special">()</span> <span class="special">;</span>
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">r</span> <span class="special">==</span> <span class="identifier">cPosOverflow</span> <span class="special">)</span>
|
||||
<span class="keyword">throw</span> <span class="identifier">positive_overflow</span><span class="special">()</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">silent_overflow_handler</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span> <span class="identifier">range_check_result</span> <span class="special">)</span> <span class="comment">// no-throw</span>
|
||||
<span class="special">{}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
And these are the Exception Classes thrown by the default overflow handler
|
||||
<a class="link" href="numeric_converter_policy_classes.html#numeric_conversion_policy_overflow_handler_important_note">(see
|
||||
IMPORTANT note)</a>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<a name="numeric_conversion_bad_numeric_cast"></a>
|
||||
<span class="keyword">class</span> <span class="identifier">bad_numeric_cast</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_cast</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">what</span><span class="special">()</span> <span class="keyword">const</span> <span class="comment">// throw()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="string">"bad numeric conversion: overflow"</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="special">};</span>
|
||||
|
||||
<a name="numeric_conversion_negative_overflow"></a>
|
||||
<span class="keyword">class</span> <span class="identifier">negative_overflow</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">bad_numeric_cast</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">what</span><span class="special">()</span> <span class="keyword">const</span> <span class="comment">// throw()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="string">"bad numeric conversion: negative overflow"</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<a name="numeric_conversion_possitive_overflow"></a>
|
||||
<span class="keyword">class</span> <span class="identifier">positive_overflow</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">bad_numeric_cast</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">what</span><span class="special">()</span> <span class="keyword">const</span> <span class="comment">// throw()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="string">"bad numeric conversion: positive overflow"</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span>
|
||||
</pre>
|
||||
<a name="numeric_conversion_policy_overflow_handler_important_note"></a><div class="important"><table border="0" summary="Important">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
|
||||
<th align="left">Important</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
<span class="bold"><strong>RELEASE NOTE for 1.33</strong></span> Previous to boost
|
||||
version 1.33, the exception class <code class="computeroutput"><span class="identifier">bad_numeric_cast</span></code>
|
||||
was named <code class="computeroutput"><span class="identifier">bad_numeric_conversion</span></code>.
|
||||
However, in 1.33, the old function <code class="computeroutput"><span class="identifier">numeric_cast</span><span class="special"><></span></code> from <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">cast</span><span class="special">.</span><span class="identifier">hpp</span></code>
|
||||
was completly replaced by the new <code class="computeroutput"><span class="identifier">numeric_cast</span><span class="special"><></span></code> in <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">numeric</span><span class="special">/</span><span class="identifier">conversion</span><span class="special">/</span><span class="identifier">cast</span><span class="special">.</span><span class="identifier">hpp</span></code>
|
||||
(and <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">cast</span><span class="special">.</span><span class="identifier">hpp</span></code> is including <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">numeric</span><span class="special">/</span><span class="identifier">conversion</span><span class="special">/</span><span class="identifier">cast</span><span class="special">.</span><span class="identifier">hpp</span></code>
|
||||
now). That old function which existed in boost for quite some time used
|
||||
the <code class="computeroutput"><span class="identifier">bad_numeric_cast</span></code> as
|
||||
its exception type so I decided to avoid backward compatibility problems
|
||||
by adopting it (guessing that the user base for the old code is wider than
|
||||
for the new code).
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder"></a><a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder" title="Policy Float2IntRounder">Policy
|
||||
Float2IntRounder</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This <span class="emphasis"><em>stateless</em></span> template policy class specifies the rounding
|
||||
mode used for <span class="underline">float to integral</span> conversions.
|
||||
It supplies the <code class="computeroutput"><span class="identifier">nearbyint</span><span class="special">()</span></code> static member function exposed by the converter,
|
||||
which means that it <span class="underline">publicly inherits from this
|
||||
policy</span>.
|
||||
</p>
|
||||
<p>
|
||||
The policy must have the following interface:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">YourFloat2IntRounderPolicy</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">S</span> <span class="identifier">source_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="special">{</span><span class="identifier">S</span> <span class="keyword">or</span> <span class="identifier">S</span> <span class="keyword">const</span><span class="special">&}</span> <span class="identifier">argument_type</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">float_round_style</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">round_</span><span class="special">...></span> <span class="identifier">round_style</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
These are the rounder classes provided by the library (only the specific
|
||||
parts are shown, see the general policy form above)
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
These classes are not intended to be general purpose rounding functions
|
||||
but specific policies for <code class="computeroutput"><span class="identifier">converter</span><span class="special"><></span></code>. This is why they are not function
|
||||
objects.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Trunc</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span> <span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ceil</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="identifier">s</span> <span class="special">>=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">S</span><span class="special">>(</span><span class="number">0</span><span class="special">)</span> <span class="special">?</span> <span class="identifier">floor</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">ceil</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">float_round_style</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">round_toward_zero</span><span class="special">></span> <span class="identifier">round_style</span> <span class="special">;</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">RoundEven</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">impl</span><span class="special">-</span><span class="identifier">defined</span><span class="special">-</span><span class="identifier">value</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">float_round_style</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">round_to_nearest</span><span class="special">></span> <span class="identifier">round_style</span> <span class="special">;</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Ceil</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ceil</span> <span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">ceil</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">float_round_style</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">round_toward_infinity</span><span class="special">></span> <span class="identifier">round_style</span> <span class="special">;</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Floor</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span> <span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="identifier">floor</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">float_round_style</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">round_toward_neg_infinity</span><span class="special">></span> <span class="identifier">round_style</span> <span class="special">;</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace numeric, namespace boost</span>
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder.h0"></a>
|
||||
<span class="phrase"><a name="boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder.math_functions_used_by_the_rounder_policies"></a></span><a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder.math_functions_used_by_the_rounder_policies">Math
|
||||
Functions used by the rounder policies</a>
|
||||
</h5>
|
||||
<p>
|
||||
The rounder policies supplied by this header use math functions <code class="computeroutput"><span class="identifier">floor</span><span class="special">()</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">ceil</span><span class="special">()</span></code>.
|
||||
The standard versions of these functions are introduced in context by a using
|
||||
directive, so in normal conditions, the standard functions will be used.
|
||||
</p>
|
||||
<p>
|
||||
However, if there are other visible corresponding overloads an ambiguity
|
||||
could arise. In this case, the user can supply her own rounder policy which
|
||||
could, for instance, use a fully qualified call.
|
||||
</p>
|
||||
<p>
|
||||
This technique allows the default rounder policies to be used directly with
|
||||
user defined types. The user only requires that suitable overloads of <code class="computeroutput"><span class="identifier">floor</span><span class="special">()</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">ceil</span><span class="special">()</span></code>
|
||||
be visible. See also <a class="link" href="type_requirements_and_user_defined_types_support.html" title="Type Requirements and User-defined-types support">User
|
||||
Defined Numeric Types</a> support.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter"></a><a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter" title="Policy RawConverter">Policy
|
||||
RawConverter</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This <span class="emphasis"><em>stateless</em></span> template policy class is used to perform
|
||||
the actual conversion from Source to Target. It supplies the <code class="computeroutput"><span class="identifier">low_level_convert</span><span class="special">()</span></code>
|
||||
static member function exposed by the converter, which means that it publicly
|
||||
inherits from this policy.
|
||||
</p>
|
||||
<p>
|
||||
The policy must have the following interface:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">YourRawConverterPolicy</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">result_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">argument_type</span> <span class="identifier">argument_type</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">result_type</span> <span class="identifier">low_level_convert</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special"><</span><span class="identifier">impl</span> <span class="identifier">defined</span><span class="special">></span> <span class="special">;</span> <span class="special">}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
This policy is mostly provided as a hook for user defined types which don't
|
||||
support <code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><></span></code>
|
||||
conversions to some types
|
||||
</p>
|
||||
<p>
|
||||
This is the only raw converter policy class provided by the library:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">raw_numeric_converter</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">result_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">argument_type</span> <span class="identifier">argument_type</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">result_type</span> <span class="identifier">low_level_convert</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">result_type</span><span class="special">>(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker"></a><a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker" title="Policy UserRangeChecker">Policy
|
||||
UserRangeChecker</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This <span class="emphasis"><em>stateless</em></span> template policy class is used <span class="underline">only if supplied</span> to <span class="bold"><strong>override</strong></span>
|
||||
the internal range checking logic.
|
||||
</p>
|
||||
<p>
|
||||
It supplies the <code class="computeroutput"><span class="identifier">validate_range</span><span class="special">()</span></code> static member function exposed by the converter,
|
||||
which means that it publicly inherits from this policy.
|
||||
</p>
|
||||
<p>
|
||||
The policy must have the following interface:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">YourRangeCheckerPolicy</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">argument_type</span> <span class="identifier">argument_type</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// Determines if the value 's' fits in the range of the Target type.</span>
|
||||
<span class="keyword">static</span> <span class="identifier">range_check_result</span> <span class="identifier">out_of_range</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// Checks whether the value 's' is out_of_range()</span>
|
||||
<span class="comment">// and passes the result of the check to the OverflowHandler policy.</span>
|
||||
<span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">validate_range</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">OverflowHandler</span><span class="special">()(</span> <span class="identifier">out_of_range</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
This policy is <span class="bold"><strong>only</strong></span> provided as a hook for
|
||||
user defined types which require range checking (which is disabled by default
|
||||
when a UDT is involved). The library provides a class: <code class="computeroutput"><span class="identifier">UseInternalRangeChecker</span><span class="special">{}</span></code>; which is a <span class="emphasis"><em>fake</em></span>
|
||||
<code class="computeroutput"><span class="identifier">RangeChecker</span></code> policy used
|
||||
to signal the converter to use its internal range checking implementation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="conversion_traits___traits_class.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="improved_numeric_cast__.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+554
@@ -0,0 +1,554 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Type Requirements and User-defined-types support</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="converter___function_object.html" title="converter<> function object">
|
||||
<link rel="next" href="bounds___traits_class.html" title="bounds<> traits class">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="converter___function_object.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="bounds___traits_class.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_numericconversion.type_requirements_and_user_defined_types_support"></a><a class="link" href="type_requirements_and_user_defined_types_support.html" title="Type Requirements and User-defined-types support">Type
|
||||
Requirements and User-defined-types support</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.type_requirements">Type
|
||||
Requirements</a></span></dt>
|
||||
<dt><span class="section"><a href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics">UDT's
|
||||
special semantics</a></span></dt>
|
||||
<dt><span class="section"><a href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.special_policies">Special
|
||||
Policies</a></span></dt>
|
||||
<dt><span class="section"><a href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast">UDTs
|
||||
with numeric_cast</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.type_requirements_and_user_defined_types_support.type_requirements"></a><a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.type_requirements" title="Type Requirements">Type
|
||||
Requirements</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Both arithmetic (built-in) and user-defined numeric types require proper
|
||||
specialization of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><></span></code>
|
||||
(that is, with (in-class) integral constants).
|
||||
</p>
|
||||
<p>
|
||||
The library uses <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_specialized</span></code> to detect whether the type
|
||||
is builtin or user defined, and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_integer</span></code>, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_signed</span></code> to detect whether the type is
|
||||
integer or floating point; and whether it is signed/unsigned.
|
||||
</p>
|
||||
<p>
|
||||
The default <code class="computeroutput"><span class="identifier">Float2IntRounder</span></code>
|
||||
policies uses unqualified calls to functions <code class="computeroutput"><span class="identifier">floor</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">ceil</span><span class="special">()</span></code>; but the standard functions are introduced
|
||||
in scope by a using directive:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span> <span class="special">;</span> <span class="keyword">return</span> <span class="identifier">floor</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Therefore, for builtin arithmetic types, the std functions will be used.
|
||||
User defined types should provide overloaded versions of these functions
|
||||
in order to use the default rounder policies. If these overloads are defined
|
||||
within a user namespace argument dependent lookup (ADL) should find them,
|
||||
but if your compiler has a weak ADL you might need to put these functions
|
||||
some place else or write your own rounder policy.
|
||||
</p>
|
||||
<p>
|
||||
The default <code class="computeroutput"><span class="identifier">Trunc</span><span class="special"><></span></code>
|
||||
rounder policy needs to determine if the source value is positive or not,
|
||||
and for this it evaluates the expression <code class="computeroutput"><span class="identifier">s</span>
|
||||
<span class="special"><</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">S</span><span class="special">>(</span><span class="number">0</span><span class="special">)</span></code>. Therefore,
|
||||
user defined types require a visible <code class="computeroutput"><span class="keyword">operator</span><span class="special"><</span></code> in order to use the <code class="computeroutput"><span class="identifier">Trunc</span><span class="special"><></span></code> policy (the default).
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics"></a><a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics" title="UDT's special semantics">UDT's
|
||||
special semantics</a>
|
||||
</h3></div></div></div>
|
||||
<h5>
|
||||
<a name="boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics.h0"></a>
|
||||
<span class="phrase"><a name="boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics.conversion_traits"></a></span><a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics.conversion_traits">Conversion
|
||||
Traits</a>
|
||||
</h5>
|
||||
<p>
|
||||
If a User Defined Type is involved in a conversion, it is <span class="emphasis"><em>assumed</em></span>
|
||||
that the UDT has <a class="link" href="definitions.html#boost_numericconversion.definitions.range_and_precision" title="Range and Precision">wider
|
||||
range</a> than any built-in type, and consequently the values of some
|
||||
<code class="computeroutput"><span class="identifier">converter_traits</span><span class="special"><></span></code>
|
||||
members are hardwired regardless of the reality. The following table summarizes
|
||||
this:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">Target</span><span class="special">=</span></code><span class="emphasis"><em>UDT</em></span>
|
||||
and <code class="computeroutput"><span class="identifier">Source</span><span class="special">=</span></code><span class="emphasis"><em>built-in</em></span>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">subranged</span><span class="special">=</span><span class="keyword">false</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">supertype</span><span class="special">=</span><span class="identifier">Target</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">subtype</span><span class="special">=</span><span class="identifier">Source</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">Target</span><span class="special">=</span></code><span class="emphasis"><em>built-in</em></span>
|
||||
and <code class="computeroutput"><span class="identifier">Source</span><span class="special">=</span></code><span class="emphasis"><em>UDT</em></span>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">subranged</span><span class="special">=</span><span class="keyword">true</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">supertype</span><span class="special">=</span><span class="identifier">Source</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">subtype</span><span class="special">=</span><span class="identifier">Target</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">Target</span><span class="special">=</span></code><span class="emphasis"><em>UDT</em></span>
|
||||
and <code class="computeroutput"><span class="identifier">Source</span><span class="special">=</span></code><span class="emphasis"><em>UDT</em></span>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">subranged</span><span class="special">=</span><span class="keyword">false</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">supertype</span><span class="special">=</span><span class="identifier">Target</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">subtype</span><span class="special">=</span><span class="identifier">Source</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The <code class="computeroutput"><span class="identifier">Traits</span></code> member <code class="computeroutput"><span class="identifier">udt_mixture</span></code> can be used to detect whether
|
||||
a UDT is involved and to infer the validity of the other members as shown
|
||||
above.
|
||||
</p>
|
||||
<h5>
|
||||
<a name="boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics.h1"></a>
|
||||
<span class="phrase"><a name="boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics.range_checking"></a></span><a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics.range_checking">Range
|
||||
Checking</a>
|
||||
</h5>
|
||||
<p>
|
||||
Because User Defined Numeric Types might have peculiar ranges (such as an
|
||||
unbounded range), this library does not attempt to supply a meaningful range
|
||||
checking logic when UDTs are involved in a conversion. Therefore, if either
|
||||
Target or Source are not built-in types, the bundled range checking of the
|
||||
<code class="computeroutput"><span class="identifier">converter</span><span class="special"><></span></code>
|
||||
function object is automatically disabled. However, it is possible to supply
|
||||
a user-defined range-checker. See <a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.special_policies" title="Special Policies">Special
|
||||
Policies</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.type_requirements_and_user_defined_types_support.special_policies"></a><a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.special_policies" title="Special Policies">Special
|
||||
Policies</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
There are two components of the <code class="computeroutput"><span class="identifier">converter</span><span class="special"><></span></code> class that might require special
|
||||
behavior if User Defined Numeric Types are involved: the Range Checking and
|
||||
the Raw Conversion.
|
||||
</p>
|
||||
<p>
|
||||
When both Target and Source are built-in types, the converter class uses
|
||||
an internal range checking logic which is optimized and customized for the
|
||||
combined properties of the types.
|
||||
</p>
|
||||
<p>
|
||||
However, this internal logic is disabled when either type is User Defined.
|
||||
In this case, the user can specify an <span class="emphasis"><em>external</em></span> range
|
||||
checking policy which will be used in place of the internal code. See <a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast" title="UDTs with numeric_cast">numeric_cast_traits</a>
|
||||
for details on using UDTs with <code class="computeroutput"><span class="identifier">numeric_cast</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
The converter class performs the actual conversion using a Raw Converter
|
||||
policy. The default raw converter simply performs a <code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Target</span><span class="special">>(</span><span class="identifier">source</span><span class="special">)</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
However, if the a UDT is involved, the <code class="computeroutput"><span class="keyword">static_cast</span></code>
|
||||
might not work. In this case, the user can implement and pass a different
|
||||
raw converter policy. See <a class="link" href="numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter" title="Policy RawConverter">RawConverter</a>
|
||||
policy for details.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast"></a><a class="link" href="type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast" title="UDTs with numeric_cast">UDTs
|
||||
with numeric_cast</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
In order to employ UDTs with <code class="computeroutput"><span class="identifier">numeric_cast</span></code>,
|
||||
the user should define a <code class="computeroutput"><span class="identifier">numeric_cast_traits</span></code>
|
||||
specialization on the UDT for each conversion. Here is an example of specializations
|
||||
for converting between the UDT and any other type:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Source</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">numeric_cast_traits</span><span class="special"><</span><span class="identifier">UDT</span><span class="special">,</span> <span class="identifier">Source</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">conversion_traits</span><span class="special"><</span><span class="identifier">UDT</span><span class="special">,</span> <span class="identifier">Source</span><span class="special">></span> <span class="identifier">conv_traits</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">//! The following are required:</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">YourOverflowHandlerPolicy</span> <span class="identifier">overflow_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">YourRangeCheckerPolicy</span><span class="special"><</span><span class="identifier">conv_traits</span><span class="special">></span> <span class="identifier">range_checking_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">YourFloat2IntRounderPolicy</span><span class="special"><</span><span class="identifier">Source</span><span class="special">></span> <span class="identifier">rounding_policy</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Target</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">numeric_cast_traits</span><span class="special"><</span><span class="identifier">Target</span><span class="special">,</span> <span class="identifier">UDT</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">conversion_traits</span><span class="special"><</span><span class="identifier">Target</span><span class="special">,</span> <span class="identifier">UDT</span><span class="special">></span> <span class="identifier">conv_traits</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">//! The following are required:</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">YourOverflowHandlerPolicy</span> <span class="identifier">overflow_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">YourRangeCheckerPolicy</span><span class="special"><</span><span class="identifier">conv_traits</span><span class="special">></span> <span class="identifier">range_checking_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">YourFloat2IntRounderPolicy</span><span class="special"><</span><span class="identifier">UDT</span><span class="special">></span> <span class="identifier">rounding_policy</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
<span class="special">}}//</span><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
These specializations are already defined with default values for the built-in
|
||||
numeric types. It is possible to disable the generation of specializations
|
||||
for built-in types by defining <code class="computeroutput"><span class="identifier">BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS</span></code>.
|
||||
For details on defining custom policies see <a class="link" href="numeric_converter_policy_classes.html" title="Numeric Converter Policy Classes">Converter
|
||||
Policies</a>.
|
||||
</p>
|
||||
<p>
|
||||
Here is a full example of how to define a custom UDT for use with <code class="computeroutput"><span class="identifier">numeric_cast</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">//! Define a simple custom number</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Double</span>
|
||||
<span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators</span>
|
||||
<span class="special"><</span>
|
||||
<span class="identifier">Double</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">double</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">double</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">float</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">int</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">long</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">long</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">long</span> <span class="keyword">long</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">char</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">char</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">short</span>
|
||||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ordered_field_operators2</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">short</span>
|
||||
<span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span> <span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">Double</span><span class="special">()</span>
|
||||
<span class="special">:</span> <span class="identifier">v</span><span class="special">(</span><span class="number">0</span><span class="special">)</span>
|
||||
<span class="special">{}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">explicit</span> <span class="identifier">Double</span><span class="special">(</span> <span class="identifier">T</span> <span class="identifier">v</span> <span class="special">)</span>
|
||||
<span class="special">:</span> <span class="identifier">v</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">v</span><span class="special">))</span>
|
||||
<span class="special">{}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span> <span class="identifier">t</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">t</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special"><</span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">v</span> <span class="special"><</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special"><</span> <span class="special">(</span> <span class="identifier">T</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">v</span> <span class="special"><</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">rhs</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">></span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">v</span> <span class="special">></span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">></span> <span class="special">(</span> <span class="identifier">T</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">v</span> <span class="special">></span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">rhs</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==(</span> <span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">v</span> <span class="special">==</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span> <span class="identifier">T</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">v</span> <span class="special">==</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">rhs</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!()</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">v</span> <span class="special">==</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="identifier">Double</span> <span class="keyword">operator</span> <span class="special">-()</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Double</span><span class="special">(-</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">+=(</span> <span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">t</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">+=</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">+=(</span> <span class="identifier">T</span> <span class="identifier">t</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">+=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">t</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">-=(</span> <span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">t</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">-=</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">-=(</span> <span class="identifier">T</span> <span class="identifier">t</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">-=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">t</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">factor</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">*=</span> <span class="identifier">factor</span><span class="special">.</span><span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*=(</span> <span class="identifier">T</span> <span class="identifier">t</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">*=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">t</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">divisor</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">/=</span> <span class="identifier">divisor</span><span class="special">.</span><span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">Double</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">/=(</span> <span class="identifier">T</span> <span class="identifier">t</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">v</span> <span class="special">/=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="identifier">t</span><span class="special">);</span>
|
||||
<span class="keyword">return</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">double</span> <span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="comment">//! Define numeric_limits for the custom type.</span>
|
||||
<span class="keyword">namespace</span> <span class="identifier">std</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">template</span><span class="special"><></span>
|
||||
<span class="keyword">class</span> <span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">Double</span><span class="special">></span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
|
||||
<span class="comment">//! Limit our Double to a range of +/- 100.0</span>
|
||||
<span class="keyword">static</span> <span class="identifier">Double</span> <span class="special">(</span><span class="identifier">min</span><span class="special">)()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Double</span><span class="special">(</span><span class="number">1.e-2</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">Double</span> <span class="special">(</span><span class="identifier">max</span><span class="special">)()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Double</span><span class="special">(</span><span class="number">1.e2</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">Double</span> <span class="identifier">epsilon</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Double</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">epsilon</span><span class="special">()</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="comment">//! Define range checking and overflow policies.</span>
|
||||
<span class="keyword">namespace</span> <span class="identifier">custom</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">//! Define a custom range checker</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">OverFlowHandler</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">range_checker</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">argument_type</span> <span class="identifier">argument_type</span> <span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">source_type</span> <span class="identifier">S</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Traits</span><span class="special">::</span><span class="identifier">target_type</span> <span class="identifier">T</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">//! Check range of integral types.</span>
|
||||
<span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">range_check_result</span> <span class="identifier">out_of_range</span><span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">;</span>
|
||||
<span class="keyword">if</span><span class="special">(</span> <span class="identifier">s</span> <span class="special">></span> <span class="identifier">bounds</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">highest</span><span class="special">()</span> <span class="special">)</span>
|
||||
<span class="keyword">return</span> <span class="identifier">cPosOverflow</span><span class="special">;</span>
|
||||
<span class="keyword">else</span> <span class="keyword">if</span><span class="special">(</span> <span class="identifier">s</span> <span class="special"><</span> <span class="identifier">bounds</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">lowest</span><span class="special">()</span> <span class="special">)</span>
|
||||
<span class="keyword">return</span> <span class="identifier">cNegOverflow</span><span class="special">;</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="keyword">return</span> <span class="identifier">cInRange</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">validate_range</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">is_bounded</span> <span class="special">);</span>
|
||||
<span class="identifier">OverFlowHandler</span><span class="special">()(</span> <span class="identifier">out_of_range</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="comment">//! Overflow handler</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">positive_overflow</span><span class="special">{};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">negative_overflow</span><span class="special">{};</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">overflow_handler</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">range_check_result</span> <span class="identifier">r</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">;</span>
|
||||
<span class="keyword">if</span><span class="special">(</span> <span class="identifier">r</span> <span class="special">==</span> <span class="identifier">cNegOverflow</span> <span class="special">)</span>
|
||||
<span class="keyword">throw</span> <span class="identifier">negative_overflow</span><span class="special">()</span> <span class="special">;</span>
|
||||
<span class="keyword">else</span> <span class="keyword">if</span><span class="special">(</span> <span class="identifier">r</span> <span class="special">==</span> <span class="identifier">cPosOverflow</span> <span class="special">)</span>
|
||||
<span class="keyword">throw</span> <span class="identifier">positive_overflow</span><span class="special">()</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="comment">//! Define a rounding policy and specialize on the custom type.</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Ceil</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">Ceil</span><span class="special"><</span><span class="identifier">S</span><span class="special">>{};</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Ceil</span><span class="special"><</span><span class="identifier">Double</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">Double</span> <span class="identifier">source_type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">Double</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">argument_type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="preprocessor">#if</span> <span class="special">!</span><span class="identifier">defined</span><span class="special">(</span><span class="identifier">BOOST_NO_STDC_NAMESPACE</span><span class="special">)</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ceil</span> <span class="special">;</span>
|
||||
<span class="preprocessor">#endif</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Double</span><span class="special">(</span> <span class="identifier">ceil</span><span class="special">(</span><span class="identifier">s</span><span class="special">.</span><span class="identifier">v</span><span class="special">)</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">float_round_style</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round_toward_infinity</span><span class="special">></span> <span class="identifier">round_style</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="comment">//! Define a rounding policy and specialize on the custom type.</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Trunc</span><span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">Trunc</span><span class="special"><</span><span class="identifier">S</span><span class="special">>{};</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">Trunc</span><span class="special"><</span><span class="identifier">Double</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">Double</span> <span class="identifier">source_type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">Double</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">argument_type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">static</span> <span class="identifier">source_type</span> <span class="identifier">nearbyint</span> <span class="special">(</span> <span class="identifier">argument_type</span> <span class="identifier">s</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="preprocessor">#if</span> <span class="special">!</span><span class="identifier">defined</span><span class="special">(</span><span class="identifier">BOOST_NO_STDC_NAMESPACE</span><span class="special">)</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">floor</span><span class="special">;</span>
|
||||
<span class="preprocessor">#endif</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Double</span><span class="special">(</span> <span class="identifier">floor</span><span class="special">(</span><span class="identifier">s</span><span class="special">.</span><span class="identifier">v</span><span class="special">)</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">float_round_style</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round_toward_zero</span><span class="special">></span> <span class="identifier">round_style</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
<span class="special">}//</span><span class="keyword">namespace</span> <span class="identifier">custom</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">numeric</span> <span class="special">{</span>
|
||||
|
||||
<span class="comment">//! Define the numeric_cast_traits specializations on the custom type.</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">numeric_cast_traits</span><span class="special"><</span><span class="identifier">Double</span><span class="special">,</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">custom</span><span class="special">::</span><span class="identifier">overflow_handler</span> <span class="identifier">overflow_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">custom</span><span class="special">::</span><span class="identifier">range_checker</span>
|
||||
<span class="special"><</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">conversion_traits</span><span class="special"><</span><span class="identifier">Double</span><span class="special">,</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="special">,</span> <span class="identifier">overflow_policy</span>
|
||||
<span class="special">></span> <span class="identifier">range_checking_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">Trunc</span><span class="special"><</span><span class="identifier">S</span><span class="special">></span> <span class="identifier">rounding_policy</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">numeric_cast_traits</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Double</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">custom</span><span class="special">::</span><span class="identifier">overflow_handler</span> <span class="identifier">overflow_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">custom</span><span class="special">::</span><span class="identifier">range_checker</span>
|
||||
<span class="special"><</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">conversion_traits</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Double</span><span class="special">></span>
|
||||
<span class="special">,</span> <span class="identifier">overflow_policy</span>
|
||||
<span class="special">></span> <span class="identifier">range_checking_policy</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">custom</span><span class="special">::</span><span class="identifier">Trunc</span><span class="special"><</span><span class="identifier">Double</span><span class="special">></span> <span class="identifier">rounding_policy</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="comment">//! Define the conversion from the custom type to built-in types and vice-versa.</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">raw_converter</span><span class="special"><</span> <span class="identifier">conversion_traits</span><span class="special"><</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">Double</span> <span class="special">></span> <span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">static</span> <span class="identifier">T</span> <span class="identifier">low_level_convert</span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">Double</span><span class="special">&</span> <span class="identifier">n</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span> <span class="identifier">n</span><span class="special">.</span><span class="identifier">v</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">S</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">raw_converter</span><span class="special"><</span> <span class="identifier">conversion_traits</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="identifier">S</span> <span class="special">></span> <span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">static</span> <span class="identifier">Double</span> <span class="identifier">low_level_convert</span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">S</span><span class="special">&</span> <span class="identifier">n</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Double</span><span class="special">(</span><span class="identifier">n</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
<span class="special">}}//</span><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">;</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="converter___function_object.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="bounds___traits_class.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,582 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2004 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to 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)
|
||||
=============================================================================*/
|
||||
|
||||
/*=============================================================================
|
||||
Body defaults
|
||||
=============================================================================*/
|
||||
|
||||
body
|
||||
{
|
||||
margin: 1em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Paragraphs
|
||||
=============================================================================*/
|
||||
|
||||
p
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Program listings
|
||||
=============================================================================*/
|
||||
|
||||
/* Code on paragraphs */
|
||||
p tt.computeroutput
|
||||
{
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
pre.synopsis
|
||||
{
|
||||
font-size: 10pt;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
font-size: 10pt;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
/* Program listings in tables don't get borders */
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
margin: 0pc 0pc 0pc 0pc;
|
||||
padding: 0pc 0pc 0pc 0pc;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Headings
|
||||
=============================================================================*/
|
||||
|
||||
h1, h2, h3, h4, h5, h6
|
||||
{
|
||||
text-align: left;
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 { font: 140% }
|
||||
h2 { font: bold 140% }
|
||||
h3 { font: bold 130% }
|
||||
h4 { font: bold 120% }
|
||||
h5 { font: italic 110% }
|
||||
h6 { font: italic 100% }
|
||||
|
||||
/* Top page titles */
|
||||
title,
|
||||
h1.title,
|
||||
h2.title
|
||||
h3.title,
|
||||
h4.title,
|
||||
h5.title,
|
||||
h6.title,
|
||||
.refentrytitle
|
||||
{
|
||||
font-weight: bold;
|
||||
margin-bottom: 1pc;
|
||||
}
|
||||
|
||||
h1.title { font-size: 140% }
|
||||
h2.title { font-size: 140% }
|
||||
h3.title { font-size: 130% }
|
||||
h4.title { font-size: 120% }
|
||||
h5.title { font-size: 110% }
|
||||
h6.title { font-size: 100% }
|
||||
|
||||
.section h1
|
||||
{
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
font-size: 140%;
|
||||
}
|
||||
|
||||
.section h2 { font-size: 140% }
|
||||
.section h3 { font-size: 130% }
|
||||
.section h4 { font-size: 120% }
|
||||
.section h5 { font-size: 110% }
|
||||
.section h6 { font-size: 100% }
|
||||
|
||||
/* Code on titles */
|
||||
h1 tt.computeroutput { font-size: 140% }
|
||||
h2 tt.computeroutput { font-size: 140% }
|
||||
h3 tt.computeroutput { font-size: 130% }
|
||||
h4 tt.computeroutput { font-size: 120% }
|
||||
h5 tt.computeroutput { font-size: 110% }
|
||||
h6 tt.computeroutput { font-size: 100% }
|
||||
|
||||
/*=============================================================================
|
||||
Author
|
||||
=============================================================================*/
|
||||
|
||||
h3.author
|
||||
{
|
||||
font-size: 100%
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Lists
|
||||
=============================================================================*/
|
||||
|
||||
li
|
||||
{
|
||||
font-size: 10pt;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Unordered lists */
|
||||
ul
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Ordered lists */
|
||||
ol
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Links
|
||||
=============================================================================*/
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration: none; /* no underline */
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Spirit style navigation
|
||||
=============================================================================*/
|
||||
|
||||
.spirit-nav
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.spirit-nav a
|
||||
{
|
||||
color: white;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.spirit-nav img
|
||||
{
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Table of contents
|
||||
=============================================================================*/
|
||||
|
||||
.toc
|
||||
{
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.1pc 1pc 0.1pc 1pc;
|
||||
font-size: 10pt;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.toc-main
|
||||
{
|
||||
text-align: center;
|
||||
margin: 3pc 16% 3pc 16%;
|
||||
padding: 3pc 1pc 3pc 1pc;
|
||||
line-height: 0.1;
|
||||
}
|
||||
|
||||
.boost-toc
|
||||
{
|
||||
float: right;
|
||||
padding: 0.5pc;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Tables
|
||||
=============================================================================*/
|
||||
|
||||
.table-title,
|
||||
div.table p.title
|
||||
{
|
||||
margin-left: 4%;
|
||||
padding-right: 0.5em;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.informaltable table,
|
||||
.table table
|
||||
{
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
div.informaltable table,
|
||||
div.table table
|
||||
{
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Table Cells */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
padding: 0.5em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
border: 1pt solid white;
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Blurbs
|
||||
=============================================================================*/
|
||||
|
||||
div.note,
|
||||
div.tip,
|
||||
div.important,
|
||||
div.caution,
|
||||
div.warning,
|
||||
div.sidebar
|
||||
{
|
||||
font-size: 10pt;
|
||||
line-height: 1.2;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
div.sidebar img
|
||||
{
|
||||
padding: 1pt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
Callouts
|
||||
=============================================================================*/
|
||||
.line_callout_bug img
|
||||
{
|
||||
float: left;
|
||||
position:relative;
|
||||
left: 4px;
|
||||
top: -12px;
|
||||
clear: left;
|
||||
margin-left:-22px;
|
||||
}
|
||||
|
||||
.callout_bug img
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
Variable Lists
|
||||
=============================================================================*/
|
||||
|
||||
/* Make the terms in definition lists bold */
|
||||
div.variablelist dl dt,
|
||||
span.term
|
||||
{
|
||||
font-weight: bold;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
div.variablelist table tbody tr td
|
||||
{
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
padding: 0em 2em 0em 0em;
|
||||
font-size: 10pt;
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Make the terms in definition lists bold */
|
||||
div.variablelist dl dt
|
||||
{
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
div.variablelist dl dd
|
||||
{
|
||||
margin: 0em 0em 0.5em 2em;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
div.variablelist table tbody tr td p
|
||||
div.variablelist dl dd p
|
||||
{
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Misc
|
||||
=============================================================================*/
|
||||
|
||||
/* Title of books and articles in bibliographies */
|
||||
span.title
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
span.underline
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
span.strikethrough
|
||||
{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* Copyright, Legal Notice */
|
||||
div div.legalnotice p
|
||||
{
|
||||
text-align: left
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Colors
|
||||
=============================================================================*/
|
||||
|
||||
@media screen
|
||||
{
|
||||
/* Links */
|
||||
a
|
||||
{
|
||||
color: #0C7445;
|
||||
}
|
||||
|
||||
a:visited
|
||||
{
|
||||
color: #663974;
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
|
||||
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
|
||||
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
|
||||
{
|
||||
text-decoration: none; /* no underline */
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* Syntax Highlighting */
|
||||
.keyword { color: #0000AA; }
|
||||
.identifier { color: #000000; }
|
||||
.special { color: #707070; }
|
||||
.preprocessor { color: #402080; }
|
||||
.char { color: teal; }
|
||||
.comment { color: #800000; }
|
||||
.string { color: teal; }
|
||||
.number { color: teal; }
|
||||
.white_bkd { background-color: #E8FBE9; }
|
||||
.dk_grey_bkd { background-color: #A0DAAC; }
|
||||
|
||||
/* Copyright, Legal Notice */
|
||||
.copyright
|
||||
{
|
||||
color: #666666;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div div.legalnotice p
|
||||
{
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
/* Program listing */
|
||||
pre.synopsis
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
border: 0px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Blurbs */
|
||||
div.note,
|
||||
div.tip,
|
||||
div.important,
|
||||
div.caution,
|
||||
div.warning,
|
||||
div.sidebar
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
.toc
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
.toc-main
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
|
||||
/* Tables */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
background-color: #E3F9E4;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
span.highlight
|
||||
{
|
||||
color: #00A000;
|
||||
}
|
||||
}
|
||||
|
||||
@media print
|
||||
{
|
||||
/* Links */
|
||||
a
|
||||
{
|
||||
color: black;
|
||||
}
|
||||
|
||||
a:visited
|
||||
{
|
||||
color: black;
|
||||
}
|
||||
|
||||
.spirit-nav
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Program listing */
|
||||
pre.synopsis
|
||||
{
|
||||
border: 1px solid gray;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid gray;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
border: 0px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
.toc
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
.toc-main
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
.informaltable table,
|
||||
.table table
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
border-bottom: 3px solid #9D9D9D;
|
||||
border-right: 3px solid #9D9D9D;
|
||||
border-collapse: collapse;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
background-color: #FAFFFB;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
span.highlight
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 293 B |
Binary file not shown.
|
After Width: | Height: | Size: 81 B |
@@ -0,0 +1,181 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Chapter 1. Boost.NumericConversion</title>
|
||||
<link rel="stylesheet" href="boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="next" href="boost_numericconversion/definitions.html" title="Definitions">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="boost_numericconversion/definitions.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
<div class="chapter">
|
||||
<div class="titlepage"><div>
|
||||
<div><h2 class="title">
|
||||
<a name="numeric_conversion"></a>Chapter 1. Boost.NumericConversion</h2></div>
|
||||
<div><div class="author"><h3 class="author">
|
||||
<span class="firstname">Fernando Luis</span> <span class="surname">Cacciola Carballal</span>
|
||||
</h3></div></div>
|
||||
<div><p class="copyright">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="numeric_conversion.legal"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></div>
|
||||
</div></div>
|
||||
<div class="toc">
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl class="toc">
|
||||
<dt><span class="section"><a href="index.html#numeric_conversion.overview">Overview</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html">Definitions</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.types_and_values">Types
|
||||
and Values</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.c___arithmetic_types">C++
|
||||
Arithmetic Types</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.numeric_types">Numeric
|
||||
Types</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.range_and_precision">Range
|
||||
and Precision</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.exact__correctly_rounded_and_out_of_range_representations">Exact,
|
||||
Correctly Rounded and Out-Of-Range Representations</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.standard__numeric__conversions">Standard
|
||||
(numeric) Conversions</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.subranged_conversion_direction__subtype_and_supertype">Subranged
|
||||
Conversion Direction, Subtype and Supertype</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_numericconversion/converter___function_object.html">converter<>
|
||||
function object</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_numericconversion/converter___function_object.html#boost_numericconversion.converter___function_object.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/converter___function_object.html#boost_numericconversion.converter___function_object.template_parameters">Template
|
||||
parameters</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/converter___function_object.html#boost_numericconversion.converter___function_object.member_functions">Member
|
||||
functions</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/converter___function_object.html#boost_numericconversion.converter___function_object.range_checking_logic">Range
|
||||
Checking Logic</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/converter___function_object.html#boost_numericconversion.converter___function_object.examples">Examples</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_numericconversion/type_requirements_and_user_defined_types_support.html">Type
|
||||
Requirements and User-defined-types support</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_numericconversion/type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.type_requirements">Type
|
||||
Requirements</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udt_s_special_semantics">UDT's
|
||||
special semantics</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.special_policies">Special
|
||||
Policies</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/type_requirements_and_user_defined_types_support.html#boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast">UDTs
|
||||
with numeric_cast</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_numericconversion/bounds___traits_class.html">bounds<>
|
||||
traits class</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_numericconversion/bounds___traits_class.html#boost_numericconversion.bounds___traits_class.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/bounds___traits_class.html#boost_numericconversion.bounds___traits_class.traits_class_bounds_n_">traits
|
||||
class bounds<N></a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/bounds___traits_class.html#boost_numericconversion.bounds___traits_class.examples">Examples</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_numericconversion/conversion_traits___traits_class.html">conversion_traits<>
|
||||
traits class</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_numericconversion/conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.types">Types</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/conversion_traits___traits_class.html#boost_numericconversion.conversion_traits___traits_class.examples">Examples</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_numericconversion/numeric_converter_policy_classes.html">Numeric
|
||||
Converter Policy Classes</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.enum_range_check_result">enum
|
||||
range_check_result</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler">Policy
|
||||
OverflowHandler</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder">Policy
|
||||
Float2IntRounder</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter">Policy
|
||||
RawConverter</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker">Policy
|
||||
UserRangeChecker</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_numericconversion/improved_numeric_cast__.html">Improved
|
||||
numeric_cast<></a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_numericconversion/improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast">numeric_cast</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast_traits">numeric_cast_traits</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_numericconversion/improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.examples">Examples</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="numeric_conversion/history_and_acknowledgments.html">History
|
||||
and Acknowledgments</a></span></dt>
|
||||
<dt><span class="section"><a href="numeric_conversion/bibliography.html">Bibliography</a></span></dt>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="numeric_conversion.overview"></a><a class="link" href="index.html#numeric_conversion.overview" title="Overview">Overview</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
The Boost Numeric Conversion library is a collection of tools to describe and
|
||||
perform conversions between values of different <a class="link" href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.numeric_types" title="Numeric Types">numeric
|
||||
types</a>.
|
||||
</p>
|
||||
<p>
|
||||
The library includes a special alternative for a subset of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><></span></code>, the <a class="link" href="boost_numericconversion/bounds___traits_class.html" title="bounds<> traits class">bounds<></a>
|
||||
traits class, which provides a consistent way to obtain the <a class="link" href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.range_and_precision" title="Range and Precision">boundary</a>
|
||||
values for the <a class="link" href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.range_and_precision" title="Range and Precision">range</a>
|
||||
of a numeric type.
|
||||
</p>
|
||||
<p>
|
||||
It also includes a set of <a class="link" href="boost_numericconversion/conversion_traits___traits_class.html" title="conversion_traits<> traits class">trait
|
||||
classes</a> which describes the compile-time properties of a conversion
|
||||
from a source to a target numeric type. Both <a class="link" href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.c___arithmetic_types" title="C++ Arithmetic Types">arithmetic</a>
|
||||
and <a class="link" href="boost_numericconversion/definitions.html#boost_numericconversion.definitions.numeric_types" title="Numeric Types">user-defined
|
||||
numeric types</a> can be used.
|
||||
</p>
|
||||
<p>
|
||||
A policy-based <a class="link" href="boost_numericconversion/converter___function_object.html" title="converter<> function object">converter</a>
|
||||
object which uses <code class="computeroutput"><span class="identifier">conversion_traits</span></code>
|
||||
to select an optimized implementation is supplied. Such implementation uses
|
||||
an optimal range checking code suitable for the source/target combination.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
The converter's out-of-range behavior can be customized via an <a class="link" href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler" title="Policy OverflowHandler">OverflowHandler</a>
|
||||
policy.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
For floating-point to integral conversions, the rounding mode can be selected
|
||||
via the <a class="link" href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder" title="Policy Float2IntRounder">Float2IntRounder</a>
|
||||
policy.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A custom low-level conversion routine (for UDTs for instance) can be passed
|
||||
via a <a class="link" href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter" title="Policy RawConverter">RawConverter</a>
|
||||
policy.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The optimized automatic range-checking logic can be overridden via a <a class="link" href="boost_numericconversion/numeric_converter_policy_classes.html#boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker" title="Policy UserRangeChecker">UserRangeChecker</a>
|
||||
policy.
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: June 02, 2014 at 09:10:01 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="boost_numericconversion/definitions.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,88 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Bibliography</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="history_and_acknowledgments.html" title="History and Acknowledgments">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="history_and_acknowledgments.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="numeric_conversion.bibliography"></a><a class="link" href="bibliography.html" title="Bibliography">Bibliography</a>
|
||||
</h2></div></div></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
Standard Documents:
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
ISO/IEC 14882:98 (C++98 Standard)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
ISO/IEC 9899:1999 (C99 Standard)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
ISO/IEC 10967-1 (Language Independent Arithmetic (LIA), Part I, 1994)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
ISO/IEC 2382-1:1993 (Information Technology - Vocabulary - Part I:
|
||||
Fundamental Terms)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
ANSI/IEEE 754-1985 [and IEC 60559:1989] (Binary floating-point)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
ANSI/IEEE 854-1988 (Radix Independent floating-point)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
ANSI X3/TR-1-82 (Dictionary for Information Processing Systems)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
ISO/IEC JTC1/SC22/WG14/N753 C9X Revision Proposal: LIA-1 Binding:
|
||||
Rationale
|
||||
</li>
|
||||
</ol></div>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Papers:
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
David Goldberg What Every Computer Scientist Should Know About Floating-Point
|
||||
Arithmetic
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Prof. William Kahan papers on floating-point.
|
||||
</li>
|
||||
</ol></div>
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="history_and_acknowledgments.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,97 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>History and Acknowledgments</title>
|
||||
<link rel="stylesheet" href="../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.NumericConversion">
|
||||
<link rel="prev" href="../boost_numericconversion/improved_numeric_cast__.html" title="Improved numeric_cast<>">
|
||||
<link rel="next" href="bibliography.html" title="Bibliography">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../boost_numericconversion/improved_numeric_cast__.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="bibliography.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="numeric_conversion.history_and_acknowledgments"></a><a class="link" href="history_and_acknowledgments.html" title="History and Acknowledgments">History
|
||||
and Acknowledgments</a>
|
||||
</h2></div></div></div>
|
||||
<h4>
|
||||
<a name="numeric_conversion.history_and_acknowledgments.h0"></a>
|
||||
<span class="phrase"><a name="numeric_conversion.history_and_acknowledgments.pre_formal_review"></a></span><a class="link" href="history_and_acknowledgments.html#numeric_conversion.history_and_acknowledgments.pre_formal_review">Pre-formal
|
||||
review</a>
|
||||
</h4>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
Kevlin Henney, with help from David Abrahams and Beman Dawes, originally
|
||||
contributed the previous version of <code class="computeroutput"><span class="identifier">numeric_cast</span><span class="special"><></span></code> which already presented the idea
|
||||
of a runtime range check.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Later, Eric Ford, Kevin Lynch and the author spotted some genericity problems
|
||||
with that <code class="computeroutput"><span class="identifier">numeric_cast</span><span class="special"><></span></code> which prevented it from being used
|
||||
in a generic layer of math functions.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
An improved <code class="computeroutput"><span class="identifier">numeric_cast</span><span class="special"><></span></code> which properly handled all combinations
|
||||
of arithmetic types was presented.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
David Abrahams and Beman Dawes acknowledged the need of an improved version
|
||||
of <code class="computeroutput"><span class="identifier">numeric_cast</span><span class="special"><></span></code>
|
||||
and supported the submission as originally laid out. Daryl Walker and Darin
|
||||
Adler made some important comments and proposed fixes to the original submission.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Special thanks go to Björn Karlsoon who helped the author considerably.
|
||||
Having found the problems with <code class="computeroutput"><span class="identifier">numeric_cast</span><span class="special"><></span></code> himself, he revised very carefully
|
||||
the original submission and spot a subtle bug in the range checking implementation.
|
||||
He also wrote part of this documentation and proof-read and corrected other
|
||||
parts. And most importantly: the features now presented here in this library
|
||||
evolved from the original submission as a result of the useful private
|
||||
communications between Björn and the author.
|
||||
</li>
|
||||
</ul></div>
|
||||
<h4>
|
||||
<a name="numeric_conversion.history_and_acknowledgments.h1"></a>
|
||||
<span class="phrase"><a name="numeric_conversion.history_and_acknowledgments.post_formal_review"></a></span><a class="link" href="history_and_acknowledgments.html#numeric_conversion.history_and_acknowledgments.post_formal_review">Post-formal
|
||||
review</a>
|
||||
</h4>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
Guillaume Melquiond spoted some documentation and code issues, particularly
|
||||
about rounding conversions.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The following people contributed an important review of the design, documentation
|
||||
and c ode: Kevin Lynch, Thorsten Ottosen, Paul Bristow, Daryle Walker,
|
||||
Jhon Torjo, Eric Ford, Gennadiy Rozental.
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2004-2007 Fernando
|
||||
Luis Cacciola Carballal<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../boost_numericconversion/improved_numeric_cast__.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="bibliography.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - Index</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000ff" VLINK="#800080">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TH VALIGN="top" WIDTH="300">
|
||||
<H3><A HREF="../../../../index.htm"><IMG HEIGHT="86" WIDTH="277"
|
||||
ALT="C++ Boost" SRC="../../../../boost.png" BORDER="0"></A></H3> </TH>
|
||||
<TH VALIGN="top">
|
||||
<H1 ALIGN="center">Boost Numeric Conversion Library</H1> </TH>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<HR>
|
||||
<table border="0" cellpadding="0" width="100%">
|
||||
<tr>
|
||||
<td width="50%" valign="top"><font size="4">This Document</font><br><br>
|
||||
<a href="#Overview">Overview</a><br>
|
||||
<a href="#Ack">History and Acknowledgments</a><br>
|
||||
<a href="#Ref">Bibliography</a><br>
|
||||
</td>
|
||||
<td width="50%"><font size="4">Other Documents</font><br><br>
|
||||
<A HREF="definitions.html">Definitions</A><br>
|
||||
<A HREF="converter.html"><code>converter<></code> function object</A><br>
|
||||
<A HREF="requirements.html">Type Requirements and User-defined-types support</A><br>
|
||||
<A HREF="bounds.html"><code>bounds<></code> traits class</A><br>
|
||||
<A HREF="conversion_traits.html"><code>conversion_traits<></code> traits class</A><br>
|
||||
<A HREF="converter_policies.html">Numeric Converter Policy Classes</A><br>
|
||||
<A HREF="numeric_cast.html">Improved numeric_cast<></A><br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
<H2><A NAME="Overview"></A>Overview</H2>
|
||||
<P>The Boost Numeric Conversion library is a collection of tools to describe and perform
|
||||
conversions between values of different <a href="definitions.html#numtypes">numeric types</a>.</p>
|
||||
<p>The library includes a special alternative for a subset of <code>std::numeric_limits<></code>,
|
||||
the <A HREF="bounds.html"><code>bounds<></code></A> traits class, which provides
|
||||
a consistent way to obtain the <a href="definitions.html#range">boundary</a> values for the
|
||||
<a href="definitions.html#range">range</a> of a numeric type.</p>
|
||||
<p>It also includes a set of <A HREF="conversion_traits.html">trait classes</A> which
|
||||
describes the compile-time properties of a conversion from a source to a target
|
||||
numeric type. Both <a href="definitions.html#stdtypes">arithmetic</a> and <a href="definitions.html#numtypes">user-defined
|
||||
numeric types</a> can be used.</p>
|
||||
<p>A policy-based <A HREF="converter.html">converter</A> object which uses <code>conversion_traits</code>
|
||||
to select an optimized implementation is supplied.
|
||||
Such implementation uses an optimal range checking code suitable for the source/target combination.<br>
|
||||
The converter's out-of-range behavior can be customized via an <A HREF="converter_policies.html#oh">OverflowHandler</A>
|
||||
policy.<br>
|
||||
For floating-point to integral conversions, the rounding mode can be selected via
|
||||
the <A HREF="converter_policies.html#f2i">Float2IntRounder</A> policy.<br>
|
||||
A custom low-level conversion routine (for UDTs for instance) can be passed
|
||||
via a <A HREF="converter_policies.html#rawc">RawConverter</A> policy.<br>
|
||||
The optimized automatic range-checking logic can be overridden via a <A HREF="converter_policies.html#rc">UserRangeChecker</A>
|
||||
policy.</p>
|
||||
<hr>
|
||||
<H2><A NAME="Ack"></A>History and Acknowledgments</H2>
|
||||
<p>Pre-formal review:</p>
|
||||
<blockquote>
|
||||
<p>Kevlin Henney, with help from David Abrahams and Beman Dawes, originally contributed
|
||||
the previous version of numeric_cast<> which already presented the idea of a runtime range check.<br>
|
||||
Later, Eric Ford, Kevin Lynch and the author spotted some genericity problems
|
||||
with that numeric_cast<> which prevented it from being used in a generic
|
||||
layer of math functions.<br>
|
||||
An improved numeric_cast<> which properly handled all combinations of arithmetic types was presented.<br>
|
||||
David Abrahams and Beman Dawes acknowledged the need of an improved version
|
||||
of numeric_cast<> and supported the submission as originally laid out.
|
||||
Daryl Walker and Darin Adler made some important comments and proposed fixes
|
||||
to the original submission.</p>
|
||||
<p>Special thanks go to Björn Karlsoon who helped the author considerably. Having
|
||||
found the problems with numeric_cast<> himself, he revised very carefully
|
||||
the original submission and spot a subtle bug in the range checking implementation.
|
||||
He also wrote part of this documentation and proof-read and corrected other
|
||||
parts. And most importantly: the features now presented here in this library
|
||||
evolved from the original submission as a result of the useful private communications
|
||||
between Björn and the author.</p>
|
||||
</blockquote>
|
||||
<p>Post-formal review:</p>
|
||||
<p>Guillaume Melquiond spoted some documentation and code issues, particularly about rounding conversions.<br>
|
||||
The following people contributed an important review of the design, documentation and code: Kevin Lynch, Thorsten Ottosen, Paul Bristow,
|
||||
Daryle Walker, Jhon Torjo, Eric Ford, Gennadiy Rozental.
|
||||
</p>
|
||||
<hr>
|
||||
<H2><A NAME="Ref"></A>Bibliography</H2>
|
||||
<ul>
|
||||
<li>Standard Documents:
|
||||
<ol>
|
||||
<li>ISO/IEC 14882:98 (C++98 Standard)</li>
|
||||
<li>ISO/IEC 9899:1999 (C99 Standard)</li>
|
||||
<li>ISO/IEC 10967-1 (Language Independent Arithmetic (LIA), Part I, 1994)</li>
|
||||
<li>ISO/IEC 2382-1:1993 (Information Technology - Vocabulary - Part I: Fundamental Terms)</li>
|
||||
<li>ANSI/IEEE 754-1985 [and IEC 60559:1989] (Binary floating-point)</li>
|
||||
<li>ANSI/IEEE 854-1988 (Radix Independent floating-point)</li>
|
||||
<li>ANSI X3/TR-1-82 (Dictionary for Information Processing Systems)</li>
|
||||
<li><a href="http://anubis.dkuug.dk/JTC1/SC22/WG14/www/docs/n753.htm">ISO/IEC JTC1/SC22/WG14/N753</a> C9X Revision Proposal: LIA-1 Binding: Rationale</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>Papers:
|
||||
<ol>
|
||||
<li>David Goldberg <A href="http://citeseer.ist.psu.edu/goldberg91what.html">
|
||||
What Every Computer Scientist Should Know About Floating-Point Arithmetic</A></li>
|
||||
<li><A href="http://www.cs.berkeley.edu/~wkahan/">Prof. William Kahan</A> papers on floating-point.</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul>
|
||||
<HR>
|
||||
<P>Revised 23 June 2004</P>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</body>
|
||||
</HTML>
|
||||
@@ -1,134 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - numeric_cast</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TH VALIGN="top" WIDTH="300">
|
||||
<H3><A HREF="../../../../index.htm"><IMG HEIGHT="86" WIDTH="277"
|
||||
ALT="C++ Boost" SRC="../../../../boost.png" BORDER="0"></A></H3> </TH>
|
||||
<TH VALIGN="top">
|
||||
<H1 ALIGN="center">Boost Numeric Conversion Library</H1>
|
||||
<H1><A HREF="http://www.boost.org">Header </A><A
|
||||
HREF="../../../../boost/numeric/conversion/cast.hpp">boost/numeric/conversion/cast.hpp</A></H1> </TH>
|
||||
</TR>
|
||||
</TABLE><HR>
|
||||
<H2>Contents</H2>
|
||||
<UL>
|
||||
<LI><A HREF="#introduction">Introduction</A></LI>
|
||||
<LI><A HREF="#numeric_cast"><CODE>numeric_cast</CODE></A></LI>
|
||||
<LI><A HREF="#examples">Examples</A></LI>
|
||||
</UL> <HR>
|
||||
<H2><A NAME="introduction">Introduction</A></H2>
|
||||
<P>The lack of preservation of range makes conversions between numeric
|
||||
types error prone. This is true for both implicit conversions and explicit
|
||||
conversions (through static_cast). <A HREF="#numeric_cast"> numeric_cast</A>
|
||||
detects loss of range when a numeric type is converted, and throws an
|
||||
exception if the range cannot be preserved.</P>
|
||||
<P>There are several situations where conversions are unsafe: </P>
|
||||
<UL>
|
||||
<LI>Conversions from an integral type with a wider range than the target
|
||||
integral type.</LI>
|
||||
<LI> Conversions from unsigned to signed (and vice versa) integral
|
||||
types.</LI>
|
||||
<LI> Conversions from floating point types to integral types.</LI>
|
||||
</UL>
|
||||
<P>The C++ Standard does not specify the behavior when a numeric type is
|
||||
assigned a value that cannot be represented by the type, except for unsigned
|
||||
integral types [3.9.1.4], which must obey the laws of arithmetic modulo
|
||||
2<SUP>n</SUP> (this implies that the result will be reduced modulo the number
|
||||
that is one greater than the largest value that can be represented). The fact
|
||||
that the behavior for overflow is undefined for all conversions (except the
|
||||
aforementioned unsigned to unsigned) makes any code that may produce positive
|
||||
or negative overflows exposed to portability issues.</P>
|
||||
<P>numeric_cast adheres to the rules for implicit conversions mandated by
|
||||
the C++ Standard, such as truncating floating point types when converting to
|
||||
integral types. The implementation must guarantee that for a conversion to a
|
||||
type that can hold all possible values of the source type, there will be no
|
||||
runtime overhead. <BR> <BR> </P> <HR>
|
||||
<H2><A NAME="numeric_cast"><CODE>numeric_cast</CODE></A></H2>
|
||||
<BLOCKQUOTE>
|
||||
<PRE>template<typename Target, typename Source> inline
|
||||
typename boost::numeric::converter<Target,Source>::result_type
|
||||
numeric_cast ( Source arg )
|
||||
{
|
||||
return boost::numeric::converter<Target,Source>::convert(arg);
|
||||
}
|
||||
</PRE> </BLOCKQUOTE>
|
||||
<P>numeric_cast returns the result of converting a value of type Source to a value of type
|
||||
Target. If out-of-range is detected, an exception is thrown (see
|
||||
<A HREF="converter_policies.html#bad_numc">bad_numeric_cast</A>, <A
|
||||
HREF="converter_policies.html#posovr">positive_overflow</A> and
|
||||
<A HREF="converter_policies.html#negovr">negative_overflow</A>). <BR> <BR> </P> <HR>
|
||||
<H2><A NAME="examples">Examples</A></H2>
|
||||
<P>The following example performs some typical conversions between numeric
|
||||
types: </P>
|
||||
<BLOCKQUOTE>
|
||||
<PRE>#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::numeric_cast;
|
||||
|
||||
using boost::numeric::bad_numeric_cast;
|
||||
using boost::numeric::positive_overflow;
|
||||
using boost::numeric::negative_overflow;
|
||||
|
||||
try
|
||||
{
|
||||
int i=42;
|
||||
short s=numeric_cast<short>(i); // This conversion succeeds (is in range)
|
||||
}
|
||||
catch(negative_overflow& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
catch(positive_overflow& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
float f=-42.1234;
|
||||
|
||||
// This will cause a boost::numeric::negative_overflow exception to be thrown
|
||||
unsigned int i=numeric_cast<unsigned int>(f);
|
||||
}
|
||||
catch(bad_numeric_cast& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
|
||||
double d= f + numeric_cast<double>(123); // int -> double
|
||||
|
||||
unsigned long l=std::numeric_limits<unsigned long>::max();
|
||||
|
||||
try
|
||||
{
|
||||
// This will cause a boost::numeric::positive_overflow exception to be thrown
|
||||
// NOTE: *operations* on unsigned integral types cannot cause overflow
|
||||
// but *conversions* to a signed type ARE range checked by numeric_cast.
|
||||
|
||||
unsigned char c=numeric_cast<unsigned char>(l);
|
||||
}
|
||||
catch(positive_overflow& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}</PRE> </BLOCKQUOTE> <BR> <BR> <HR>
|
||||
<HR>
|
||||
<P>Back to <A HREF="index.html">Numeric Conversion library index</A></P>
|
||||
<HR>
|
||||
<P>Revised 20 May 2006</P>
|
||||
<p>© Copyright Boost 1999</p>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 1999,2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,153 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 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)
|
||||
]
|
||||
|
||||
[section Improved numeric_cast<>]
|
||||
|
||||
[section Introduction]
|
||||
|
||||
The lack of preservation of range makes conversions between numeric types
|
||||
error prone. This is true for both implicit conversions and explicit
|
||||
conversions (through `static_cast`).
|
||||
[link boost_numericconversion.improved_numeric_cast__.numeric_cast `numeric_cast`]
|
||||
detects loss of range when a numeric type is converted, and throws an
|
||||
exception if the range cannot be preserved.
|
||||
|
||||
There are several situations where conversions are unsafe:
|
||||
|
||||
* Conversions from an integral type with a wider range than the target integral type.
|
||||
* Conversions from unsigned to signed (and vice versa) integral types.
|
||||
* Conversions from floating point types to integral types.
|
||||
|
||||
The C++ Standard does not specify the behavior when a numeric type is
|
||||
assigned a value that cannot be represented by the type, except for unsigned
|
||||
integral types \[3.9.1.4\], which must obey the laws of arithmetic modulo 2n
|
||||
(this implies that the result will be reduced modulo the number that is one
|
||||
greater than the largest value that can be represented). The fact that the
|
||||
behavior for overflow is undefined for all conversions (except the
|
||||
aforementioned unsigned to unsigned) makes any code that may produce
|
||||
positive or negative overflows exposed to portability issues.
|
||||
|
||||
By default `numeric_cast` adheres to the rules for implicit conversions mandated by
|
||||
the C++ Standard, such as truncating floating point types when converting
|
||||
to integral types. The implementation must guarantee that for a conversion
|
||||
to a type that can hold all possible values of the source type, there will
|
||||
be no runtime overhead.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section numeric_cast]
|
||||
|
||||
template <typename Target, typename Source> inline
|
||||
Target numeric_cast( Source arg )
|
||||
{
|
||||
typedef conversion_traits<Target, Source> conv_traits;
|
||||
typedef numeric_cast_traits<Target, Source> cast_traits;
|
||||
typedef converter
|
||||
<
|
||||
Target,
|
||||
Source,
|
||||
conv_traits,
|
||||
typename cast_traits::overflow_policy,
|
||||
typename cast_traits::rounding_policy,
|
||||
raw_converter<conv_traits>,
|
||||
typename cast_traits::range_checking_policy
|
||||
> converter;
|
||||
return converter::convert(arg);
|
||||
}
|
||||
|
||||
`numeric_cast` returns the result of converting a value of type Source
|
||||
to a value of type Target. If out-of-range is detected, an overflow policy
|
||||
is executed whose default behavior is to throw an an exception (see
|
||||
[link numeric_conversion_bad_numeric_cast bad_numeric_cast],
|
||||
[link numeric_conversion_negative_overflow negative_overflow] and
|
||||
[link numeric_conversion_possitive_overflow positive_overflow]
|
||||
).
|
||||
|
||||
[endsect]
|
||||
|
||||
[section numeric_cast_traits]
|
||||
|
||||
template <typename Target, typename Source, typename EnableIf = void>
|
||||
struct numeric_cast_traits
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<Source> rounding_policy;
|
||||
};
|
||||
|
||||
The behavior of `numeric_cast` may be tailored for custom numeric types through
|
||||
the specialization of `numeric_cast_traits`. (see
|
||||
[link boost_numericconversion.type_requirements_and_user_defined_types_support User Defined Types]
|
||||
for details.
|
||||
)
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
|
||||
The following example performs some typical conversions between numeric types:
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::numeric_cast;
|
||||
|
||||
using boost::numeric::bad_numeric_cast;
|
||||
using boost::numeric::positive_overflow;
|
||||
using boost::numeric::negative_overflow;
|
||||
|
||||
try
|
||||
{
|
||||
int i=42;
|
||||
short s=numeric_cast<short>(i); // This conversion succeeds (is in range)
|
||||
}
|
||||
catch(negative_overflow& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
catch(positive_overflow& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
float f=-42.1234;
|
||||
|
||||
// This will cause a boost::numeric::negative_overflow exception to be thrown
|
||||
unsigned int i=numeric_cast<unsigned int>(f);
|
||||
}
|
||||
catch(bad_numeric_cast& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
|
||||
double d= f + numeric_cast<double>(123); // int -> double
|
||||
|
||||
unsigned long l=std::numeric_limits<unsigned long>::max();
|
||||
|
||||
try
|
||||
{
|
||||
// This will cause a boost::numeric::positive_overflow exception to be thrown
|
||||
// NOTE: *operations* on unsigned integral types cannot cause overflow
|
||||
// but *conversions* to a signed type ARE range checked by numeric_cast.
|
||||
|
||||
unsigned char c=numeric_cast<unsigned char>(l);
|
||||
}
|
||||
catch(positive_overflow& e) {
|
||||
std::cout << e.what();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
@@ -1,116 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../boost.css">
|
||||
<TITLE>Boost Numeric Conversion Library - Type Requirements and User-defined-types support</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000ff" VLINK="#800080">
|
||||
<TABLE BORDER="0" CELLPADDING="7" CELLSPACING="0" WIDTH="100%"
|
||||
SUMMARY="header">
|
||||
<TR>
|
||||
<TH VALIGN="top" WIDTH="300">
|
||||
<H3><A HREF="../../../../index.htm"><IMG HEIGHT="86" WIDTH="277"
|
||||
ALT="C++ Boost" SRC="../../../../boost.png" BORDER="0"></A></H3> </TH>
|
||||
<TH VALIGN="top">
|
||||
<H1 ALIGN="center">Boost Numeric Conversion Library</H1>
|
||||
<H1 ALIGN="center">Type Requirements<br>and<br>User-defined-types support</H1>
|
||||
</TH>
|
||||
</TR>
|
||||
</TABLE> <HR>
|
||||
<H2>Contents</H2>
|
||||
<DL CLASS="page-index">
|
||||
<DT><A HREF="#req">Type Requirements</A></DT>
|
||||
<DT><A HREF="#sem">UDT's special semantics</A></DT>
|
||||
<DT><A HREF="#hooks">Special Policies</A></DT>
|
||||
</DL>
|
||||
|
||||
|
||||
<HR>
|
||||
|
||||
<H2><A NAME="req"></A>Type Requirements</H2>
|
||||
<P>Both arithmetic (built-in) and user-defined numeric types require proper specialization of
|
||||
<CODE>std::numeric_limits<></CODE> (that is, with (in-class) integral constants).<br>
|
||||
The library uses <CODE>std::numeric_limits<T>::is_specialized</CODE> to detect whether
|
||||
the type is builtin or user defined, and <CODE>std::numeric_limits<T>::is_integer,
|
||||
std::numeric_limits<T>::is_signed</CODE>
|
||||
to detect whether the type is integer or floating point; and whether it is signed/unsigned.</P>
|
||||
<P>The default Float2IntRounder policies uses unqualified calls to functions <CODE>floor()
|
||||
and ceil()</CODE>; but the standard functions are introduced in scope by a
|
||||
using directive:</P>
|
||||
<PRE>using std::floor ; return floor(s); </PRE>
|
||||
<P>Therefore, for builtin arithmetic types, the std functions will be used.
|
||||
User defined types should provide overloaded versions of these functions in
|
||||
order to use the default rounder policies. If these overloads are defined within a user namespace
|
||||
argument dependent lookup (ADL) should find them, but if your compiler has a weak ADL
|
||||
you might need to put these functions some place else or write your own rounder policy.</P>
|
||||
<P>The default Trunc<> rounder policy needs to determine if the source value
|
||||
is positive or not, and for this it evaluates the expression "s < static_cast<S>(0)".
|
||||
Therefore, user defined types require a visible operator < in order to use
|
||||
the Trunc<> policy (the default).<br>
|
||||
</P>
|
||||
|
||||
<HR>
|
||||
<H2><A NAME="sem"></A>UDT's special semantics</H2>
|
||||
|
||||
<p><u>Conversion Traits</u></p>
|
||||
<p>If a User Defined Type is involved in a conversion, it is <i>assumed</i> that
|
||||
the UDT has <a href="definitions.html#range">wider range</a> than any built-in
|
||||
type, and consequently the values of some <code>converter_traits<></code>
|
||||
members are hardwired regardless of the reality. The following table summarizes
|
||||
this:</p>
|
||||
|
||||
<li>Target=UDT and Source=built-in
|
||||
<blockquote><code>subranged=false</code><br>
|
||||
<code>supertype=Target</code><br>
|
||||
<code>subtype=Source</code></blockquote>
|
||||
</li>
|
||||
|
||||
<li>Target=built-in and Source=UDT
|
||||
<blockquote><code>subranged=true</code><br>
|
||||
<code>supertype=Source</code><br>
|
||||
<code>subtype=Target</code></blockquote>
|
||||
</li>
|
||||
|
||||
<li>Target=UDT and Source=UDT
|
||||
<blockquote><code>subranged=false</code><br>
|
||||
<code>supertype=Target</code><br>
|
||||
<code>subtype=Source</code></blockquote>
|
||||
</li>
|
||||
<p>The Traits member <code>udt_mixture</code> can be used to detect whether a
|
||||
UDT is involved and to infer the validity of the other members as shown above.</p>
|
||||
<p><u>Range Checking</u></p>
|
||||
<p>Because User Defined Numeric Types might have peculiar ranges (such as an unbounded
|
||||
range), this library does not attempt to supply a meaningful range checking
|
||||
logic when UDTs are involved in a conversion. Therefore, if either Target or
|
||||
Source are not built-in types, the bundled range checking of the <code>converter<></code>
|
||||
function object is automatically disabled. However, it is possible to supply
|
||||
a user-defined range-checker. See <A HREF="#hooks">Special Policies</A></p>
|
||||
|
||||
<HR>
|
||||
<H2><A NAME="hooks"></A>Special Policies</H2>
|
||||
<p>There are two components of the <code>converter<></code> class that might
|
||||
require special behavior if User Defined Numeric Types are involved: the Range
|
||||
Checking and the Raw Conversion.</p>
|
||||
<p>When both Target and Source are built-in types, the converter class uses an
|
||||
<i>internal</i> range checking logic which is optimized and customized for the
|
||||
combined properties of the types.<br>
|
||||
However, this internal logic is disabled when either type is User Defined. In
|
||||
this case, the user can specify an <i>external</i> range checking policy which
|
||||
will be used in place of the internal code.
|
||||
See <a HREF="converter_policies.html#rc">UserRangeChecker</a> policy for details.</p>
|
||||
<p>The converter class performs the actual conversion using a Raw Converter policy.
|
||||
The default raw converter simply performs a <code>"static_cast<Target>(source)".</code><br>
|
||||
However, if the a UDT is involved, the static_cast might not work. In this case,
|
||||
the user can implement and pass a different raw converter policy.
|
||||
See <a HREF="converter_policies.html#rawc">RawConverter</a> policy for details </p>
|
||||
<HR>
|
||||
<P>Back to <A HREF="index.html">Numeric Conversion library index</A></P>
|
||||
<HR>
|
||||
<P>Revised 23 June 2004</P>
|
||||
<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
|
||||
<p> Use, modification, and distribution are subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,448 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 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)
|
||||
]
|
||||
|
||||
[section Type Requirements and User-defined-types support]
|
||||
|
||||
[section Type Requirements]
|
||||
|
||||
Both arithmetic (built-in) and user-defined numeric types require proper
|
||||
specialization of `std::numeric_limits<>` (that is, with (in-class) integral
|
||||
constants).
|
||||
|
||||
The library uses `std::numeric_limits<T>::is_specialized` to detect whether
|
||||
the type is builtin or user defined, and `std::numeric_limits<T>::is_integer`,
|
||||
`std::numeric_limits<T>::is_signed` to detect whether the type is integer
|
||||
or floating point; and whether it is signed/unsigned.
|
||||
|
||||
The default `Float2IntRounder` policies uses unqualified calls to functions
|
||||
`floor()` and `ceil()`; but the standard functions are introduced in scope
|
||||
by a using directive:
|
||||
|
||||
using std::floor ; return floor(s);
|
||||
|
||||
Therefore, for builtin arithmetic types, the std functions will be used.
|
||||
User defined types should provide overloaded versions of these functions in
|
||||
order to use the default rounder policies. If these overloads are defined
|
||||
within a user namespace argument dependent lookup (ADL) should find them,
|
||||
but if your compiler has a weak ADL you might need to put these functions
|
||||
some place else or write your own rounder policy.
|
||||
|
||||
The default `Trunc<>` rounder policy needs to determine if the source value
|
||||
is positive or not, and for this it evaluates the expression
|
||||
`s < static_cast<S>(0)`. Therefore, user defined types require a visible
|
||||
`operator<` in order to use the `Trunc<>` policy (the default).
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section UDT's special semantics]
|
||||
|
||||
[heading Conversion Traits]
|
||||
|
||||
If a User Defined Type is involved in a conversion, it is ['assumed] that
|
||||
the UDT has [link boost_numericconversion.definitions.range_and_precision wider range]
|
||||
than any built-in type, and consequently the values
|
||||
of some `converter_traits<>` members are hardwired regardless of the reality.
|
||||
The following table summarizes this:
|
||||
|
||||
* `Target=`['UDT] and `Source=`['built-in]
|
||||
* `subranged=false`
|
||||
* `supertype=Target`
|
||||
* `subtype=Source`
|
||||
* `Target=`['built-in] and `Source=`['UDT]
|
||||
* `subranged=true`
|
||||
* `supertype=Source`
|
||||
* `subtype=Target`
|
||||
|
||||
* `Target=`['UDT] and `Source=`['UDT]
|
||||
* `subranged=false`
|
||||
* `supertype=Target`
|
||||
* `subtype=Source`
|
||||
|
||||
|
||||
The `Traits` member `udt_mixture` can be used to detect whether a UDT is involved
|
||||
and to infer the validity of the other members as shown above.
|
||||
|
||||
[heading Range Checking]
|
||||
|
||||
Because User Defined Numeric Types might have peculiar ranges (such as an
|
||||
unbounded range), this library does not attempt to supply a meaningful range
|
||||
checking logic when UDTs are involved in a conversion. Therefore, if either
|
||||
Target or Source are not built-in types, the bundled range checking of the
|
||||
`converter<>` function object is automatically disabled. However, it is possible
|
||||
to supply a user-defined range-checker. See
|
||||
[link boost_numericconversion.type_requirements_and_user_defined_types_support.special_policies Special Policies]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Special Policies]
|
||||
|
||||
There are two components of the `converter<>` class that might require special
|
||||
behavior if User Defined Numeric Types are involved: the Range Checking and the
|
||||
Raw Conversion.
|
||||
|
||||
When both Target and Source are built-in types, the converter class uses an internal
|
||||
range checking logic which is optimized and customized for the combined properties
|
||||
of the types.
|
||||
|
||||
However, this internal logic is disabled when either type is User Defined.
|
||||
In this case, the user can specify an ['external] range checking policy which will be
|
||||
used in place of the internal code. See
|
||||
[link boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast numeric_cast_traits]
|
||||
for details on using UDTs with `numeric_cast`.
|
||||
|
||||
The converter class performs the actual conversion using a Raw Converter policy.
|
||||
The default raw converter simply performs a `static_cast<Target>(source)`.
|
||||
|
||||
However, if the a UDT is involved, the `static_cast` might not work. In this case,
|
||||
the user can implement and pass a different raw converter policy.
|
||||
See [link boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter RawConverter] policy for details.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section UDTs with numeric_cast]
|
||||
|
||||
In order to employ UDTs with `numeric_cast`, the user should define
|
||||
a `numeric_cast_traits` specialization on the UDT for each conversion.
|
||||
Here is an example of specializations for converting between the UDT
|
||||
and any other type:
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
template <typename Source>
|
||||
struct numeric_cast_traits<UDT, Source>
|
||||
{
|
||||
typedef conversion_traits<UDT, Source> conv_traits;
|
||||
|
||||
//! The following are required:
|
||||
typedef YourOverflowHandlerPolicy overflow_policy;
|
||||
typedef YourRangeCheckerPolicy<conv_traits> range_checking_policy;
|
||||
typedef YourFloat2IntRounderPolicy<Source> rounding_policy;
|
||||
};
|
||||
template <typename Target>
|
||||
struct numeric_cast_traits<Target, UDT>
|
||||
{
|
||||
typedef conversion_traits<Target, UDT> conv_traits;
|
||||
|
||||
//! The following are required:
|
||||
typedef YourOverflowHandlerPolicy overflow_policy;
|
||||
typedef YourRangeCheckerPolicy<conv_traits> range_checking_policy;
|
||||
typedef YourFloat2IntRounderPolicy<UDT> rounding_policy;
|
||||
};
|
||||
}}//namespace boost::numeric;
|
||||
|
||||
These specializations are already defined with default values for the built-in
|
||||
numeric types. It is possible to disable the generation of specializations for
|
||||
built-in types by defining `BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS`.
|
||||
For details on defining custom policies see [link boost_numericconversion.numeric_converter_policy_classes Converter Policies].
|
||||
|
||||
Here is a full example of how to define a custom UDT for use with `numeric_cast`:
|
||||
|
||||
//! Define a simple custom number
|
||||
struct Double
|
||||
: boost::ordered_field_operators
|
||||
<
|
||||
Double
|
||||
, boost::ordered_field_operators2< Double, long double
|
||||
, boost::ordered_field_operators2< Double, double
|
||||
, boost::ordered_field_operators2< Double, float
|
||||
, boost::ordered_field_operators2< Double, int
|
||||
, boost::ordered_field_operators2< Double, unsigned int
|
||||
, boost::ordered_field_operators2< Double, long
|
||||
, boost::ordered_field_operators2< Double, unsigned long
|
||||
, boost::ordered_field_operators2< Double, long long
|
||||
, boost::ordered_field_operators2< Double, unsigned long long
|
||||
, boost::ordered_field_operators2< Double, char
|
||||
, boost::ordered_field_operators2< Double, unsigned char
|
||||
, boost::ordered_field_operators2< Double, short
|
||||
, boost::ordered_field_operators2< Double, unsigned short
|
||||
> > > > > > > > > > > > > >
|
||||
{
|
||||
Double()
|
||||
: v(0)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
explicit Double( T v )
|
||||
: v(static_cast<double>(v))
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
Double& operator= ( T t )
|
||||
{
|
||||
v = static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator < ( const Double& rhs ) const
|
||||
{
|
||||
return v < rhs.v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator < ( T rhs ) const
|
||||
{
|
||||
return v < static_cast<double>(rhs);
|
||||
}
|
||||
|
||||
bool operator > ( const Double& rhs ) const
|
||||
{
|
||||
return v > rhs.v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator > ( T rhs ) const
|
||||
{
|
||||
return v > static_cast<double>(rhs);
|
||||
}
|
||||
|
||||
bool operator ==( const Double& rhs ) const
|
||||
{
|
||||
return v == rhs.v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator == ( T rhs ) const
|
||||
{
|
||||
return v == static_cast<double>(rhs);
|
||||
}
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return v == 0;
|
||||
}
|
||||
|
||||
Double operator -() const
|
||||
{
|
||||
return Double(-v);
|
||||
}
|
||||
|
||||
Double& operator +=( const Double& t )
|
||||
{
|
||||
v += t.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator +=( T t )
|
||||
{
|
||||
v += static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double& operator -=( const Double& t )
|
||||
{
|
||||
v -= t.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator -=( T t )
|
||||
{
|
||||
v -= static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double& operator *= ( const Double& factor )
|
||||
{
|
||||
v *= factor.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator *=( T t )
|
||||
{
|
||||
v *= static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double& operator /= (const Double& divisor)
|
||||
{
|
||||
v /= divisor.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator /=( T t )
|
||||
{
|
||||
v /= static_cast<double>(t);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
double v;
|
||||
};
|
||||
|
||||
//! Define numeric_limits for the custom type.
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
class numeric_limits<Double> : public numeric_limits<double>
|
||||
{
|
||||
public:
|
||||
|
||||
//! Limit our Double to a range of +/- 100.0
|
||||
static Double (min)()
|
||||
{
|
||||
return Double(1.e-2);
|
||||
}
|
||||
|
||||
static Double (max)()
|
||||
{
|
||||
return Double(1.e2);
|
||||
}
|
||||
|
||||
static Double epsilon()
|
||||
{
|
||||
return Double( std::numeric_limits<double>::epsilon() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//! Define range checking and overflow policies.
|
||||
namespace custom
|
||||
{
|
||||
//! Define a custom range checker
|
||||
template<typename Traits, typename OverFlowHandler>
|
||||
struct range_checker
|
||||
{
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
typedef typename Traits::source_type S;
|
||||
typedef typename Traits::target_type T;
|
||||
|
||||
//! Check range of integral types.
|
||||
static boost::numeric::range_check_result out_of_range( argument_type s )
|
||||
{
|
||||
using namespace boost::numeric;
|
||||
if( s > bounds<T>::highest() )
|
||||
return cPosOverflow;
|
||||
else if( s < bounds<T>::lowest() )
|
||||
return cNegOverflow;
|
||||
else
|
||||
return cInRange;
|
||||
}
|
||||
|
||||
static void validate_range ( argument_type s )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_bounded );
|
||||
OverFlowHandler()( out_of_range(s) );
|
||||
}
|
||||
};
|
||||
|
||||
//! Overflow handler
|
||||
struct positive_overflow{};
|
||||
struct negative_overflow{};
|
||||
|
||||
struct overflow_handler
|
||||
{
|
||||
void operator() ( boost::numeric::range_check_result r )
|
||||
{
|
||||
using namespace boost::numeric;
|
||||
if( r == cNegOverflow )
|
||||
throw negative_overflow() ;
|
||||
else if( r == cPosOverflow )
|
||||
throw positive_overflow() ;
|
||||
}
|
||||
};
|
||||
|
||||
//! Define a rounding policy and specialize on the custom type.
|
||||
template<class S>
|
||||
struct Ceil : boost::numeric::Ceil<S>{};
|
||||
|
||||
template<>
|
||||
struct Ceil<Double>
|
||||
{
|
||||
typedef Double source_type;
|
||||
|
||||
typedef Double const& argument_type;
|
||||
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::ceil ;
|
||||
#endif
|
||||
return Double( ceil(s.v) );
|
||||
}
|
||||
|
||||
typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style;
|
||||
};
|
||||
|
||||
//! Define a rounding policy and specialize on the custom type.
|
||||
template<class S>
|
||||
struct Trunc: boost::numeric::Trunc<S>{};
|
||||
|
||||
template<>
|
||||
struct Trunc<Double>
|
||||
{
|
||||
typedef Double source_type;
|
||||
|
||||
typedef Double const& argument_type;
|
||||
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::floor;
|
||||
#endif
|
||||
return Double( floor(s.v) );
|
||||
}
|
||||
|
||||
typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style;
|
||||
};
|
||||
}//namespace custom;
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
//! Define the numeric_cast_traits specializations on the custom type.
|
||||
template <typename S>
|
||||
struct numeric_cast_traits<Double, S>
|
||||
{
|
||||
typedef custom::overflow_handler overflow_policy;
|
||||
typedef custom::range_checker
|
||||
<
|
||||
boost::numeric::conversion_traits<Double, S>
|
||||
, overflow_policy
|
||||
> range_checking_policy;
|
||||
typedef boost::numeric::Trunc<S> rounding_policy;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct numeric_cast_traits<T, Double>
|
||||
{
|
||||
typedef custom::overflow_handler overflow_policy;
|
||||
typedef custom::range_checker
|
||||
<
|
||||
boost::numeric::conversion_traits<T, Double>
|
||||
, overflow_policy
|
||||
> range_checking_policy;
|
||||
typedef custom::Trunc<Double> rounding_policy;
|
||||
};
|
||||
|
||||
//! Define the conversion from the custom type to built-in types and vice-versa.
|
||||
template<typename T>
|
||||
struct raw_converter< conversion_traits< T, Double > >
|
||||
{
|
||||
static T low_level_convert ( const Double& n )
|
||||
{
|
||||
return static_cast<T>( n.v );
|
||||
}
|
||||
};
|
||||
|
||||
template<typename S>
|
||||
struct raw_converter< conversion_traits< Double, S > >
|
||||
{
|
||||
static Double low_level_convert ( const S& n )
|
||||
{
|
||||
return Double(n);
|
||||
}
|
||||
};
|
||||
}}//namespace boost::numeric;
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// boost cast.hpp header file
|
||||
//
|
||||
// (C) Copyright Antony Polukhin 2014.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/conversion for Documentation.
|
||||
|
||||
// This is a DEPRECATED header file!
|
||||
// Use <boost/polymorphic_cast.hpp> or <boost/numeric/conversion/cast.hpp> instead
|
||||
|
||||
#ifndef BOOST_CAST_HPP
|
||||
#define BOOST_CAST_HPP
|
||||
|
||||
# include <boost/polymorphic_cast.hpp>
|
||||
# include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#endif // BOOST_CAST_HPP
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -16,13 +16,14 @@
|
||||
// 30 Oct 2001 Some fixes suggested by Daryle Walker (Fernando Cacciola)
|
||||
// 25 Oct 2001 Initial boostification (Fernando Cacciola)
|
||||
// 23 Jan 2004 Inital add to cvs (post review)s
|
||||
// 22 Jun 2011 Added support for specializing cast policies via numeric_cast_traits (Brandon Kohn).
|
||||
//
|
||||
#ifndef BOOST_NUMERIC_CONVERSION_CAST_25OCT2001_HPP
|
||||
#define BOOST_NUMERIC_CONVERSION_CAST_25OCT2001_HPP
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x582))
|
||||
|
||||
# include<boost/numeric/conversion/detail/old_numeric_cast.hpp>
|
||||
|
||||
@@ -30,22 +31,31 @@
|
||||
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/numeric/conversion/converter.hpp>
|
||||
#include <boost/numeric/conversion/numeric_cast_traits.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename Target, typename Source>
|
||||
inline
|
||||
Target numeric_cast ( Source arg )
|
||||
{
|
||||
typedef boost::numeric::converter<Target,Source> Converter ;
|
||||
return Converter::convert(arg);
|
||||
}
|
||||
|
||||
using numeric::bad_numeric_cast;
|
||||
|
||||
template <typename Target, typename Source>
|
||||
inline Target numeric_cast( Source arg )
|
||||
{
|
||||
typedef numeric::conversion_traits<Target, Source> conv_traits;
|
||||
typedef numeric::numeric_cast_traits<Target, Source> cast_traits;
|
||||
typedef boost::numeric::converter
|
||||
<
|
||||
Target,
|
||||
Source,
|
||||
conv_traits,
|
||||
typename cast_traits::overflow_policy,
|
||||
typename cast_traits::rounding_policy,
|
||||
boost::numeric::raw_converter< conv_traits >,
|
||||
typename cast_traits::range_checking_policy
|
||||
> converter;
|
||||
return converter::convert(arg);
|
||||
}
|
||||
|
||||
using numeric::bad_numeric_cast;
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -21,13 +21,6 @@ template<class T, class S>
|
||||
struct conversion_traits
|
||||
: convdetail::get_conversion_traits<T,S>::type
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
typedef typename convdetail::get_conversion_traits<T,S>::type base_;
|
||||
typedef typename base_::target_type target_type;
|
||||
typedef typename base_::source_type source_type;
|
||||
typedef typename base_::result_type result_type;
|
||||
typedef typename base_::argument_type argument_type;
|
||||
#endif
|
||||
} ;
|
||||
|
||||
} } // namespace boost::numeric
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -10,11 +10,12 @@
|
||||
#ifndef BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
|
||||
#define BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <typeinfo> // for std::bad_cast
|
||||
|
||||
#include <cmath> // for std::floor and std::ceil
|
||||
|
||||
#include <functional>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/no_tr1/cmath.hpp> // for std::floor and std::ceil
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include "boost/type_traits/is_arithmetic.hpp"
|
||||
|
||||
@@ -135,7 +136,7 @@ class bad_numeric_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char * what() const throw()
|
||||
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
|
||||
{ return "bad numeric conversion: overflow"; }
|
||||
};
|
||||
|
||||
@@ -143,14 +144,14 @@ class negative_overflow : public bad_numeric_cast
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char * what() const throw()
|
||||
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
|
||||
{ return "bad numeric conversion: negative overflow"; }
|
||||
};
|
||||
class positive_overflow : public bad_numeric_cast
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char * what() const throw()
|
||||
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
|
||||
{ return "bad numeric conversion: positive overflow"; }
|
||||
};
|
||||
|
||||
@@ -158,10 +159,17 @@ struct def_overflow_handler
|
||||
{
|
||||
void operator() ( range_check_result r ) // throw(negative_overflow,positive_overflow)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
if ( r == cNegOverflow )
|
||||
throw negative_overflow() ;
|
||||
else if ( r == cPosOverflow )
|
||||
throw positive_overflow() ;
|
||||
#else
|
||||
if ( r == cNegOverflow )
|
||||
::boost::throw_exception(negative_overflow()) ;
|
||||
else if ( r == cPosOverflow )
|
||||
::boost::throw_exception(positive_overflow()) ;
|
||||
#endif
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -450,13 +450,10 @@ namespace boost { namespace numeric { namespace convdetail
|
||||
// Trivial Converter : used when (cv-unqualified) T == (cv-unqualified) S
|
||||
//
|
||||
template<class Traits>
|
||||
struct trivial_converter_impl : public std::unary_function< BOOST_DEDUCED_TYPENAME Traits::argument_type
|
||||
,BOOST_DEDUCED_TYPENAME Traits::result_type
|
||||
>
|
||||
,public dummy_range_checker<Traits>
|
||||
struct trivial_converter_impl : public dummy_range_checker<Traits>
|
||||
{
|
||||
typedef Traits traits ;
|
||||
|
||||
|
||||
typedef typename Traits::source_type source_type ;
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
typedef typename Traits::result_type result_type ;
|
||||
@@ -471,10 +468,7 @@ namespace boost { namespace numeric { namespace convdetail
|
||||
// Rounding Converter : used for float to integral conversions.
|
||||
//
|
||||
template<class Traits,class RangeChecker,class RawConverter,class Float2IntRounder>
|
||||
struct rounding_converter : public std::unary_function< BOOST_DEDUCED_TYPENAME Traits::argument_type
|
||||
,BOOST_DEDUCED_TYPENAME Traits::result_type
|
||||
>
|
||||
,public RangeChecker
|
||||
struct rounding_converter : public RangeChecker
|
||||
,public Float2IntRounder
|
||||
,public RawConverter
|
||||
{
|
||||
@@ -501,10 +495,7 @@ namespace boost { namespace numeric { namespace convdetail
|
||||
// Non-Rounding Converter : used for all other conversions.
|
||||
//
|
||||
template<class Traits,class RangeChecker,class RawConverter>
|
||||
struct non_rounding_converter : public std::unary_function< BOOST_DEDUCED_TYPENAME Traits::argument_type
|
||||
,BOOST_DEDUCED_TYPENAME Traits::result_type
|
||||
>
|
||||
,public RangeChecker
|
||||
struct non_rounding_converter : public RangeChecker
|
||||
,public RawConverter
|
||||
{
|
||||
typedef RangeChecker RangeCheckerBase ;
|
||||
@@ -570,7 +561,7 @@ namespace boost { namespace numeric { namespace convdetail
|
||||
>
|
||||
struct get_converter_impl
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT( 0x0561 ) )
|
||||
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT( 0x0561 ) )
|
||||
// bcc55 prefers sometimes template parameters to be explicit local types.
|
||||
// (notice that is is illegal to reuse the names like this)
|
||||
typedef Traits Traits ;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -16,15 +16,15 @@
|
||||
#include "boost/numeric/conversion/int_float_mixture_enum.hpp"
|
||||
#include "boost/numeric/conversion/detail/meta.hpp"
|
||||
|
||||
#include "boost/mpl/integral_c.hpp"
|
||||
#include "boost/type_traits/integral_constant.hpp"
|
||||
|
||||
namespace boost { namespace numeric { namespace convdetail
|
||||
{
|
||||
// Integral Constants for 'IntFloatMixture'
|
||||
typedef mpl::integral_c<int_float_mixture_enum, integral_to_integral> int2int_c ;
|
||||
typedef mpl::integral_c<int_float_mixture_enum, integral_to_float> int2float_c ;
|
||||
typedef mpl::integral_c<int_float_mixture_enum, float_to_integral> float2int_c ;
|
||||
typedef mpl::integral_c<int_float_mixture_enum, float_to_float> float2float_c ;
|
||||
typedef boost::integral_constant<int_float_mixture_enum, integral_to_integral> int2int_c ;
|
||||
typedef boost::integral_constant<int_float_mixture_enum, integral_to_float> int2float_c ;
|
||||
typedef boost::integral_constant<int_float_mixture_enum, float_to_integral> float2int_c ;
|
||||
typedef boost::integral_constant<int_float_mixture_enum, float_to_float> float2float_c ;
|
||||
|
||||
// Metafunction:
|
||||
//
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -25,7 +25,7 @@ namespace boost { namespace numeric { namespace convdetail
|
||||
template< class T1, class T2>
|
||||
struct equal_to
|
||||
{
|
||||
#if !defined(__BORLANDC__)
|
||||
#if !defined(BOOST_BORLANDC)
|
||||
|
||||
enum { x = ( BOOST_MPL_AUX_VALUE_WKND(T1)::value == BOOST_MPL_AUX_VALUE_WKND(T2)::value ) };
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
//
|
||||
//! Copyright (c) 2011-2012
|
||||
//! Brandon Kohn
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NUMERIC_CONVERSION_DONT_USE_PREPROCESSED_FILES)
|
||||
|
||||
#include <boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
#include <boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp>
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if !BOOST_PP_IS_ITERATING
|
||||
|
||||
#include <boost/preprocessor/seq/elem.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
|
||||
#if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
|
||||
#pragma wave option(preserve: 2, line: 0, output: "preprocessed/numeric_cast_traits_common.hpp")
|
||||
#endif
|
||||
//
|
||||
//! Copyright (c) 2011-2012
|
||||
//! Brandon Kohn
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
#if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
|
||||
#pragma wave option(preserve: 1)
|
||||
#endif
|
||||
|
||||
//! These are the assumed common built in fundamental types (not typedefs/macros.)
|
||||
#define BOOST_NUMERIC_CONVERSION_BASE_BUILTIN_TYPES() \
|
||||
(char) \
|
||||
(signed char) \
|
||||
(unsigned char) \
|
||||
(short) \
|
||||
(unsigned short) \
|
||||
(int) \
|
||||
(unsigned int) \
|
||||
(long) \
|
||||
(unsigned long) \
|
||||
(float) \
|
||||
(double) \
|
||||
(long double) \
|
||||
/***/
|
||||
|
||||
#define BOOST_NUMERIC_CONVERSION_SEQ_A() BOOST_NUMERIC_CONVERSION_BASE_BUILTIN_TYPES()
|
||||
#define BOOST_NUMERIC_CONVERSION_SEQ_B() BOOST_NUMERIC_CONVERSION_BASE_BUILTIN_TYPES()
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_NUMERIC_CONVERSION_SEQ_A())), <boost/numeric/conversion/detail/numeric_cast_traits.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
}}//namespace boost::numeric;
|
||||
|
||||
#if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
|
||||
#pragma wave option(output: null)
|
||||
#endif
|
||||
|
||||
#if ( defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES) ) || !defined(BOOST_NO_LONG_LONG)
|
||||
|
||||
#undef BOOST_NUMERIC_CONVERSION_SEQ_A
|
||||
#undef BOOST_NUMERIC_CONVERSION_SEQ_B
|
||||
|
||||
#if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
|
||||
#pragma wave option(preserve: 2, line: 0, output: "preprocessed/numeric_cast_traits_long_long.hpp")
|
||||
#endif
|
||||
|
||||
//
|
||||
//! Copyright (c) 2011-2012
|
||||
//! Brandon Kohn
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
#if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
|
||||
#pragma wave option(preserve: 1)
|
||||
#endif
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
#define BOOST_NUMERIC_CONVERSION_SEQ_A() BOOST_NUMERIC_CONVERSION_BASE_BUILTIN_TYPES()(boost::long_long_type)(boost::ulong_long_type)
|
||||
#define BOOST_NUMERIC_CONVERSION_SEQ_B() (boost::long_long_type)(boost::ulong_long_type)
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_NUMERIC_CONVERSION_SEQ_A())), <boost/numeric/conversion/detail/numeric_cast_traits.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
}}//namespace boost::numeric;
|
||||
|
||||
#if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
|
||||
#pragma wave option(output: null)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_NUMERIC_CONVERSION_BASE_BUILTIN_TYPES
|
||||
#undef BOOST_NUMERIC_CONVERSION_SEQ_A
|
||||
#undef BOOST_NUMERIC_CONVERSION_SEQ_B
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_NUMERIC_CONVERSION_SEQ_B())), <boost/numeric/conversion/detail/numeric_cast_traits.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 2
|
||||
|
||||
//! Generate default traits for the specified source and target.
|
||||
#define BOOST_NUMERIC_CONVERSION_A BOOST_PP_FRAME_ITERATION(1)
|
||||
#define BOOST_NUMERIC_CONVERSION_B BOOST_PP_FRAME_ITERATION(2)
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
BOOST_PP_SEQ_ELEM(BOOST_NUMERIC_CONVERSION_A, BOOST_NUMERIC_CONVERSION_SEQ_A())
|
||||
, BOOST_PP_SEQ_ELEM(BOOST_NUMERIC_CONVERSION_B, BOOST_NUMERIC_CONVERSION_SEQ_B())
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<BOOST_PP_SEQ_ELEM(BOOST_NUMERIC_CONVERSION_B, BOOST_NUMERIC_CONVERSION_SEQ_B())> rounding_policy;
|
||||
};
|
||||
|
||||
#undef BOOST_NUMERIC_CONVERSION_A
|
||||
#undef BOOST_NUMERIC_CONVERSION_B
|
||||
|
||||
#endif//! Depth 2.
|
||||
#endif// BOOST_NUMERIC_CONVERSION_DONT_USE_PREPROCESSED_FILES
|
||||
Executable → Regular
+7
-38
@@ -8,6 +8,8 @@
|
||||
// See http://www.boost.org/libs/conversion for Documentation.
|
||||
|
||||
// Revision History
|
||||
// 02 Jun 14 Remove VC6 workarounds.
|
||||
// 16 Jul 11 Bugfixes for VC6.
|
||||
// 23 JUN 05 Code extracted from /boost/cast.hpp into this new header.
|
||||
// Keeps this legacy version of numeric_cast<> for old compilers
|
||||
// wich can't compile the new version in /boost/numeric/conversion/cast.hpp
|
||||
@@ -53,19 +55,6 @@
|
||||
# include <boost/limits.hpp>
|
||||
# include <boost/numeric/conversion/converter_policies.hpp>
|
||||
|
||||
// It has been demonstrated numerous times that MSVC 6.0 fails silently at link
|
||||
// time if you use a template function which has template parameters that don't
|
||||
// appear in the function's argument list.
|
||||
//
|
||||
// TODO: Add this to config.hpp?
|
||||
// FLC: This macro is repeated in boost/cast.hpp but only locally (is undefined at the bottom)
|
||||
// so is OK to reproduce it here.
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC < 1300
|
||||
# define BOOST_EXPLICIT_DEFAULT_TARGET , ::boost::type<Target>* = 0
|
||||
# else
|
||||
# define BOOST_EXPLICIT_DEFAULT_TARGET
|
||||
# endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
using numeric::bad_numeric_cast;
|
||||
@@ -214,24 +203,6 @@ namespace boost
|
||||
template <class X, class Y>
|
||||
static inline bool check(X x, Y)
|
||||
{ return x >= 0 && static_cast<X>(static_cast<Y>(x)) != x; }
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC < 1300
|
||||
// MSVC6 can't static_cast unsigned __int64 -> floating types
|
||||
# define BOOST_UINT64_CAST(src_type) \
|
||||
static inline bool check(src_type x, unsigned __int64) \
|
||||
{ \
|
||||
if (x < 0) return false; \
|
||||
unsigned __int64 y = static_cast<unsigned __int64>(x); \
|
||||
bool odd = y & 0x1; \
|
||||
__int64 div2 = static_cast<__int64>(y >> 1); \
|
||||
return ((static_cast<src_type>(div2) * 2.0) + odd) != x; \
|
||||
}
|
||||
|
||||
BOOST_UINT64_CAST(long double);
|
||||
BOOST_UINT64_CAST(double);
|
||||
BOOST_UINT64_CAST(float);
|
||||
# undef BOOST_UINT64_CAST
|
||||
# endif
|
||||
};
|
||||
|
||||
template<>
|
||||
@@ -260,7 +231,7 @@ namespace boost
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4018)
|
||||
# pragma warning(disable : 4146)
|
||||
#elif defined(__BORLANDC__)
|
||||
#elif defined(BOOST_BORLANDC)
|
||||
# pragma option push -w-8041
|
||||
# endif
|
||||
|
||||
@@ -277,7 +248,7 @@ namespace boost
|
||||
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#elif defined(__BORLANDC__)
|
||||
#elif defined(BOOST_BORLANDC)
|
||||
# pragma option pop
|
||||
# endif
|
||||
} // namespace detail
|
||||
@@ -285,7 +256,7 @@ namespace boost
|
||||
#endif
|
||||
|
||||
template<typename Target, typename Source>
|
||||
inline Target numeric_cast(Source arg BOOST_EXPLICIT_DEFAULT_TARGET)
|
||||
inline Target numeric_cast(Source arg)
|
||||
{
|
||||
// typedefs abbreviating respective trait classes
|
||||
typedef detail::fixed_numeric_limits<Source> arg_traits;
|
||||
@@ -314,7 +285,7 @@ namespace boost
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4018)
|
||||
#elif defined(__BORLANDC__)
|
||||
#elif defined(BOOST_BORLANDC)
|
||||
#pragma option push -w-8012
|
||||
# endif
|
||||
if ((arg < 0 && !result_traits::is_signed) // loss of negative range
|
||||
@@ -322,7 +293,7 @@ namespace boost
|
||||
|| arg > (result_traits::max)()) // overflow
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#elif defined(__BORLANDC__)
|
||||
#elif defined(BOOST_BORLANDC)
|
||||
#pragma option pop
|
||||
# endif
|
||||
#endif
|
||||
@@ -332,8 +303,6 @@ namespace boost
|
||||
return static_cast<Target>(arg);
|
||||
} // numeric_cast
|
||||
|
||||
# undef BOOST_EXPLICIT_DEFAULT_TARGET
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_OLD_NUMERIC_CAST_HPP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+347
@@ -0,0 +1,347 @@
|
||||
//
|
||||
//! Copyright (c) 2011-2012
|
||||
//! Brandon Kohn
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
char
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
char
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
signed char
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
signed char
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned char
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned char
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
short
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
short
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned short
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned short
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
int
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
int
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned int
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned int
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
long
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
long
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned long
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
unsigned long
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
float
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
float
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
double
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
double
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
long double
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
long double
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
boost::long_long_type
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
boost::long_long_type
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
boost::ulong_long_type
|
||||
, boost::long_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::long_long_type> rounding_policy;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_cast_traits
|
||||
<
|
||||
boost::ulong_long_type
|
||||
, boost::ulong_long_type
|
||||
>
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<boost::ulong_long_type> rounding_policy;
|
||||
};
|
||||
}}
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -16,15 +16,15 @@
|
||||
#include "boost/numeric/conversion/sign_mixture_enum.hpp"
|
||||
#include "boost/numeric/conversion/detail/meta.hpp"
|
||||
|
||||
#include "boost/mpl/integral_c.hpp"
|
||||
#include "boost/type_traits/integral_constant.hpp"
|
||||
|
||||
namespace boost { namespace numeric { namespace convdetail
|
||||
{
|
||||
// Integral Constants for 'SignMixture'
|
||||
typedef mpl::integral_c<sign_mixture_enum, unsigned_to_unsigned> unsig2unsig_c ;
|
||||
typedef mpl::integral_c<sign_mixture_enum, signed_to_signed> sig2sig_c ;
|
||||
typedef mpl::integral_c<sign_mixture_enum, signed_to_unsigned> sig2unsig_c ;
|
||||
typedef mpl::integral_c<sign_mixture_enum, unsigned_to_signed> unsig2sig_c ;
|
||||
typedef boost::integral_constant<sign_mixture_enum, unsigned_to_unsigned> unsig2unsig_c ;
|
||||
typedef boost::integral_constant<sign_mixture_enum, signed_to_signed> sig2sig_c ;
|
||||
typedef boost::integral_constant<sign_mixture_enum, signed_to_unsigned> sig2unsig_c ;
|
||||
typedef boost::integral_constant<sign_mixture_enum, unsigned_to_signed> unsig2sig_c ;
|
||||
|
||||
// Metafunction:
|
||||
//
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -15,15 +15,15 @@
|
||||
#include "boost/numeric/conversion/udt_builtin_mixture_enum.hpp"
|
||||
#include "boost/numeric/conversion/detail/meta.hpp"
|
||||
|
||||
#include "boost/mpl/integral_c.hpp"
|
||||
#include "boost/type_traits/integral_constant.hpp"
|
||||
|
||||
namespace boost { namespace numeric { namespace convdetail
|
||||
{
|
||||
// Integral Constants for 'UdtMixture'
|
||||
typedef mpl::integral_c<udt_builtin_mixture_enum, builtin_to_builtin> builtin2builtin_c ;
|
||||
typedef mpl::integral_c<udt_builtin_mixture_enum, builtin_to_udt> builtin2udt_c ;
|
||||
typedef mpl::integral_c<udt_builtin_mixture_enum, udt_to_builtin> udt2builtin_c ;
|
||||
typedef mpl::integral_c<udt_builtin_mixture_enum, udt_to_udt> udt2udt_c ;
|
||||
typedef boost::integral_constant<udt_builtin_mixture_enum, builtin_to_builtin> builtin2builtin_c ;
|
||||
typedef boost::integral_constant<udt_builtin_mixture_enum, builtin_to_udt> builtin2udt_c ;
|
||||
typedef boost::integral_constant<udt_builtin_mixture_enum, udt_to_builtin> udt2builtin_c ;
|
||||
typedef boost::integral_constant<udt_builtin_mixture_enum, udt_to_udt> udt2udt_c ;
|
||||
|
||||
// Metafunction:
|
||||
//
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
//! Copyright (c) 2011
|
||||
//! Brandon Kohn
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
#ifndef BOOST_NUMERIC_CAST_TRAITS_HPP
|
||||
#define BOOST_NUMERIC_CAST_TRAITS_HPP
|
||||
|
||||
#include <boost/numeric/conversion/converter_policies.hpp>
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
template <typename Target, typename Source, typename EnableIf = void>
|
||||
struct numeric_cast_traits
|
||||
{
|
||||
typedef def_overflow_handler overflow_policy;
|
||||
typedef UseInternalRangeChecker range_checking_policy;
|
||||
typedef Trunc<Source> rounding_policy;
|
||||
};
|
||||
|
||||
}}//namespace boost::numeric;
|
||||
|
||||
#if !defined( BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS )
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/numeric/conversion/detail/numeric_cast_traits.hpp>
|
||||
#endif//!defined BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS
|
||||
|
||||
#endif//BOOST_NUMERIC_CAST_TRAITS_HPP
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.html">
|
||||
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="doc/index.html">doc/index.html</a>. <hr>
|
||||
<p>© Copyright Beman Dawes, 2001</p>
|
||||
<a href="doc/html/index.html">doc/index.html</a>. <hr>
|
||||
<p>� Copyright Beman Dawes, 2001</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
|
||||
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"key": "numeric/conversion",
|
||||
"name": "Numeric Conversion",
|
||||
"authors": [
|
||||
"Fernando Cacciola"
|
||||
],
|
||||
"description": "Optimized Policy-based Numeric Conversions.",
|
||||
"category": [
|
||||
"Math",
|
||||
"Miscellaneous"
|
||||
],
|
||||
"maintainers": [
|
||||
"Fernando Cacciola <fernando_cacciola -at- ciudad.com.ar>",
|
||||
"Brandon Kohn <blkohn -at- hotmail.com>"
|
||||
],
|
||||
"cxxstd": "03"
|
||||
}
|
||||
+39
-8
@@ -1,11 +1,42 @@
|
||||
# Boost Numeric Conversion Library test Jamfile
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
# import testing ;
|
||||
|
||||
test-suite numeric/conversion :
|
||||
[ run bounds_test.cpp ]
|
||||
[ run traits_test.cpp ]
|
||||
[ run converter_test.cpp ]
|
||||
[ run udt_support_test.cpp ]
|
||||
[ run numeric_cast_test.cpp ]
|
||||
[ run udt_example_0.cpp ]
|
||||
;
|
||||
project numeric_conversion_unit_tests
|
||||
:
|
||||
requirements
|
||||
<include>.
|
||||
<toolset>gcc:<cxxflags>"-ftemplate-depth-300 -g0"
|
||||
<toolset>darwin:<cxxflags>"-ftemplate-depth-300 -g0"
|
||||
;
|
||||
|
||||
test-suite minimal
|
||||
:
|
||||
[ run bounds_test.cpp ]
|
||||
[ run traits_test.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run converter_test.cpp ]
|
||||
[ run udt_support_test.cpp ]
|
||||
[ run numeric_cast_test.cpp ]
|
||||
[ run udt_example_0.cpp ]
|
||||
[ run numeric_cast_traits_test.cpp ]
|
||||
;
|
||||
|
||||
test-suite full
|
||||
:
|
||||
minimal
|
||||
[ compile-fail compile_fail/built_in_numeric_cast_traits.cpp ]
|
||||
;
|
||||
|
||||
test-suite extra ;
|
||||
|
||||
explicit minimal ;
|
||||
explicit extra ;
|
||||
|
||||
# support the old test target
|
||||
test-suite numeric/conversion : full ;
|
||||
|
||||
+7
-13
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "boost/numeric/conversion/bounds.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
@@ -32,17 +32,11 @@ void test_bounds( T expected_lowest, T expected_highest, T expected_smallest )
|
||||
T highest = bounds<T>::highest () ;
|
||||
T smallest = bounds<T>::smallest() ;
|
||||
|
||||
BOOST_CHECK_MESSAGE ( lowest == expected_lowest,
|
||||
"bounds<" << typeid(T).name() << ">::lowest() = " << printable(lowest) << ". Expected " << printable(expected_lowest)
|
||||
) ;
|
||||
BOOST_TEST_EQ(lowest, expected_lowest);
|
||||
|
||||
BOOST_CHECK_MESSAGE ( highest == expected_highest,
|
||||
"bounds<" << typeid(T).name() << ">::highest() = " << printable(highest) << ". Expected " << printable(expected_highest)
|
||||
) ;
|
||||
BOOST_TEST_EQ(highest, expected_highest);
|
||||
|
||||
BOOST_CHECK_MESSAGE ( smallest == expected_smallest,
|
||||
"bounds<" << typeid(T).name() << ">::smallest() = " << printable(smallest) << ". Expected " << printable(expected_smallest)
|
||||
) ;
|
||||
BOOST_TEST_EQ(smallest, expected_smallest);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,12 +84,12 @@ void test_bounds()
|
||||
}
|
||||
|
||||
|
||||
int test_main( int, char * [] )
|
||||
int main( )
|
||||
{
|
||||
cout << setprecision( std::numeric_limits<long double>::digits10 ) ;
|
||||
|
||||
test_bounds();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
//! Copyright (c) 2011
|
||||
//! Brandon Kohn
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/preprocessor/control/iif.hpp>
|
||||
#include <boost/preprocessor/comparison/less.hpp>
|
||||
#include <boost/preprocessor/comparison/not_equal.hpp>
|
||||
#include <boost/preprocessor/repetition/for.hpp>
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
#include <boost/preprocessor/seq/elem.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
|
||||
//! Generate default traits for the specified source and target.
|
||||
#define BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS(r, state) \
|
||||
template <> \
|
||||
struct numeric_cast_traits< \
|
||||
BOOST_PP_SEQ_ELEM( BOOST_PP_TUPLE_ELEM(4,0,state) \
|
||||
, BOOST_PP_TUPLE_ELEM(4,3,state) ) \
|
||||
, BOOST_PP_TUPLE_ELEM(4,2,state)> \
|
||||
{ \
|
||||
typedef def_overflow_handler overflow_policy; \
|
||||
typedef UseInternalRangeChecker range_checking_policy; \
|
||||
typedef Trunc<BOOST_PP_TUPLE_ELEM(4,2,state)> rounding_policy; \
|
||||
}; \
|
||||
/***/
|
||||
|
||||
#define BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL(r, state) \
|
||||
BOOST_PP_LESS \
|
||||
( \
|
||||
BOOST_PP_TUPLE_ELEM(4,0,state) \
|
||||
, BOOST_PP_TUPLE_ELEM(4,1,state) \
|
||||
) \
|
||||
/***/
|
||||
|
||||
#define BOOST_NUMERIC_CONVERSION_INC_OP(r, state) \
|
||||
( \
|
||||
BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4,0,state)) \
|
||||
, BOOST_PP_TUPLE_ELEM(4,1,state) \
|
||||
, BOOST_PP_TUPLE_ELEM(4,2,state) \
|
||||
, BOOST_PP_TUPLE_ELEM(4,3,state) \
|
||||
) \
|
||||
/***/
|
||||
|
||||
#define BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP(r, state) \
|
||||
BOOST_PP_FOR \
|
||||
( \
|
||||
( \
|
||||
0 \
|
||||
, BOOST_PP_TUPLE_ELEM(4,1,state) \
|
||||
, BOOST_PP_SEQ_ELEM(BOOST_PP_TUPLE_ELEM(4,0,state),BOOST_PP_TUPLE_ELEM(4,2,state)) \
|
||||
, BOOST_PP_TUPLE_ELEM(4,2,state) \
|
||||
) \
|
||||
, BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL \
|
||||
, BOOST_NUMERIC_CONVERSION_INC_OP \
|
||||
, BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS \
|
||||
) \
|
||||
/***/
|
||||
|
||||
#define BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS(types) \
|
||||
BOOST_PP_FOR \
|
||||
( \
|
||||
(0,BOOST_PP_SEQ_SIZE(types),types,_) \
|
||||
, BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL \
|
||||
, BOOST_NUMERIC_CONVERSION_INC_OP \
|
||||
, BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP \
|
||||
) \
|
||||
/***/
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
#if !defined( BOOST_NO_INT64_T )
|
||||
//! Generate the specializations for the built-in types.
|
||||
BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS
|
||||
(
|
||||
(char)
|
||||
(boost::int8_t)
|
||||
(boost::uint8_t)
|
||||
(boost::int16_t)
|
||||
(boost::uint16_t)
|
||||
(boost::int32_t)
|
||||
(boost::uint32_t)
|
||||
(boost::int64_t)
|
||||
(boost::uint64_t)
|
||||
(float)
|
||||
(double)
|
||||
(long double)
|
||||
)
|
||||
#else
|
||||
BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS
|
||||
(
|
||||
(char)
|
||||
(boost::int8_t)
|
||||
(boost::uint8_t)
|
||||
(boost::int16_t)
|
||||
(boost::uint16_t)
|
||||
(boost::int32_t)
|
||||
(boost::uint32_t)
|
||||
(float)
|
||||
(double)
|
||||
(long double)
|
||||
)
|
||||
#endif
|
||||
}}//namespace boost::numeric;
|
||||
|
||||
#undef BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS
|
||||
#undef BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP
|
||||
#undef BOOST_NUMERIC_CONVERSION_INC_OP
|
||||
#undef BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL
|
||||
#undef BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS
|
||||
@@ -1,4 +1,4 @@
|
||||
// © Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
// Borland 5.5 lacks the following math overloads
|
||||
//
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
|
||||
#if BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x551)
|
||||
namespace std
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ inline long double floor (long double x) { return std::floorl(x); }
|
||||
#include "boost/numeric/conversion/converter.hpp"
|
||||
#include "boost/numeric/conversion/cast.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
@@ -368,7 +368,7 @@ void test_round_style( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S) )
|
||||
void test_round_even( double n, double x )
|
||||
{
|
||||
double r = boost::numeric::RoundEven<double>::nearbyint(n);
|
||||
BOOST_CHECK( r == x ) ;
|
||||
BOOST_TEST( r == x ) ;
|
||||
}
|
||||
|
||||
void test_round_even()
|
||||
@@ -419,7 +419,7 @@ void test_converter_as_function_object()
|
||||
|
||||
// Match 'w' and 'i' which should be equal.
|
||||
bool double_to_int_OK = std::equal(W.begin(),W.end(),I.begin()) ;
|
||||
BOOST_CHECK_MESSAGE(double_to_int_OK, "converter (int,double) as function object");
|
||||
BOOST_TEST(double_to_int_OK);
|
||||
|
||||
// Create a sequence of double values from s using a default numeric::converter (which should be the trivial conv).
|
||||
std::vector<double> D ;
|
||||
@@ -431,7 +431,7 @@ void test_converter_as_function_object()
|
||||
|
||||
// Match 's' and 'd' which should be equal.
|
||||
bool double_to_double_OK = std::equal(S.begin(),S.end(),D.begin()) ;
|
||||
BOOST_CHECK_MESSAGE(double_to_double_OK, "converter (double,double) as function object");
|
||||
BOOST_TEST(double_to_double_OK);
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__IBMCPP__, <= 600 ) // VCAPP6
|
||||
@@ -545,7 +545,7 @@ void test_optimizations()
|
||||
//---------------------------------
|
||||
}
|
||||
|
||||
int test_main( int, char* argv[] )
|
||||
int main()
|
||||
{
|
||||
std::cout << std::setprecision( std::numeric_limits<long double>::digits10 ) ;
|
||||
|
||||
@@ -556,7 +556,7 @@ int test_main( int, char* argv[] )
|
||||
test_converter_as_function_object();
|
||||
test_optimizations() ;
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
+17
-34
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
# if SCHAR_MAX == LONG_MAX
|
||||
# error "This test program doesn't work if SCHAR_MAX == LONG_MAX"
|
||||
@@ -24,7 +24,7 @@
|
||||
using namespace boost;
|
||||
using std::cout;
|
||||
|
||||
int test_main( int argc, char * argv[] )
|
||||
int main()
|
||||
{
|
||||
|
||||
# ifdef NDEBUG
|
||||
@@ -47,51 +47,34 @@ int test_main( int argc, char * argv[] )
|
||||
c = large_value; // see if compiler generates warning
|
||||
|
||||
c = numeric_cast<signed char>( small_value );
|
||||
BOOST_CHECK( c == 1 );
|
||||
BOOST_TEST( c == 1 );
|
||||
c = 0;
|
||||
c = numeric_cast<signed char>( small_value );
|
||||
BOOST_CHECK( c == 1 );
|
||||
BOOST_TEST( c == 1 );
|
||||
c = 0;
|
||||
c = numeric_cast<signed char>( small_negative_value );
|
||||
BOOST_CHECK( c == -1 );
|
||||
BOOST_TEST( c == -1 );
|
||||
|
||||
// These tests courtesy of Joe R NWP Swatosh<joe.r.swatosh@usace.army.mil>
|
||||
BOOST_CHECK( 0.0f == numeric_cast<float>( 0.0 ) );
|
||||
BOOST_CHECK( 0.0 == numeric_cast<double>( 0.0 ) );
|
||||
BOOST_TEST( 0.0f == numeric_cast<float>( 0.0 ) );
|
||||
BOOST_TEST( 0.0 == numeric_cast<double>( 0.0 ) );
|
||||
|
||||
// tests which should result in errors being detected
|
||||
|
||||
bool caught_exception = false;
|
||||
try { c = numeric_cast<signed char>( large_value ); }
|
||||
catch ( numeric::bad_numeric_cast )
|
||||
{ cout<<"caught bad_numeric_cast #1\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
BOOST_TEST_THROWS( numeric_cast<signed char>(large_value),
|
||||
numeric::bad_numeric_cast );
|
||||
|
||||
caught_exception = false;
|
||||
try { c = numeric_cast<signed char>( large_negative_value ); }
|
||||
catch ( numeric::bad_numeric_cast )
|
||||
{ cout<<"caught bad_numeric_cast #2\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
BOOST_TEST_THROWS( numeric_cast<signed char>(large_negative_value),
|
||||
numeric::bad_numeric_cast );
|
||||
|
||||
unsigned long ul;
|
||||
caught_exception = false;
|
||||
try { ul = numeric_cast<unsigned long>( large_negative_value ); }
|
||||
catch ( numeric::bad_numeric_cast )
|
||||
{ cout<<"caught bad_numeric_cast #3\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
BOOST_TEST_THROWS( numeric_cast<signed char>(large_negative_value),
|
||||
numeric::bad_numeric_cast );
|
||||
|
||||
caught_exception = false;
|
||||
try { ul = numeric_cast<unsigned long>( small_negative_value ); }
|
||||
catch ( numeric::bad_numeric_cast )
|
||||
{ cout<<"caught bad_numeric_cast #4\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
BOOST_TEST_THROWS( numeric_cast<unsigned long>(small_negative_value),
|
||||
numeric::bad_numeric_cast );
|
||||
|
||||
caught_exception = false;
|
||||
try { numeric_cast<int>( DBL_MAX ); }
|
||||
catch ( numeric::bad_numeric_cast )
|
||||
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
BOOST_TEST_THROWS( numeric_cast<int>(DBL_MAX), numeric::bad_numeric_cast );
|
||||
|
||||
return 0 ;
|
||||
return boost::report_errors() ;
|
||||
|
||||
} // main
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
//
|
||||
//! Copyright (c) 2011
|
||||
//! Brandon Kohn
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
//! Define a simple custom number
|
||||
struct Double
|
||||
{
|
||||
Double()
|
||||
: v(0)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
explicit Double( T v )
|
||||
: v(static_cast<double>(v))
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
Double& operator= ( T t )
|
||||
{
|
||||
v = static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator < ( const Double& rhs ) const
|
||||
{
|
||||
return v < rhs.v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator < ( T rhs ) const
|
||||
{
|
||||
return v < static_cast<double>(rhs);
|
||||
}
|
||||
|
||||
template <typename LHS>
|
||||
friend bool operator < ( const LHS& lhs, const Double& rhs )
|
||||
{
|
||||
return lhs < rhs.v;
|
||||
}
|
||||
|
||||
bool operator > ( const Double& rhs ) const
|
||||
{
|
||||
return v > rhs.v;
|
||||
}
|
||||
|
||||
template <typename LHS>
|
||||
friend bool operator > ( const LHS& lhs, const Double& rhs )
|
||||
{
|
||||
return lhs > rhs.v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator > ( T rhs ) const
|
||||
{
|
||||
return v > static_cast<double>(rhs);
|
||||
}
|
||||
|
||||
bool operator == ( const Double& rhs ) const
|
||||
{
|
||||
return v == rhs.v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator == ( T rhs ) const
|
||||
{
|
||||
return v == static_cast<double>(rhs);
|
||||
}
|
||||
|
||||
template <typename LHS>
|
||||
friend bool operator == ( const LHS& lhs, const Double& rhs )
|
||||
{
|
||||
return lhs == rhs.v;
|
||||
}
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return v == 0;
|
||||
}
|
||||
|
||||
Double operator -() const
|
||||
{
|
||||
return Double(-v);
|
||||
}
|
||||
|
||||
Double& operator +=( const Double& t )
|
||||
{
|
||||
v += t.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator +=( T t )
|
||||
{
|
||||
v += static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double& operator -=( const Double& t )
|
||||
{
|
||||
v -= t.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator -=( T t )
|
||||
{
|
||||
v -= static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double& operator *= ( const Double& factor )
|
||||
{
|
||||
v *= factor.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator *=( T t )
|
||||
{
|
||||
v *= static_cast<double>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double& operator /= (const Double& divisor)
|
||||
{
|
||||
v /= divisor.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Double& operator /=( T t )
|
||||
{
|
||||
v /= static_cast<double>(t);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
double v;
|
||||
};
|
||||
|
||||
//! Define numeric_limits for the custom type.
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
class numeric_limits< Double > : public numeric_limits<double>
|
||||
{
|
||||
public:
|
||||
|
||||
//! Limit our Double to a range of +/- 100.0
|
||||
static Double (min)()
|
||||
{
|
||||
return Double(1.e-2);
|
||||
}
|
||||
|
||||
static Double (max)()
|
||||
{
|
||||
return Double(1.e2);
|
||||
}
|
||||
|
||||
static Double epsilon()
|
||||
{
|
||||
return Double( std::numeric_limits<double>::epsilon() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//! Define range checking and overflow policies.
|
||||
namespace custom
|
||||
{
|
||||
//! Define a custom range checker
|
||||
template<typename Traits, typename OverFlowHandler>
|
||||
struct range_checker
|
||||
{
|
||||
typedef typename Traits::argument_type argument_type ;
|
||||
typedef typename Traits::source_type S;
|
||||
typedef typename Traits::target_type T;
|
||||
|
||||
//! Check range of integral types.
|
||||
static boost::numeric::range_check_result out_of_range( argument_type s )
|
||||
{
|
||||
using namespace boost::numeric;
|
||||
if( s > bounds<T>::highest() )
|
||||
return cPosOverflow;
|
||||
else if( s < bounds<T>::lowest() )
|
||||
return cNegOverflow;
|
||||
else
|
||||
return cInRange;
|
||||
}
|
||||
|
||||
static void validate_range ( argument_type s )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_bounded );
|
||||
OverFlowHandler()( out_of_range(s) );
|
||||
}
|
||||
};
|
||||
|
||||
//! Overflow handler
|
||||
struct positive_overflow{};
|
||||
struct negative_overflow{};
|
||||
|
||||
struct overflow_handler
|
||||
{
|
||||
void operator() ( boost::numeric::range_check_result r )
|
||||
{
|
||||
using namespace boost::numeric;
|
||||
if( r == cNegOverflow )
|
||||
throw negative_overflow() ;
|
||||
else if( r == cPosOverflow )
|
||||
throw positive_overflow() ;
|
||||
}
|
||||
};
|
||||
|
||||
//! Define a rounding policy and specialize on the custom type.
|
||||
template<class S>
|
||||
struct Ceil : boost::numeric::Ceil<S>{};
|
||||
|
||||
template<>
|
||||
struct Ceil<Double>
|
||||
{
|
||||
typedef Double source_type;
|
||||
|
||||
typedef Double const& argument_type;
|
||||
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::ceil ;
|
||||
#endif
|
||||
return Double( ceil(s.v) );
|
||||
}
|
||||
|
||||
typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style;
|
||||
};
|
||||
|
||||
//! Define a rounding policy and specialize on the custom type.
|
||||
template<class S>
|
||||
struct Trunc: boost::numeric::Trunc<S>{};
|
||||
|
||||
template<>
|
||||
struct Trunc<Double>
|
||||
{
|
||||
typedef Double source_type;
|
||||
|
||||
typedef Double const& argument_type;
|
||||
|
||||
static source_type nearbyint ( argument_type s )
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::floor;
|
||||
#endif
|
||||
return Double( floor(s.v) );
|
||||
}
|
||||
|
||||
typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style;
|
||||
};
|
||||
}//namespace custom;
|
||||
|
||||
namespace boost { namespace numeric {
|
||||
|
||||
//! Define the numeric_cast_traits specializations on the custom type.
|
||||
template <typename S>
|
||||
struct numeric_cast_traits<Double, S>
|
||||
{
|
||||
typedef custom::overflow_handler overflow_policy;
|
||||
typedef custom::range_checker
|
||||
<
|
||||
boost::numeric::conversion_traits<Double, S>
|
||||
, overflow_policy
|
||||
> range_checking_policy;
|
||||
typedef boost::numeric::Trunc<S> rounding_policy;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct numeric_cast_traits<T, Double>
|
||||
{
|
||||
typedef custom::overflow_handler overflow_policy;
|
||||
typedef custom::range_checker
|
||||
<
|
||||
boost::numeric::conversion_traits<T, Double>
|
||||
, overflow_policy
|
||||
> range_checking_policy;
|
||||
typedef custom::Trunc<Double> rounding_policy;
|
||||
};
|
||||
|
||||
//! Define the conversion from the custom type to built-in types and vice-versa.
|
||||
template<typename T>
|
||||
struct raw_converter< conversion_traits< T, Double > >
|
||||
{
|
||||
static T low_level_convert ( const Double& n )
|
||||
{
|
||||
return static_cast<T>( n.v );
|
||||
}
|
||||
};
|
||||
|
||||
template<typename S>
|
||||
struct raw_converter< conversion_traits< Double, S > >
|
||||
{
|
||||
static Double low_level_convert ( const S& n )
|
||||
{
|
||||
return Double(n);
|
||||
}
|
||||
};
|
||||
}}//namespace boost::numeric;
|
||||
|
||||
#define BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW( CastCode ) \
|
||||
BOOST_TEST_THROWS( CastCode, custom::positive_overflow )
|
||||
/***/
|
||||
|
||||
#define BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW( CastCode ) \
|
||||
BOOST_TEST_THROWS( CastCode, custom::negative_overflow )
|
||||
/***/
|
||||
|
||||
struct test_cast_traits
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(T) const
|
||||
{
|
||||
Double d = boost::numeric_cast<Double>( static_cast<T>(50) );
|
||||
BOOST_TEST( d.v == 50. );
|
||||
T v = boost::numeric_cast<T>( d );
|
||||
BOOST_TEST( v == 50 );
|
||||
}
|
||||
};
|
||||
|
||||
void test_numeric_cast_traits()
|
||||
{
|
||||
typedef boost::mpl::vector
|
||||
<
|
||||
boost::int8_t
|
||||
, boost::uint8_t
|
||||
, boost::int16_t
|
||||
, boost::uint16_t
|
||||
, boost::int32_t
|
||||
, boost::uint32_t
|
||||
#if !defined( BOOST_NO_INT64_T )
|
||||
, boost::int64_t
|
||||
, boost::uint64_t
|
||||
#endif
|
||||
, float
|
||||
, double
|
||||
, long double
|
||||
> types;
|
||||
boost::mpl::for_each<types>( test_cast_traits() );
|
||||
|
||||
//! Check overflow handler.
|
||||
Double d( 56.0 );
|
||||
BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW( d = boost::numeric_cast<Double>( 101 ) );
|
||||
BOOST_TEST( d.v == 56. );
|
||||
BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW( d = boost::numeric_cast<Double>( -101 ) );
|
||||
BOOST_TEST( d.v == 56.);
|
||||
|
||||
//! Check custom round policy.
|
||||
d = 5.9;
|
||||
int five = boost::numeric_cast<int>( d );
|
||||
BOOST_TEST( five == 5 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_numeric_cast_traits();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#undef BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW
|
||||
#undef BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// 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
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "boost/limits.hpp"
|
||||
#include "boost/utility.hpp"
|
||||
|
||||
#include "boost/test/included/test_exec_monitor.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <stdexcept> // std::runtime_error
|
||||
|
||||
// Convenience macros to help with compilers which don't parse
|
||||
// explicit template function instantiations (MSVC6)
|
||||
@@ -118,7 +119,7 @@ class numeric_limits<MyUDT::MyFloat> : public numeric_limits<double>
|
||||
// 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(__BORLANDC__) || defined(__GNUC__)
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || defined(BOOST_BORLANDC) || defined(__GNUC__)
|
||||
namespace std {
|
||||
using MyUDT::floor ;
|
||||
using MyUDT::ceil ;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// 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
|
||||
|
||||
+7
-36
@@ -1,4 +1,4 @@
|
||||
// (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// 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
|
||||
@@ -69,51 +69,22 @@ void test_conv_base( Instance const& conv )
|
||||
{
|
||||
result_type result = converter::convert(source);
|
||||
|
||||
if ( conv.post == c_converted )
|
||||
if (BOOST_TEST_EQ(conv.post, c_converted))
|
||||
{
|
||||
BOOST_CHECK_MESSAGE( result == conv.result,
|
||||
conv.to_string() << printable(source) << ")= " << printable(result) << ". Expected:" << printable(conv.result)
|
||||
) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR( conv.to_string() << printable(source) << ") = " << printable(result)
|
||||
<< ". Expected:" << ( conv.post == c_neg_overflow ? " negative_overflow" : "positive_overflow" )
|
||||
) ;
|
||||
BOOST_TEST_EQ(result, conv.result);
|
||||
}
|
||||
}
|
||||
catch ( boost::numeric::negative_overflow const& )
|
||||
{
|
||||
if ( conv.post == c_neg_overflow )
|
||||
{
|
||||
BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = negative_overflow, as expected" ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR( conv.to_string() << printable(source) << ") = negative_overflow. Expected:" << printable(conv.result) ) ;
|
||||
}
|
||||
{
|
||||
BOOST_TEST_EQ(conv.post, c_neg_overflow);
|
||||
}
|
||||
catch ( boost::numeric::positive_overflow const& )
|
||||
{
|
||||
if ( conv.post == c_pos_overflow )
|
||||
{
|
||||
BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = positive_overflow, as expected" ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR( conv.to_string() << printable(source) << ") = positive_overflow. Expected:" << printable(conv.result) ) ;
|
||||
}
|
||||
BOOST_TEST_EQ(conv.post, c_pos_overflow);
|
||||
}
|
||||
catch ( boost::numeric::bad_numeric_cast const& )
|
||||
{
|
||||
if ( conv.post == c_overflow )
|
||||
{
|
||||
BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = bad_numeric_cast, as expected" ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR( conv.to_string() << printable(source) << ") = bad_numeric_cast. Expected:" << printable(conv.result) ) ;
|
||||
}
|
||||
BOOST_TEST_EQ(conv.post, c_overflow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-14
@@ -1,4 +1,4 @@
|
||||
// (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// 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
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <boost/numeric/conversion/udt_builtin_mixture.hpp>
|
||||
#include <boost/numeric/conversion/is_subranged.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
@@ -258,11 +258,7 @@ struct generate_expected_traits
|
||||
#define TEST_VALUE_FIELD(Name) \
|
||||
typedef typename traits::Name BOOST_PP_CAT(t,Name) ; \
|
||||
typedef typename expected::Name BOOST_PP_CAT(x,Name) ; \
|
||||
BOOST_CHECK_MESSAGE ( ( BOOST_PP_CAT(t,Name)::value == BOOST_PP_CAT(x,Name)::value ) , \
|
||||
"conversion_traits<" << typeid(T).name() << "," << typeid(S).name() \
|
||||
<< ">::" << #Name << " = " << to_string(BOOST_PP_CAT(t,Name)::value) \
|
||||
<< ". Expected: " << to_string(BOOST_PP_CAT(x,Name)::value) \
|
||||
) ;
|
||||
BOOST_TEST( ( BOOST_PP_CAT(t,Name)::value == BOOST_PP_CAT(x,Name)::value ) ) ;
|
||||
|
||||
// This macro generates the code that compares a type field
|
||||
// in numeric::conversion_traits<> with its corresponding field
|
||||
@@ -271,11 +267,7 @@ struct generate_expected_traits
|
||||
#define TEST_TYPE_FIELD(Name) \
|
||||
typedef typename traits::Name BOOST_PP_CAT(t,Name) ; \
|
||||
typedef typename expected::Name BOOST_PP_CAT(x,Name) ; \
|
||||
BOOST_CHECK_MESSAGE ( ( typeid(BOOST_PP_CAT(t,Name)) == typeid(BOOST_PP_CAT(x,Name)) ) , \
|
||||
"conversion_traits<" << typeid(T).name() << "," << typeid(S).name() \
|
||||
<< ">::" << #Name << " = " << typeid(BOOST_PP_CAT(t,Name)).name() \
|
||||
<< ". Expected: " << typeid(BOOST_PP_CAT(x,Name)).name() \
|
||||
) ;
|
||||
BOOST_TEST ( ( typeid(BOOST_PP_CAT(t,Name)) == typeid(BOOST_PP_CAT(x,Name)) ) ) ;
|
||||
|
||||
//
|
||||
// Test core.
|
||||
@@ -329,13 +321,13 @@ void test_traits()
|
||||
test_traits_from( SET_FNTPL_ARG(MyFloat) );
|
||||
}
|
||||
|
||||
int test_main( int, char * [])
|
||||
int main()
|
||||
{
|
||||
std::cout << std::setprecision( std::numeric_limits<long double>::digits10 ) ;
|
||||
|
||||
test_traits();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
+20
-20
@@ -1,4 +1,4 @@
|
||||
// (C) 2005, Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2005, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -16,7 +16,7 @@
|
||||
#include<cmath>
|
||||
|
||||
|
||||
#include "boost/test/included/test_exec_monitor.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include "boost/numeric/conversion/cast.hpp"
|
||||
|
||||
@@ -58,13 +58,13 @@ void simplest_case()
|
||||
//
|
||||
// conversion_traits<>::udt_builtin_mixture works out of the box as long as boost::is_arithmetic<UDT> yields false
|
||||
//
|
||||
BOOST_CHECK( (conversion_traits<double,Double>::udt_builtin_mixture::value == udt_to_builtin) ) ;
|
||||
BOOST_CHECK( (conversion_traits<Double,double>::udt_builtin_mixture::value == builtin_to_udt) ) ;
|
||||
BOOST_CHECK( (conversion_traits<Double,Double>::udt_builtin_mixture::value == udt_to_udt ) ) ;
|
||||
BOOST_TEST( (conversion_traits<double,Double>::udt_builtin_mixture::value == udt_to_builtin) ) ;
|
||||
BOOST_TEST( (conversion_traits<Double,double>::udt_builtin_mixture::value == builtin_to_udt) ) ;
|
||||
BOOST_TEST( (conversion_traits<Double,Double>::udt_builtin_mixture::value == udt_to_udt ) ) ;
|
||||
|
||||
// BY DEFINITION, a conversion from UDT to Builtin is subranged. No attempt is made to actually compare ranges.
|
||||
BOOST_CHECK( (conversion_traits<double,Double>::subranged::value) == true ) ;
|
||||
BOOST_CHECK( (conversion_traits<Double,double>::subranged::value) == false ) ;
|
||||
BOOST_TEST( (conversion_traits<double,Double>::subranged::value) == true ) ;
|
||||
BOOST_TEST( (conversion_traits<Double,double>::subranged::value) == false ) ;
|
||||
|
||||
|
||||
|
||||
@@ -72,18 +72,18 @@ void simplest_case()
|
||||
// Conversions to/from FLOATING types, if already supported by an UDT
|
||||
// are also supported out-of-the-box by converter<> in its default configuration.
|
||||
//
|
||||
BOOST_CHECK( numeric_cast<double>(Dv) == static_cast<double>(Dv) ) ;
|
||||
BOOST_CHECK( numeric_cast<Double>(dv) == static_cast<Double>(dv) ) ;
|
||||
BOOST_TEST( numeric_cast<double>(Dv) == static_cast<double>(Dv) ) ;
|
||||
BOOST_TEST( numeric_cast<Double>(dv) == static_cast<Double>(dv) ) ;
|
||||
|
||||
BOOST_CHECK( numeric_cast<float> (Dv) == static_cast<float> (Dv) ) ;
|
||||
BOOST_CHECK( numeric_cast<Double>(fv) == static_cast<Double>(fv) ) ;
|
||||
BOOST_TEST( numeric_cast<float> (Dv) == static_cast<float> (Dv) ) ;
|
||||
BOOST_TEST( numeric_cast<Double>(fv) == static_cast<Double>(fv) ) ;
|
||||
|
||||
|
||||
//
|
||||
// Range checking is disabled by default if an UDT is either the source or target of the conversion.
|
||||
//
|
||||
BOOST_CHECK( (converter<float,double>::out_of_range(dv) == cPosOverflow) );
|
||||
BOOST_CHECK( (converter<float,Double>::out_of_range(Dv) == cInRange) );
|
||||
BOOST_TEST( (converter<float,double>::out_of_range(dv) == cPosOverflow) );
|
||||
BOOST_TEST( (converter<float,Double>::out_of_range(Dv) == cInRange) );
|
||||
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ Double ceil ( Double v ) { return Double(std::ceil (v.mV)) ; }
|
||||
|
||||
void rounding()
|
||||
{
|
||||
BOOST_CHECK( numeric_cast<int>(Dv) == static_cast<int>(Dv) ) ;
|
||||
BOOST_TEST( numeric_cast<int>(Dv) == static_cast<int>(Dv) ) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ void custom_rounding()
|
||||
>
|
||||
DoubleToIntConverter ;
|
||||
|
||||
BOOST_CHECK( DoubleToIntConverter::convert(Dv) == static_cast<int>(Dv) ) ;
|
||||
BOOST_TEST( DoubleToIntConverter::convert(Dv) == static_cast<int>(Dv) ) ;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -187,8 +187,8 @@ void custom_raw_converter()
|
||||
Int i (12);
|
||||
Float fi(12);
|
||||
|
||||
BOOST_CHECK(numeric_cast<Int> (f).mV == i .mV ) ;
|
||||
BOOST_CHECK(numeric_cast<Float>(i).mV == fi.mV ) ;
|
||||
BOOST_TEST(numeric_cast<Int> (f).mV == i .mV ) ;
|
||||
BOOST_TEST(numeric_cast<Float>(i).mV == fi.mV ) ;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -219,10 +219,10 @@ void custom_raw_converter2()
|
||||
>
|
||||
Float2IntConverter ;
|
||||
|
||||
BOOST_CHECK(Float2IntConverter::convert(f).mV == i .mV ) ;
|
||||
BOOST_TEST(Float2IntConverter::convert(f).mV == i .mV ) ;
|
||||
}
|
||||
|
||||
int test_main( int, char* [] )
|
||||
int main()
|
||||
{
|
||||
cout << setprecision( numeric_limits<long double>::digits10 ) ;
|
||||
|
||||
@@ -232,7 +232,7 @@ int test_main( int, char* [] )
|
||||
custom_raw_converter();
|
||||
custom_raw_converter2();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// (C) Copyright 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "boost/numeric/conversion/converter.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
@@ -292,14 +292,14 @@ void test_udt_conversions_with_custom_range_checking()
|
||||
}
|
||||
|
||||
|
||||
int test_main( int, char* [] )
|
||||
int main()
|
||||
{
|
||||
cout << setprecision( numeric_limits<long double>::digits10 ) ;
|
||||
|
||||
test_udt_conversions_with_defaults();
|
||||
test_udt_conversions_with_custom_range_checking();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user