Revision: 378 Author: alai04 Date: Mon Feb 8 07:24:10 2010 Log: 升级至1.42.0,第四批,libs/目录下h-p子目录 http://code.google.com/p/boost-doc-zh/source/detail?r=378 Added: /trunk/libs/integer/doc/Jamfile.v2 /trunk/libs/integer/doc/html /trunk/libs/integer/doc/html/boost_integer /trunk/libs/integer/doc/html/boost_integer/cstdint.html /trunk/libs/integer/doc/html/boost_integer/history.html /trunk/libs/integer/doc/html/boost_integer/integer.html /trunk/libs/integer/doc/html/boost_integer/log2.html /trunk/libs/integer/doc/html/boost_integer/mask.html /trunk/libs/integer/doc/html/boost_integer/minmax.html /trunk/libs/integer/doc/html/boost_integer/traits.html /trunk/libs/integer/doc/html/index.html /trunk/libs/integer/doc/integer.qbk /trunk/libs/integer/test/Jamfile.v2 /trunk/libs/integer/test/cstdint_include_test.cpp /trunk/libs/integer/test/cstdint_test.cpp /trunk/libs/integer/test/cstdint_test2.cpp /trunk/libs/integer/test/integer_fwd_include_test.cpp /trunk/libs/integer/test/integer_include_test.cpp /trunk/libs/integer/test/integer_mask_include_test.cpp /trunk/libs/integer/test/integer_test.cpp /trunk/libs/integer/test/integer_traits_include_test.cpp /trunk/libs/integer/test/integer_traits_test.cpp /trunk/libs/integer/test/static_log2_include_test.cpp /trunk/libs/integer/test/static_min_max_include_test.cpp /trunk/libs/multi_index/test/Jamfile.v2 /trunk/libs/numeric/conversion/doc/Jamfile.v2 /trunk/libs/numeric/conversion/doc/bounds.qbk /trunk/libs/numeric/conversion/doc/conversion.qbk /trunk/libs/numeric/conversion/doc/conversion_traits.qbk /trunk/libs/numeric/conversion/doc/converter.qbk /trunk/libs/numeric/conversion/doc/converter_policies.qbk /trunk/libs/numeric/conversion/doc/definitions.qbk /trunk/libs/numeric/conversion/doc/numeric_cast.qbk /trunk/libs/numeric/conversion/doc/requirements.qbk /trunk/libs/numeric/conversion/test /trunk/libs/numeric/conversion/test/Jamfile.v2 /trunk/libs/numeric/conversion/test/bounds_test.cpp /trunk/libs/numeric/conversion/test/converter_test.cpp /trunk/libs/numeric/conversion/test/numeric_cast_test.cpp /trunk/libs/numeric/conversion/test/test_helpers.cpp /trunk/libs/numeric/conversion/test/test_helpers2.cpp /trunk/libs/numeric/conversion/test/test_helpers3.cpp /trunk/libs/numeric/conversion/test/traits_test.cpp /trunk/libs/numeric/conversion/test/udt_example_0.cpp /trunk/libs/numeric/conversion/test/udt_support_test.cpp /trunk/libs/optional/doc/Jamfile.v2 /trunk/libs/optional/doc/acknowledgments.qbk /trunk/libs/optional/doc/dependencies.qbk /trunk/libs/optional/doc/development.qbk /trunk/libs/optional/doc/examples.qbk /trunk/libs/optional/doc/implementation_notes.qbk /trunk/libs/optional/doc/optional.qbk /trunk/libs/optional/doc/reference.qbk /trunk/libs/optional/doc/special_cases.qbk /trunk/libs/optional/test /trunk/libs/optional/test/Jamfile.v2 /trunk/libs/optional/test/optional_test.cpp /trunk/libs/optional/test/optional_test_common.cpp /trunk/libs/optional/test/optional_test_fail1.cpp /trunk/libs/optional/test/optional_test_fail2.cpp /trunk/libs/optional/test/optional_test_fail3.cpp /trunk/libs/optional/test/optional_test_fail3a.cpp /trunk/libs/optional/test/optional_test_fail3b.cpp /trunk/libs/optional/test/optional_test_inplace.cpp /trunk/libs/optional/test/optional_test_inplace_fail.cpp /trunk/libs/optional/test/optional_test_inplace_fail2.cpp /trunk/libs/optional/test/optional_test_io.cpp /trunk/libs/optional/test/optional_test_ref.cpp /trunk/libs/optional/test/optional_test_ref_fail1.cpp /trunk/libs/optional/test/optional_test_ref_fail3.cpp /trunk/libs/optional/test/optional_test_ref_fail4.cpp /trunk/libs/optional/test/optional_test_tie.cpp /trunk/libs/program_options/example /trunk/libs/program_options/example/Jamfile.v2 /trunk/libs/program_options/example/custom_syntax.cpp /trunk/libs/program_options/example/first.cpp /trunk/libs/program_options/example/multiple_sources.cfg /trunk/libs/program_options/example/multiple_sources.cpp /trunk/libs/program_options/example/option_groups.cpp /trunk/libs/program_options/example/options_description.cpp /trunk/libs/program_options/example/real.cpp /trunk/libs/program_options/example/regex.cpp /trunk/libs/program_options/example/response_file.cpp /trunk/libs/program_options/example/response_file.rsp /trunk/libs/program_options/test /trunk/libs/program_options/test/Jamfile.v2 /trunk/libs/program_options/test/cmdline_test.cpp /trunk/libs/program_options/test/config_test.cfg /trunk/libs/program_options/test/exception_test.cpp /trunk/libs/program_options/test/minitest.hpp /trunk/libs/program_options/test/options_description_test.cpp /trunk/libs/program_options/test/parsers_test.cpp /trunk/libs/program_options/test/positional_options_test.cpp /trunk/libs/program_options/test/program_options_size_test.py /trunk/libs/program_options/test/required_test.cfg /trunk/libs/program_options/test/required_test.cpp /trunk/libs/program_options/test/split_test.cpp /trunk/libs/program_options/test/test_convert.cpp /trunk/libs/program_options/test/ucs2.txt /trunk/libs/program_options/test/unicode_test.cpp /trunk/libs/program_options/test/unrecognized_test.cpp /trunk/libs/program_options/test/utf8.txt /trunk/libs/program_options/test/variable_map_test.cpp /trunk/libs/program_options/test/winmain.cpp /trunk/libs/program_options/test/winmain.py /trunk/libs/proto/example /trunk/libs/proto/example/Jamfile.v2 /trunk/libs/proto/example/calc1.cpp /trunk/libs/proto/example/calc2.cpp /trunk/libs/proto/example/calc3.cpp /trunk/libs/proto/example/futures.cpp /trunk/libs/proto/example/hello.cpp /trunk/libs/proto/example/lambda.hpp /trunk/libs/proto/example/lazy_vector.cpp /trunk/libs/proto/example/map_assign.cpp /trunk/libs/proto/example/mini_lambda.cpp /trunk/libs/proto/example/mixed.cpp /trunk/libs/proto/example/rgb.cpp /trunk/libs/proto/example/tarray.cpp /trunk/libs/proto/example/vec3.cpp /trunk/libs/proto/example/vector.cpp /trunk/libs/proto/example/virtual_member.cpp /trunk/libs/proto/test /trunk/libs/proto/test/Jamfile.v2 /trunk/libs/proto/test/bug2407.cpp /trunk/libs/proto/test/calculator.cpp /trunk/libs/proto/test/deep_copy.cpp /trunk/libs/proto/test/examples.cpp /trunk/libs/proto/test/lambda.cpp /trunk/libs/proto/test/make_expr.cpp /trunk/libs/proto/test/matches.cpp /trunk/libs/proto/test/mem_ptr.cpp /trunk/libs/proto/test/noinvoke.cpp /trunk/libs/proto/test/proto_fusion.cpp /trunk/libs/proto/test/proto_fusion_s.cpp /trunk/libs/proto/test/toy_spirit.cpp /trunk/libs/proto/test/toy_spirit2.cpp /trunk/libs/python/test/Jamfile.v2 /trunk/libs/python/test/enable_shared_from_this.cpp /trunk/libs/python/test/enable_shared_from_this.py /trunk/libs/python/test/pyrun.py /trunk/libs/python/test/test_overload_resolution.cpp Deleted: /trunk/libs/integer/cstdint.htm /trunk/libs/integer/cstdint_test.cpp /trunk/libs/integer/doc/integer_mask.html /trunk/libs/integer/doc/static_log2.html /trunk/libs/integer/doc/static_min_max.html /trunk/libs/integer/integer.htm /trunk/libs/integer/integer_test.cpp /trunk/libs/integer/integer_traits.html /trunk/libs/integer/integer_traits_test.cpp Modified: /trunk/libs/integer/index.html /trunk/libs/integer/test/integer_mask_test.cpp /trunk/libs/integer/test/static_log2_test.cpp /trunk/libs/integer/test/static_min_max_test.cpp /trunk/libs/iostreams/doc/classes/null.html /trunk/libs/iostreams/doc/functions/filter_test.html /trunk/libs/iostreams/doc/functions/positioning.html /trunk/libs/iostreams/doc/macros/workarounds.html /trunk/libs/iostreams/doc/release_notes.html /trunk/libs/iostreams/example/container_device.hpp /trunk/libs/libraries.htm /trunk/libs/multi_index/doc/reference/ord_indices.html /trunk/libs/multi_index/test/pair_of_ints.hpp /trunk/libs/multi_index/test/test_composite_key.cpp /trunk/libs/multi_index/test/test_key_extractors.cpp /trunk/libs/multi_index/test/test_list_ops.cpp /trunk/libs/multi_index/test/test_modifiers.cpp /trunk/libs/python/test/a_map_indexing_suite.cpp /trunk/libs/python/test/andreas_beyer.cpp /trunk/libs/python/test/andreas_beyer.py /trunk/libs/python/test/args.cpp /trunk/libs/python/test/args.py /trunk/libs/python/test/as_to_python_function.cpp /trunk/libs/python/test/auto_ptr.cpp /trunk/libs/python/test/auto_ptr.py /trunk/libs/python/test/back_reference.cpp /trunk/libs/python/test/back_reference.py /trunk/libs/python/test/bases.cpp /trunk/libs/python/test/ben_scott1.cpp /trunk/libs/python/test/ben_scott1.py /trunk/libs/python/test/bienstman1.cpp /trunk/libs/python/test/bienstman1.py /trunk/libs/python/test/bienstman2.cpp /trunk/libs/python/test/bienstman2.py /trunk/libs/python/test/bienstman3.cpp /trunk/libs/python/test/bienstman3.py /trunk/libs/python/test/bienstman4.cpp /trunk/libs/python/test/bienstman4.py /trunk/libs/python/test/bienstman5.cpp /trunk/libs/python/test/bienstman5.py /trunk/libs/python/test/borrowed.cpp /trunk/libs/python/test/callbacks.cpp /trunk/libs/python/test/callbacks.py /trunk/libs/python/test/cltree.cpp /trunk/libs/python/test/complicated.hpp /trunk/libs/python/test/const_argument.cpp /trunk/libs/python/test/const_argument.py /trunk/libs/python/test/copy_ctor_mutates_rhs.cpp /trunk/libs/python/test/crossmod_exception.py /trunk/libs/python/test/crossmod_exception_a.cpp /trunk/libs/python/test/crossmod_exception_b.cpp /trunk/libs/python/test/crossmod_opaque.py /trunk/libs/python/test/crossmod_opaque_a.cpp /trunk/libs/python/test/crossmod_opaque_b.cpp /trunk/libs/python/test/data_members.cpp /trunk/libs/python/test/data_members.py /trunk/libs/python/test/defaults.cpp /trunk/libs/python/test/defaults.py /trunk/libs/python/test/destroy_test.cpp /trunk/libs/python/test/dict.cpp /trunk/libs/python/test/dict.py /trunk/libs/python/test/docstring.cpp /trunk/libs/python/test/docstring.py /trunk/libs/python/test/enum.cpp /trunk/libs/python/test/enum.py /trunk/libs/python/test/exception_translator.cpp /trunk/libs/python/test/exception_translator.py /trunk/libs/python/test/exec.cpp /trunk/libs/python/test/exec.py /trunk/libs/python/test/extract.cpp /trunk/libs/python/test/extract.py /trunk/libs/python/test/if_else.cpp /trunk/libs/python/test/implicit.cpp /trunk/libs/python/test/implicit.py /trunk/libs/python/test/import_.cpp /trunk/libs/python/test/import_.py /trunk/libs/python/test/indirect_traits_test.cpp /trunk/libs/python/test/injected.cpp /trunk/libs/python/test/injected.py /trunk/libs/python/test/input_iterator.cpp /trunk/libs/python/test/int_map_indexing_suite.cpp /trunk/libs/python/test/iterator.cpp /trunk/libs/python/test/iterator.py /trunk/libs/python/test/keywords.cpp /trunk/libs/python/test/keywords_test.py /trunk/libs/python/test/list.cpp /trunk/libs/python/test/list.py /trunk/libs/python/test/long.cpp /trunk/libs/python/test/long.py /trunk/libs/python/test/m1.cpp /trunk/libs/python/test/m2.cpp /trunk/libs/python/test/map_indexing_suite.cpp /trunk/libs/python/test/map_indexing_suite.py /trunk/libs/python/test/minimal.cpp /trunk/libs/python/test/minimal.py /trunk/libs/python/test/module_tail.cpp /trunk/libs/python/test/multi_arg_constructor.cpp /trunk/libs/python/test/multi_arg_constructor.py /trunk/libs/python/test/nested.cpp /trunk/libs/python/test/nested.py /trunk/libs/python/test/newtest.py /trunk/libs/python/test/numarray_tests.py /trunk/libs/python/test/numeric_tests.py /trunk/libs/python/test/numpy.cpp /trunk/libs/python/test/numpy.py /trunk/libs/python/test/object.cpp /trunk/libs/python/test/object.py /trunk/libs/python/test/object_fail1.cpp /trunk/libs/python/test/object_manager.cpp /trunk/libs/python/test/opaque.cpp /trunk/libs/python/test/opaque.py /trunk/libs/python/test/operators.cpp /trunk/libs/python/test/operators.py /trunk/libs/python/test/operators_wrapper.cpp /trunk/libs/python/test/operators_wrapper.py /trunk/libs/python/test/pickle1.cpp /trunk/libs/python/test/pickle1.py /trunk/libs/python/test/pickle2.cpp /trunk/libs/python/test/pickle2.py /trunk/libs/python/test/pickle3.cpp /trunk/libs/python/test/pickle3.py /trunk/libs/python/test/pickle4.cpp /trunk/libs/python/test/pickle4.py /trunk/libs/python/test/pointee.cpp /trunk/libs/python/test/pointer_type_id_test.cpp /trunk/libs/python/test/pointer_vector.cpp /trunk/libs/python/test/pointer_vector.py /trunk/libs/python/test/polymorphism.cpp /trunk/libs/python/test/polymorphism.py /trunk/libs/python/test/polymorphism2.cpp /trunk/libs/python/test/polymorphism2.py /trunk/libs/python/test/polymorphism2_auto_ptr.cpp /trunk/libs/python/test/polymorphism2_auto_ptr.py /trunk/libs/python/test/printer.py /trunk/libs/python/test/properties.cpp /trunk/libs/python/test/properties.py /trunk/libs/python/test/pytype_function.cpp /trunk/libs/python/test/pytype_function.py /trunk/libs/python/test/raw_ctor.cpp /trunk/libs/python/test/raw_ctor.py /trunk/libs/python/test/raw_pyobject_fail1.cpp /trunk/libs/python/test/raw_pyobject_fail2.cpp /trunk/libs/python/test/register_ptr.cpp /trunk/libs/python/test/register_ptr_test.py /trunk/libs/python/test/result.cpp /trunk/libs/python/test/return_arg.cpp /trunk/libs/python/test/return_arg.py /trunk/libs/python/test/select_arg_to_python_test.cpp /trunk/libs/python/test/select_from_python_test.cpp /trunk/libs/python/test/select_holder.cpp /trunk/libs/python/test/shared_ptr.cpp /trunk/libs/python/test/shared_ptr.py /trunk/libs/python/test/simple_type.hpp /trunk/libs/python/test/slice.cpp /trunk/libs/python/test/slice.py /trunk/libs/python/test/staticmethod.cpp /trunk/libs/python/test/staticmethod.py /trunk/libs/python/test/stl_iterator.cpp /trunk/libs/python/test/stl_iterator.py /trunk/libs/python/test/str.cpp /trunk/libs/python/test/str.py /trunk/libs/python/test/string_literal.cpp /trunk/libs/python/test/test_builtin_converters.cpp /trunk/libs/python/test/test_builtin_converters.py /trunk/libs/python/test/test_class.hpp /trunk/libs/python/test/test_cltree.py /trunk/libs/python/test/test_pointer_adoption.cpp /trunk/libs/python/test/test_pointer_adoption.py /trunk/libs/python/test/tuple.cpp /trunk/libs/python/test/tuple.py /trunk/libs/python/test/upcast.cpp /trunk/libs/python/test/vector_indexing_suite.cpp /trunk/libs/python/test/vector_indexing_suite.py /trunk/libs/python/test/virtual_functions.cpp /trunk/libs/python/test/virtual_functions.py /trunk/libs/python/test/voidptr.cpp /trunk/libs/python/test/voidptr.py /trunk/libs/python/test/wrapper_held_type.cpp /trunk/libs/python/test/wrapper_held_type.py ======================================= --- /dev/null +++ /trunk/libs/integer/doc/Jamfile.v2 Mon Feb 8 07:24:10 2010 @@ -0,0 +1,59 @@ + + +# Copyright John Maddock 2005. Use, modification, and distribution are +# 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) + +using quickbook ; + +xml integer : integer.qbk ; +boostbook standalone + : + integer + : + # HTML options first: + # Use graphics not text for navigation: + <xsl:param>navig.graphics=1 + # How far down we chunk nested sections, basically all of them: + <xsl:param>chunk.section.depth=1 + # Don't put the first section on the same page as the TOC: + <xsl:param>chunk.first.sections=0 + # How far down sections get TOC's + <xsl:param>toc.section.depth=1 + # Max depth in each TOC: + <xsl:param>toc.max.depth=1 + # How far down we go with TOC's + <xsl:param>generate.section.toc.level=4 + # Path for links to Boost: + <xsl:param>boost.root=../../../.. + # Path for libraries index: + <xsl:param>boost.libraries=../../../../libs/libraries.htm + # Use the main Boost stylesheet: + <xsl:param>html.stylesheet=../../../../doc/html/boostbook.css + + # PDF Options: + # TOC Generation: this is needed for FOP-0.9 and later: + <xsl:param>fop1.extensions=0 + # Or enable this if you're using XEP: + <xsl:param>xep.extensions=1+ # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
+ <xsl:param>fop.extensions=0 + # No indent on body text: + <xsl:param>body.start.indent=0pt + # Margin size: + <xsl:param>page.margin.inner=0.5in + # Margin size: + <xsl:param>page.margin.outer=0.5in + # Yes, we want graphics for admonishments: + <xsl:param>admon.graphics=1 + # Set this one for PDF generation *only*: + # default pnd graphics are awful in PDF form, + # better use SVG's instead: + <format>pdf:<xsl:param>admon.graphics.extension=".svg" + <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/+ <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/regex/doc/html
+ ; + +install pdf-install : standalone : <location>. <install-type>PDF ; + + ======================================= --- /dev/null+++ /trunk/libs/integer/doc/html/boost_integer/cstdint.html Mon Feb 8 07:24:10 2010
@@ -0,0 +1,257 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Standard Integer Types</title>+<link rel="stylesheet" href="../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="../index.html" title="Boost.Integer"> +<link rel="up" href="../index.html" title="Boost.Integer"> +<link rel="prev" href="../index.html" title="Boost.Integer"> +<link rel="next" href="traits.html" title="Integer Traits"> +</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/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="traits.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.cstdint"></a><a class="link" href="cstdint.html" title="Standard Integer Types"> Standard Integer Types</a>
+</h2></div></div></div> +<div class="toc"><dl>+<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.overview">Overview</a></span></dt> +<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.rationale"> Rationale</a></span></dt> +<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.ce"> <span class="emphasis"><em>Caveat emptor</em></span></a></span></dt> +<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.exact_width_integer_types">Exact-width
+ integer types</a></span></dt>+<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.minimum_width_integer_types">Minimum-width
+ integer types</a></span></dt>+<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.fastest_minimum_width_integer_types">Fastest
+ minimum-width integer types</a></span></dt>+<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.greatest_width_integer_types">Greatest-width
+ integer types</a></span></dt>+<dt><span class="section"><a href="cstdint.html#boost_integer.cstdint.integer_constant_macros">Integer
+ Constant Macros</a></span></dt> +</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.overview"></a><a class="link" href="cstdint.html#boost_integer.cstdint.overview" title="Overview">Overview</a>
+</h3></div></div></div> +<p>+ The header <code class="literal"><a href="../../../../../boost/cstdint.hpp" target="_top"><boost/cstdint.hpp></a></code> + provides the typedef's useful for writing portable code that requires certain
+ integer widths. All typedef's are in namespace boost. + </p> +<p>+ The specifications for these types are based on the ISO/IEC 9899:1999 C Language + standard header <stdint.h>. The 64-bit types required by the C standard + are <span class="emphasis"><em>not required</em></span> in the boost header, and may not be + supplied for all platforms/compilers, because <code class="literal">long long</code>
+ is not [yet] included in the C++ standard. + </p> +<p>+ See <a href="../../../test/cstdint_test.cpp" target="_top">cstdint_test.cpp</a> for
+ a test program. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.rationale"></a><a class="link" href="cstdint.html#boost_integer.cstdint.rationale" title="Rationale"> Rationale</a>
+</h3></div></div></div> +<p>+ The organization of the Boost.Integer headers and classes is designed to + take advantage of <stdint.h> types from the 1999 C standard without + causing undefined behavior in terms of the 1998 C++ standard. The header + <boost/cstdint.hpp> makes the standard integer types safely available + in namespace <code class="literal">boost</code> without placing any names in namespace + <code class="literal">std</code>. The intension is to complement rather than compete + with the C++ Standard Library. Should some future C++ standard include <stdint.h> + and <cstdint>, then <boost/cstdint.hpp> will continue to function,
+ but will become redundant and may be safely deprecated. + </p> +<p>+ Because these are boost headers, their names conform to boost header naming + conventions rather than C++ Standard Library header naming conventions.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.ce"></a><a class="link" href="cstdint.html#boost_integer.cstdint.ce" title="Caveat emptor"> <span class="emphasis"><em>Caveat emptor</em></span></a>
+</h3></div></div></div> +<p>+ As an implementation artifact, certain C <limits.h> macro names may + possibly be visible to users of <boost/cstdint.hpp>. Don't use these + macros; they are not part of any Boost-specified interface. Use <code class="literal">boost::integer_traits<></code> + or <code class="literal">std::numeric_limits<></code> instead.
+ </p> +<p>+ As another implementation artifact, certain C <stdint.h> typedef names + may possibly be visible in the global namespace to users of <boost/cstdint.hpp>. + Don't use these names, they are not part of any Boost-specified interface. + Use the respective names in namespace <code class="literal">boost</code> instead.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.exact_width_integer_types"></a><a class="link" href="cstdint.html#boost_integer.cstdint.exact_width_integer_types" title="Exact-width integer types">Exact-width
+ integer types</a> +</h3></div></div></div> +<p>+ The typedef <code class="literal">int#_t</code>, with # replaced by the width, designates + a signed integer type of exactly # bits; for example <code class="literal">int8_t</code> + denotes an 8-bit signed integer type. Similarly, the typedef <code class="literal">uint#_t</code>
+ designates an unsigned integer type of exactly # bits. + </p> +<p>+ These types are optional. However, if a platform supports integer types with + widths of 8, 16, 32, 64, or any combination thereof, then <boost/cstdint.hpp>
+ does provide the corresponding typedefs. + </p> +<p>+ The absence of int64_t and uint64_t is indicated by the macro <code class="computeroutput"><span class="identifier">BOOST_NO_INT64_T</span></code>.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.minimum_width_integer_types"></a><a class="link" href="cstdint.html#boost_integer.cstdint.minimum_width_integer_types" title="Minimum-width integer types">Minimum-width
+ integer types</a> +</h3></div></div></div> +<p>+ The typedef <code class="literal">int_least#_t</code>, with # replaced by the width, + designates a signed integer type with a width of at least # bits, such that + no signed integer type with lesser size has at least the specified width. + Thus, <code class="literal">int_least32_t</code> denotes the smallest signed integer + type with a width of at least 32 bits. Similarly, the typedef name <code class="literal">uint_least#_t</code> + designates an unsigned integer type with a width of at least # bits, such + that no unsigned integer type with lesser size has at least the specified
+ width. + </p> +<p>+ The following minimum-width integer types are provided for all platforms:
+ </p> +<div class="itemizedlist"><ul type="disc"> +<li><code class="literal">int_least8_t</code></li> +<li><code class="literal">int_least16_t</code></li> +<li><code class="literal">int_least32_t</code></li> +<li><code class="literal">uint_least8_t</code></li> +<li><code class="literal">uint_least16_t</code></li> +<li><code class="literal">uint_least32_t</code></li> +</ul></div> +<p>+ The following types are available only if, after including <boost/cstdint.hpp>,
+ the macro BOOST_NO_INT64_T is not defined: + </p> +<div class="itemizedlist"><ul type="disc"> +<li><code class="literal">int_least64_t</code></li> +<li><code class="literal">uint_least64_t</code></li> +</ul></div> +<p> + All other minimum-width integer types are optional. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.fastest_minimum_width_integer_types"></a><a class="link" href="cstdint.html#boost_integer.cstdint.fastest_minimum_width_integer_types" title="Fastest minimum-width integer types">Fastest
+ minimum-width integer types</a> +</h3></div></div></div> +<p>+ The typedef <code class="literal">int_fast#_t</code>, with # replaced by the width, + designates the fastest signed integer type with a width of at least # bits. + Similarly, the typedef name <code class="literal">uint_fast#_t</code> designates the
+ fastest unsigned integer type with a width of at least # bits. + </p> +<p>+ There is no guarantee that these types are fastest for all purposes. In any
+ case, however, they satisfy the signedness and width requirements. + </p> +<p>+ The following fastest minimum-width integer types are provided for all platforms:
+ </p> +<div class="itemizedlist"><ul type="disc"> +<li><code class="literal">int_fast8_t</code></li> +<li><code class="literal">int_fast16_t</code></li> +<li><code class="literal">int_fast32_t</code></li> +<li><code class="literal">uint_fast8_t</code></li> +<li><code class="literal">uint_fast16_t</code></li> +<li><code class="literal">uint_fast32_t</code></li> +</ul></div> +<p>+ The following types are available only if, after including <boost/cstdint.hpp>,
+ the macro BOOST_NO_INT64_T is not defined: + </p> +<div class="itemizedlist"><ul type="disc"> +<li><code class="literal">int_fast64_t</code></li> +<li><code class="literal">uint_fast64_t</code></li> +</ul></div> +<p> + All other fastest minimum-width integer types are optional. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.greatest_width_integer_types"></a><a class="link" href="cstdint.html#boost_integer.cstdint.greatest_width_integer_types" title="Greatest-width integer types">Greatest-width
+ integer types</a> +</h3></div></div></div> +<p>+ The typedef <code class="literal">intmax_t </code>designates a signed integer type
+ capable of representing any value of any signed integer type. + </p> +<p>+ The typedef <code class="literal">uintmax_t</code> designates an unsigned integer type
+ capable of representing any value of any unsigned integer type. + </p> +<p> + These types are provided for all platforms. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.cstdint.integer_constant_macros"></a><a class="link" href="cstdint.html#boost_integer.cstdint.integer_constant_macros" title="Integer Constant Macros">Integer
+ Constant Macros</a> +</h3></div></div></div> +<p>+ The following macros are always defined after inclusion of this header, these + allow integer constants of at least the specified width to be declared: INT8_C,
+ UINT8_C, INT16_C, UINT16_C, INT32_C, UINT32_C, INTMAX_C, UINTMAX_C. + </p> +<p>+ The macros INT64_C and UINT64_C are also defined if the the macro BOOST_NO_INT64_T
+ is not defined. + </p> +<p>+ The C99 macro __STDC_CONSTANT_MACROS is also defined as an artifact of the
+ implementation. + </p> +<p> + For example: + </p>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">cstdint</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
++<span class="comment">// Here the constant 0x1FFFFFFFF has the correct suffix applied: +</span><span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uint64_t</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">INT64_C</span><span class="special">(</span><span class="number">0</span><span class="identifier">x1FFFFFFFF</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 © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock<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/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="traits.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +</body> +</html> ======================================= --- /dev/null+++ /trunk/libs/integer/doc/html/boost_integer/history.html Mon Feb 8 07:24:10 2010
@@ -0,0 +1,82 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>History</title>+<link rel="stylesheet" href="../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="../index.html" title="Boost.Integer"> +<link rel="up" href="../index.html" title="Boost.Integer">+<link rel="prev" href="minmax.html" title="Compile time min/max calculation">
+</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="minmax.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a>
+</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.history"></a><a class="link" href="history.html" title="History"> History</a>
+</h2></div></div></div> +<a name="boost_integer.history.1_42_0"></a><h5> +<a name="id786079"></a>+ <a class="link" href="history.html#boost_integer.history.1_42_0">1.42.0</a>
+ </h5> +<div class="itemizedlist"><ul type="disc"> +<li> + Reverted Trunk to release branch state (i.e. a "known good state"). + </li> +<li>+ Fixed issues: <a href="https://svn.boost.org/trac/boost/ticket/653"; target="_top">653</a>, + <a href="https://svn.boost.org/trac/boost/ticket/3084"; target="_top">3084</a>, + <a href="https://svn.boost.org/trac/boost/ticket/3177"; target="_top">3177</a>, + <a href="https://svn.boost.org/trac/boost/ticket/3180"; target="_top">3180</a>, + <a href="https://svn.boost.org/trac/boost/ticket/3548"; target="_top">3568</a>, + <a href="https://svn.boost.org/trac/boost/ticket/3657"; target="_top">3657</a>, + <a href="https://svn.boost.org/trac/boost/ticket/2134"; target="_top">2134</a>.
+ </li> +<li>+ Added long long support to <code class="literal">boost::static_log2</code>, <code class="literal">boost::static_signed_min</code>, + <code class="literal">boost::static_signed_max</code>, <code class="literal">boost::static_unsigned_min</code><code class="literal">boost::static_unsigned_max</code>,
+ when available. + </li> +<li>+ The argument type and the result type of <code class="literal">boost::static_signed_min</code> + etc are now typedef'd. Formerly, they were hardcoded as <code class="literal">unsigned + long</code> and <code class="literal">int</code> respectively. Please, use the provided
+ typedefs in new code (and update old code as soon as possible). + </li> +</ul></div> +<a name="boost_integer.history.1_32_0"></a><h5> +<a name="id786181"></a>+ <a class="link" href="history.html#boost_integer.history.1_32_0">1.32.0</a>
+ </h5> +<div class="itemizedlist"><ul type="disc"><li>+ The argument type and the result type of <code class="literal">boost::static_log2</code> + are now typedef'd. Formerly, they were hardcoded as <code class="literal">unsigned long</code> + and <code class="literal">int</code> respectively. Please, use the provided typedefs
+ in new code (and update old code as soon as possible). + </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 © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock<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="minmax.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a>
+</div> +</body> +</html> ======================================= --- /dev/null+++ /trunk/libs/integer/doc/html/boost_integer/integer.html Mon Feb 8 07:24:10 2010
@@ -0,0 +1,430 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Integer Type Selection</title>+<link rel="stylesheet" href="../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="../index.html" title="Boost.Integer"> +<link rel="up" href="../index.html" title="Boost.Integer"> +<link rel="prev" href="traits.html" title="Integer Traits"> +<link rel="next" href="mask.html" title="Integer Masks"> +</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="traits.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="mask.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.integer"></a><a class="link" href="integer.html" title="Integer Type Selection"> Integer Type Selection</a>
+</h2></div></div></div> +<div class="toc"><dl>+<dt><span class="section"><a href="integer.html#boost_integer.integer.synopsis"> Synopsis</a></span></dt> +<dt><span class="section"><a href="integer.html#boost_integer.integer.easiest"> Easiest-to-Manipulate
+ Types</a></span></dt>+<dt><span class="section"><a href="integer.html#boost_integer.integer.sized"> Sized Types</a></span></dt> +<dt><span class="section"><a href="integer.html#boost_integer.integer.example">Example</a></span></dt> +<dt><span class="section"><a href="integer.html#boost_integer.integer.demonstration_program">Demonstration
+ Program</a></span></dt>+<dt><span class="section"><a href="integer.html#boost_integer.integer.rationale">Rationale</a></span></dt> +<dt><span class="section"><a href="integer.html#boost_integer.integer.alternative">Alternative</a></span></dt> +<dt><span class="section"><a href="integer.html#boost_integer.integer.credits">Credits</a></span></dt>
+</dl></div> +<p>+ The <a href="../../../../../boost/integer.hpp" target="_top"><boost/integer.hpp></a> + type selection templates allow integer types to be selected based on desired + characteristics such as number of bits or maximum value. This facility is particularly
+ useful for solving generic programming problems. + </p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.synopsis"></a><a class="link" href="integer.html#boost_integer.integer.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="comment">// fast integers from least integers+</span> <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">LeastInt</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">int_fast_t</span>
+ <span class="special">{</span>+ <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">type</span><span class="special">;</span>
+ <span class="special">};</span> + + <span class="comment">// signed+</span> <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Bits</span><span class="special">></span>
+ <span class="keyword">struct</span> <span class="identifier">int_t</span> + <span class="special">{</span>+ <span class="comment">/* Member exact may or may not be defined depending upon Bits */</span> + <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">exact</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">least</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="identifier">int_fast_t</span><span class="special"><</span><span class="identifier">least</span><span class="special">>::</span><span class="identifier">fast</span> <span class="identifier">fast</span><span class="special">;</span>
+ <span class="special">};</span> + + <span class="comment">// unsigned+</span> <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Bits</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">uint_t</span>
+ <span class="special">{</span>+ <span class="comment">/* Member exact may or may not be defined depending upon Bits */</span> + <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">exact</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">least</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="identifier">int_fast_t</span><span class="special"><</span><span class="identifier">least</span><span class="special">>::</span><span class="identifier">fast</span> <span class="identifier">fast</span><span class="special">;</span>
+ <span class="special">};</span> + + <span class="comment">// signed+</span> <span class="keyword">template</span><span class="special"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">MaxValue</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">int_max_value_t</span>
+ <span class="special">{</span>+ <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">least</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="identifier">int_fast_t</span><span class="special"><</span><span class="identifier">least</span><span class="special">>::</span><span class="identifier">fast</span> <span class="identifier">fast</span><span class="special">;</span>
+ <span class="special">};</span> ++ <span class="keyword">template</span><span class="special"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">MinValue</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">int_min_value_t</span>
+ <span class="special">{</span>+ <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">least</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="identifier">int_fast_t</span><span class="special"><</span><span class="identifier">least</span><span class="special">>::</span><span class="identifier">fast</span> <span class="identifier">fast</span><span class="special">;</span>
+ <span class="special">};</span> + + <span class="comment">// unsigned+</span> <span class="keyword">template</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">Value</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">uint_value_t</span>
+ <span class="special">{</span>+ <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">least</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="identifier">int_fast_t</span><span class="special"><</span><span class="identifier">least</span><span class="special">>::</span><span class="identifier">fast</span> <span class="identifier">fast</span><span class="special">;</span>
+ <span class="special">};</span> +<span class="special">}</span> <span class="comment">// namespace boost +</span></pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.easiest"></a><a class="link" href="integer.html#boost_integer.integer.easiest" title="Easiest-to-Manipulate Types"> Easiest-to-Manipulate
+ Types</a> +</h3></div></div></div> +<p>+ The <code class="literal">int_fast_t</code> class template maps its input type to the + next-largest type that the processor can manipulate the easiest, or to itself + if the input type is already an easy-to-manipulate type. For instance, processing + a bunch of <code class="literal">char</code> objects may go faster if they were converted + to <code class="literal">int</code> objects before processing. The input type, passed + as the only template parameter, must be a built-in integral type, except + <code class="literal">bool</code>. Unsigned integral types can be used, as well as + signed integral types. The output type is given as the nested type <code class="literal">fast</code>.
+ </p> +<p>+ <span class="bold"><strong>Implementation Notes:</strong></span> By default, the output + type is identical to the input type. Eventually, this code's implementation + should be customized for each platform to give accurate mappings between + the built-in types and the easiest-to-manipulate built-in types. Also, there + is no guarantee that the output type actually is easier to manipulate than
+ the input type. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.sized"></a><a class="link" href="integer.html#boost_integer.integer.sized" title="Sized Types"> Sized Types</a>
+</h3></div></div></div> +<p>+ The <code class="literal">int_t</code>, <code class="literal">uint_t</code>, <code class="literal">int_max_value_t</code>, + <code class="literal">int_min_value_t</code>, and <code class="literal">uint_value_t</code> class + templates find the most appropiate built-in integral type for the given template + parameter. This type is given by the nested type <code class="literal">least</code>. + The easiest-to-manipulate version of that type is given by the nested type + <code class="literal">fast</code>. The following table describes each template's criteria.
+ </p> +<div class="table">+<a name="id781665"></a><p class="title"><b>Table 1. Criteria for the Sized Type Class Templates</b></p> +<div class="table-contents"><table class="table" summary="Criteria for the Sized Type Class Templates">
+<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Class Template + </p> + </th> +<th> + <p> + Template Parameter Mapping + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="literal">boost::int_t<N>::least</code> + </p> + </td> +<td> + <p>+ The smallest, built-in, signed integral type with at least <span class="emphasis"><em>N</em></span> + bits, including the sign bit. The parameter should be a positive number. + A compile-time error results if the parameter is larger than the number
+ of bits in the largest integer type. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">boost::int_t<N>::fast</code> + </p> + </td> +<td> + <p>+ The easiest-to-manipulate, built-in, signed integral type with at least + <span class="emphasis"><em>N</em></span> bits, including the sign bit. The parameter + should be a positive number. A compile-time error results if the parameter + is larger than the number of bits in the largest integer type.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">boost::int_t<N>::exact</code> + </p> + </td> +<td> + <p>+ A built-in, signed integral type with exactly <span class="emphasis"><em>N</em></span> + bits, including the sign bit. The parameter should be a positive number. + Note that the member <span class="emphasis"><em>exact</em></span> is defined <span class="bold"><strong>only</strong></span> if there exists a type with exactly <span class="emphasis"><em>N</em></span>
+ bits. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">boost::uint_t<N>::least</code> + </p> + </td> +<td> + <p>+ The smallest, built-in, unsigned integral type with at least <span class="emphasis"><em>N</em></span> + bits. The parameter should be a positive number. A compile-time error + results if the parameter is larger than the number of bits in the largest
+ integer type. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">boost::uint_t<N>::fast</code> + </p> + </td> +<td> + <p>+ The easiest-to-manipulate, built-in, unsigned integral type with at + least <span class="emphasis"><em>N</em></span> bits. The parameter should be a positive + number. A compile-time error results if the parameter is larger than
+ the number of bits in the largest integer type. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">boost::uint_t<N>::exact</code> + </p> + </td> +<td> + <p>+ A built-in, unsigned integral type with exactly <span class="emphasis"><em>N</em></span> + bits. The parameter should be a positive number. A compile-time error + results if the parameter is larger than the number of bits in the largest + integer type. Note that the member <span class="emphasis"><em>exact</em></span> is defined + <span class="bold"><strong>only</strong></span> if there exists a type with exactly
+ N bits. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="literal">boost::int_max_value_t<V>::last</code>
+ </p> + </td> +<td> + <p>+ The smallest, built-in, signed integral type that can hold all the + values in the inclusive range <span class="emphasis"><em>0 - V</em></span>. The parameter
+ should be a positive number. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="literal">boost::int_max_value_t<V>::fast</code>
+ </p> + </td> +<td> + <p>+ The easiest-to-manipulate, built-in, signed integral type that can + hold all the values in the inclusive range <span class="emphasis"><em>0 - V</em></span>.
+ The parameter should be a positive number. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="literal">boost::int_min_value_t<V>::least</code>
+ </p> + </td> +<td> + <p>+ The smallest, built-in, signed integral type that can hold all the + values in the inclusive range <span class="emphasis"><em>V - 0</em></span>. The parameter
+ should be a negative number. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="literal">boost::int_min_value_t<V>::fast</code>
+ </p> + </td> +<td> + <p>+ The easiest-to-manipulate, built-in, signed integral type that can + hold all the values in the inclusive range <span class="emphasis"><em>V - 0</em></span>.
+ The parameter should be a negative number. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="literal">boost::uint_value_t<V>::least</code>
+ </p> + </td> +<td> + <p>+ The smallest, built-in, unsigned integral type that can hold all positive + values up to and including <span class="emphasis"><em>V</em></span>. The parameter should
+ be a positive number. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="literal">boost::uint_value_t<V>::fast</code>
+ </p> + </td> +<td> + <p>+ The easiest-to-manipulate, built-in, unsigned integral type that can + hold all positive values up to and including <span class="emphasis"><em>V</em></span>.
+ The parameter should be a positive number. + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.example"></a><a class="link" href="integer.html#boost_integer.integer.example" title="Example">Example</a>
+</h3></div></div></div>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">integer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+ +<span class="comment">//... +</span>+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>+ <span class="identifier">boost</span><span class="special">::</span><span class="identifier">int_t</span><span class="special"><</span><span class="number">24</span><span class="special">>::</span><span class="identifier">least</span> <span class="identifier">my_var</span><span class="special">;</span> <span class="comment">// my_var has at least 24-bits
+</span> <span class="comment">//...+</span> <span class="comment">// This one is guarenteed not to be truncated: +</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">int_max_value_t</span><span class="special"><</span><span class="number">1000</span><span class="special">>::</span><span class="identifier">least</span> <span class="identifier">my1000</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
+ <span class="comment">//...+</span> <span class="comment">// This one is guarenteed not to be truncated, and as fast +</span> <span class="comment">// to manipulate as possible, its size may be greater than
+</span> <span class="comment">// that of my1000:+</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">int_max_value_t</span><span class="special"><</span><span class="number">1000</span><span class="special">>::</span><span class="identifier">fast</span> <span class="identifier">my_fast1000</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
+<span class="special">}</span> +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.demonstration_program"></a><a class="link" href="integer.html#boost_integer.integer.demonstration_program" title="Demonstration Program">Demonstration
+ Program</a> +</h3></div></div></div> +<p>+ The program <a href="../../../test/integer_test.cpp" target="_top">integer_test.cpp</a> + is a simplistic demonstration of the results from instantiating various examples
+ of the sized type class templates. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.rationale"></a><a class="link" href="integer.html#boost_integer.integer.rationale" title="Rationale">Rationale</a>
+</h3></div></div></div> +<p>+ The rationale for the design of the templates in this header includes:
+ </p> +<div class="itemizedlist"><ul type="disc"> +<li>+ Avoid recursion because of concern about C++'s limited guaranteed recursion
+ depth (17). + </li> +<li> + Avoid macros on general principles. + </li> +<li> + Try to keep the design as simple as possible. + </li> +</ul></div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.alternative"></a><a class="link" href="integer.html#boost_integer.integer.alternative" title="Alternative">Alternative</a>
+</h3></div></div></div> +<p>+ If the number of bits required is known beforehand, it may be more appropriate + to use the types supplied in <a href="../../../../../boost/cstdint.hpp" target="_top"><boost/cstdint.hpp></a>.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.integer.credits"></a><a class="link" href="integer.html#boost_integer.integer.credits" title="Credits">Credits</a>
+</h3></div></div></div> +<p>+ The author of most of the Boost integer type choosing templates is <a href="http://www.boost.org/people/beman_dawes.html"; target="_top">Beman Dawes</a>. He + gives thanks to Valentin Bonnard and <a href="http://www.boost.org/people/kevlin_henney.htm"; target="_top">Kevlin + Henney</a> for sharing their designs for similar templates. <a href="http://www.boost.org/people/daryle_walker.html"; target="_top">Daryle
+ Walker</a> designed the value-based sized templates. + </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 © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock<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="traits.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="mask.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +</body> +</html> ======================================= --- /dev/null+++ /trunk/libs/integer/doc/html/boost_integer/log2.html Mon Feb 8 07:24:10 2010
@@ -0,0 +1,151 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Compile Time log2 Calculation</title>+<link rel="stylesheet" href="../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="../index.html" title="Boost.Integer"> +<link rel="up" href="../index.html" title="Boost.Integer"> +<link rel="prev" href="mask.html" title="Integer Masks">+<link rel="next" href="minmax.html" title="Compile time min/max calculation">
+</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="mask.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="minmax.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.log2"></a><a class="link" href="log2.html" title="Compile Time log2 Calculation"> Compile Time log2 Calculation</a>
+</h2></div></div></div> +<div class="toc"><dl>+<dt><span class="section"><a href="log2.html#boost_integer.log2.synopsis">Synopsis</a></span></dt> +<dt><span class="section"><a href="log2.html#boost_integer.log2.usage">Usage</a></span></dt> +<dt><span class="section"><a href="log2.html#boost_integer.log2.demonstration_program">Demonstration
+ Program</a></span></dt>+<dt><span class="section"><a href="log2.html#boost_integer.log2.rationale">Rationale</a></span></dt> +<dt><span class="section"><a href="log2.html#boost_integer.log2.credits">Credits</a></span></dt>
+</dl></div> +<p>+ The class template in <a href="../../../../../boost/integer/static_log2.hpp" target="_top"><boost/integer/static_log2.hpp></a> + determines the position of the highest bit in a given value. This facility
+ is useful for solving generic programming problems. + </p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.log2.synopsis"></a><a class="link" href="log2.html#boost_integer.log2.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">typedef</span> <span class="emphasis"><em>implementation-defined</em></span> <span class="identifier">static_log2_argument_type</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined</em></span> <span class="identifier">static_log2_result_type</span><span class="special">;</span>
++ <span class="keyword">template</span> <span class="special"><</span><span class="identifier">static_log2_argument_type</span> <span class="identifier">arg</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">static_log2</span>
+ <span class="special">{</span>+ <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">static_log2_result_type</span> <span class="identifier">value</span> <span class="special">=</span> <span class="emphasis"><em>implementation-defined</em></span><span class="special">;</span>
+ <span class="special">};</span> + ++ <span class="keyword">template</span> <span class="special"><</span> <span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">static_log2</span><span class="special"><</span> <span class="number">0</span> <span class="special">></span>
+ <span class="special">{</span> + <span class="comment">// The logarithm of zero is undefined. +</span> <span class="special">};</span> + + +<span class="special">}</span> <span class="comment">// namespace boost +</span></pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.log2.usage"></a><a class="link" href="log2.html#boost_integer.log2.usage" title="Usage">Usage</a>
+</h3></div></div></div> +<p>+ The <code class="literal">boost::static_log2</code> class template takes one template + parameter, a value of type <code class="literal">static_log2_argument_type</code>. + The template only defines one member, <code class="literal">value</code>, which gives
+ the truncated, base-two logarithm of the template argument. + </p> +<p>+ Since the logarithm of zero, for any base, is undefined, there is a specialization + of <code class="literal">static_log2</code> for a template argument of zero. This specialization + has no members, so an attempt to use the base-two logarithm of zero results
+ in a compile-time error. + </p> +<p> + Note: + </p> +<div class="itemizedlist"><ul type="disc"> +<li>+<code class="literal">static_log2_argument_type</code> is an <span class="emphasis"><em>unsigned integer
+ type</em></span> (C++ standard, 3.9.1p3). + </li> +<li>+<code class="literal">static_log2_result_type</code> is an <span class="emphasis"><em>integer type</em></span>
+ (C++ standard, 3.9.1p7). + </li> +</ul></div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.log2.demonstration_program"></a><a class="link" href="log2.html#boost_integer.log2.demonstration_program" title="Demonstration Program">Demonstration
+ Program</a> +</h3></div></div></div> +<p>+ The program <a href="../../../test/static_log2_test.cpp" target="_top">static_log2_test.cpp</a> + is a simplistic demonstration of the results from instantiating various examples
+ of the binary logarithm class template. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.log2.rationale"></a><a class="link" href="log2.html#boost_integer.log2.rationale" title="Rationale">Rationale</a>
+</h3></div></div></div> +<p>+ The base-two (binary) logarithm, abbreviated lb, function is occasionally + used to give order-estimates of computer algorithms. The truncated logarithm + can be considered the highest power-of-two in a value, which corresponds + to the value's highest set bit (for binary integers). Sometimes the highest-bit + position could be used in generic programming, which requires the position + to be available statically (<span class="emphasis"><em>i.e.</em></span> at compile-time).
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.log2.credits"></a><a class="link" href="log2.html#boost_integer.log2.credits" title="Credits">Credits</a>
+</h3></div></div></div> +<p>+ The original version of the Boost binary logarithm class template was written + by <a href="http://www.boost.org/people/daryle_walker.html"; target="_top">Daryle Walker</a> + and then enhanced by Giovanni Bajo with support for compilers without partial + template specialization. The current version was suggested, together with + a reference implementation, by Vesa Karvonen. Gennaro Prota wrote the actual
+ source file. + </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 © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock<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="mask.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="minmax.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +</body> +</html> ======================================= --- /dev/null+++ /trunk/libs/integer/doc/html/boost_integer/mask.html Mon Feb 8 07:24:10 2010
@@ -0,0 +1,375 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Integer Masks</title>+<link rel="stylesheet" href="../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="../index.html" title="Boost.Integer"> +<link rel="up" href="../index.html" title="Boost.Integer"> +<link rel="prev" href="integer.html" title="Integer Type Selection"> +<link rel="next" href="log2.html" title="Compile Time log2 Calculation"> +</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="integer.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="log2.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.mask"></a><a class="link" href="mask.html" title="Integer Masks"> Integer Masks</a>
+</h2></div></div></div> +<div class="toc"><dl>+<dt><span class="section"><a href="mask.html#boost_integer.mask.overview">Overview</a></span></dt> +<dt><span class="section"><a href="mask.html#boost_integer.mask.synopsis">Synopsis</a></span></dt> +<dt><span class="section"><a href="mask.html#boost_integer.mask.single_bit_mask_class_template">Single
+ Bit-Mask Class Template</a></span></dt>+<dt><span class="section"><a href="mask.html#boost_integer.mask.group_bit_mask_class_template">Group
+ Bit-Mask Class Template</a></span></dt>+<dt><span class="section"><a href="mask.html#boost_integer.mask.implementation_notes">Implementation
+ Notes</a></span></dt>+<dt><span class="section"><a href="mask.html#boost_integer.mask.example">Example</a></span></dt> +<dt><span class="section"><a href="mask.html#boost_integer.mask.demonstration_program">Demonstration
+ Program</a></span></dt>+<dt><span class="section"><a href="mask.html#boost_integer.mask.rationale">Rationale</a></span></dt> +<dt><span class="section"><a href="mask.html#boost_integer.mask.credits">Credits</a></span></dt>
+</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.overview"></a><a class="link" href="mask.html#boost_integer.mask.overview" title="Overview">Overview</a>
+</h3></div></div></div> +<p>+ The class templates in <a href="../../../../../boost/integer/integer_mask.hpp" target="_top"><boost/integer/integer_mask.hpp></a> + provide bit masks for a certain bit position or a contiguous-bit pack of + a certain size. The types of the masking constants come from the <a class="link" href="integer.html" title="Integer Type Selection">integer
+ type selection templates</a> header. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.synopsis"></a><a class="link" href="mask.html#boost_integer.mask.synopsis" title="Synopsis">Synopsis</a>
+</h3></div></div></div>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cstddef</span><span class="special">></span> <span class="comment">// for std::size_t
+</span>+<span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span> ++<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">Bit</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">high_bit_mask_t</span>
+<span class="special">{</span>+ <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">least</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">fast</span><span class="special">;</span>
++ <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">least</span> <span class="identifier">high_bit</span> <span class="special">=</span> <span class="emphasis"><em>implementation-defined</em></span><span class="special">;</span> + <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">fast</span> <span class="identifier">high_bit_fast</span> <span class="special">=</span> <span class="emphasis"><em>implementation-defined</em></span><span class="special">;</span>
++ <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bit_position</span> <span class="special">=</span> <span class="identifier">Bit</span><span class="special">;</span>
+<span class="special">};</span> ++<span class="keyword">template</span> <span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">Bits</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">low_bits_mask_t</span>
+<span class="special">{</span>+ <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">least</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined-type</em></span> <span class="identifier">fast</span><span class="special">;</span>
++ <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">least</span> <span class="identifier">sig_bits</span> <span class="special">=</span> <span class="emphasis"><em>implementation-defined</em></span><span class="special">;</span> + <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">fast</span> <span class="identifier">sig_bits_fast</span> <span class="special">=</span> <span class="emphasis"><em>implementation-defined</em></span><span class="special">;</span>
++ <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bit_count</span> <span class="special">=</span> <span class="identifier">Bits</span><span class="special">;</span>
+<span class="special">};</span> ++<span class="comment">// Specializations for low_bits_mask_t exist for certain bit counts.
+</span> +<span class="special">}</span> <span class="comment">// namespace boost +</span></pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.single_bit_mask_class_template"></a><a class="link" href="mask.html#boost_integer.mask.single_bit_mask_class_template" title="Single Bit-Mask Class Template">Single
+ Bit-Mask Class Template</a> +</h3></div></div></div> +<p>+ The <code class="literal">boost::high_bit_mask_t</code> class template provides constants + for bit masks representing the bit at a certain position. The masks are equivalent + to the value 2<sup>Bit</sup>, where <code class="literal">Bit</code> is the template parameter. + The bit position must be a nonnegative number from zero to <span class="emphasis"><em>Max</em></span>, + where Max is one less than the number of bits supported by the largest unsigned + built-in integral type. The following table describes the members of an instantiation
+ of <code class="literal">high_bit_mask_t</code>. + </p> +<div class="table">+<a name="id782866"></a><p class="title"><b>Table 2. Members of the `boost::high_bit_mask_t` Class Template</b></p> +<div class="table-contents"><table class="table" summary="Members of the `boost::high_bit_mask_t` Class Template">
+<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Member + </p> + </th> +<th> + <p> + Meaning + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="literal">least</code> + </p> + </td> +<td> + <p>+ The smallest, unsigned, built-in type that supports the given bit position.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">fast</code> + </p> + </td> +<td> + <p>+ The easiest-to-manipulate analog of <code class="literal">least</code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">high_bit</code> + </p> + </td> +<td> + <p>+ A <code class="literal">least</code> constant of the value 2<sup>Bit</sup>.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">high_bit_fast</code> + </p> + </td> +<td> + <p>+ A <code class="literal">fast</code> analog of <code class="literal">high_bit</code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">bit_position</code> + </p> + </td> +<td> + <p>+ The value of the template parameter, in case its needed from a renamed
+ instantiation of the class template. + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.group_bit_mask_class_template"></a><a class="link" href="mask.html#boost_integer.mask.group_bit_mask_class_template" title="Group Bit-Mask Class Template">Group
+ Bit-Mask Class Template</a> +</h3></div></div></div> +<p>+ The <code class="literal">boost::low_bits_mask_t</code> class template provides constants + for bit masks equivalent to the value (2<sup>Bits</sup> - 1), where <code class="literal">Bits</code> + is the template parameter. The parameter <code class="literal">Bits</code> must be + a non-negative integer from zero to <span class="emphasis"><em>Max</em></span>, where Max is + the number of bits supported by the largest, unsigned, built-in integral + type. The following table describes the members of <code class="literal">low_bits_mask_t</code>.
+ </p> +<div class="table">+<a name="id783074"></a><p class="title"><b>Table 3. Members of the [^boost::low_bits_mask_t] Class Template</b></p> +<div class="table-contents"><table class="table" summary="Members of the [^boost::low_bits_mask_t] Class Template">
+<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Member + </p> + </th> +<th> + <p> + Meaning + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="literal">least</code> + </p> + </td> +<td> + <p>+ The smallest, unsigned built-in type that supports the given bit count.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">fast</code> + </p> + </td> +<td> + <p>+ The easiest-to-manipulate analog of <code class="literal">least</code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">sig_bits</code> + </p> + </td> +<td> + <p>+ A <code class="literal">least</code> constant of the desired bit-masking value.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">sig_bits_fast</code> + </p> + </td> +<td> + <p>+ A <code class="literal">fast</code> analog of <code class="literal">sig_bits</code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">bit_count</code> + </p> + </td> +<td> + <p>+ The value of the template parameter, in case its needed from a renamed
+ instantiation of the class template. + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.implementation_notes"></a><a class="link" href="mask.html#boost_integer.mask.implementation_notes" title="Implementation Notes">Implementation
+ Notes</a> +</h3></div></div></div> +<p>+ When <code class="literal">Bits</code> is the exact size of a built-in unsigned type, + the implementation has to change to prevent undefined behavior. Therefore, + there are specializations of <code class="literal">low_bits_mask_t</code> at those
+ bit counts. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.example"></a><a class="link" href="mask.html#boost_integer.mask.example" title="Example">Example</a>
+</h3></div></div></div>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">integer</span><span class="special">/</span><span class="identifier">integer_mask</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+ +<span class="comment">//... +</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">high_bit_mask_t</span><span class="special"><</span><span class="number">29</span><span class="special">></span> <span class="identifier">mask1_type</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">low_bits_mask_t</span><span class="special"><</span><span class="number">15</span><span class="special">></span> <span class="identifier">mask2_type</span><span class="special">;</span>
++ <span class="identifier">mask1_type</span><span class="special">::</span><span class="identifier">least</span> <span class="identifier">my_var1</span><span class="special">;</span> + <span class="identifier">mask2_type</span><span class="special">::</span><span class="identifier">fast</span> <span class="identifier">my_var2</span><span class="special">;</span>
+ <span class="comment">//... +</span>+ <span class="identifier">my_var1</span> <span class="special">| =</span> <span class="identifier">mask1_type</span><span class="special">::</span><span class="identifier">high_bit</span><span class="special">;</span> + <span class="identifier">my_var2</span> <span class="special">&=</span> <span class="identifier">mask2_type</span><span class="special">::</span><span class="identifier">sig_bits_fast</span><span class="special">;</span>
+ + <span class="comment">//... +</span><span class="special">}</span> +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.demonstration_program"></a><a class="link" href="mask.html#boost_integer.mask.demonstration_program" title="Demonstration Program">Demonstration
+ Program</a> +</h3></div></div></div> +<p>+ The program <a href="../../../test/integer_mask_test.cpp" target="_top">integer_mask_test.cpp</a> + is a simplistic demonstration of the results from instantiating various examples
+ of the bit mask class templates. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.rationale"></a><a class="link" href="mask.html#boost_integer.mask.rationale" title="Rationale">Rationale</a>
+</h3></div></div></div> +<p>+ The class templates in this header are an extension of the <a class="link" href="integer.html" title="Integer Type Selection">integer + type selection class templates</a>. The new class templates provide the + same sized types, but also convenient masks to use when extracting the highest + or all the significant bits when the containing built-in type contains more + bits. This prevents contamination of values by the higher, unused bits.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.mask.credits"></a><a class="link" href="mask.html#boost_integer.mask.credits" title="Credits">Credits</a>
+</h3></div></div></div> +<p>+ The author of the Boost bit mask class templates is <a href="http://www.boost.org/people/daryle_walker.html"; target="_top">Daryle
+ Walker</a>. + </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 © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock<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="integer.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="log2.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +</body> +</html> ======================================= --- /dev/null+++ /trunk/libs/integer/doc/html/boost_integer/minmax.html Mon Feb 8 07:24:10 2010
@@ -0,0 +1,160 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Compile time min/max calculation</title>+<link rel="stylesheet" href="../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="../index.html" title="Boost.Integer"> +<link rel="up" href="../index.html" title="Boost.Integer"> +<link rel="prev" href="log2.html" title="Compile Time log2 Calculation"> +<link rel="next" href="history.html" title="History"> +</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="log2.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="history.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.minmax"></a><a class="link" href="minmax.html" title="Compile time min/max calculation"> Compile time min/max calculation</a>
+</h2></div></div></div> +<div class="toc"><dl>+<dt><span class="section"><a href="minmax.html#boost_integer.minmax.synopsis">Synopsis</a></span></dt> +<dt><span class="section"><a href="minmax.html#boost_integer.minmax.usage">Usage</a></span></dt> +<dt><span class="section"><a href="minmax.html#boost_integer.minmax.example">Example</a></span></dt> +<dt><span class="section"><a href="minmax.html#boost_integer.minmax.demonstration_program">Demonstration
+ Program</a></span></dt>+<dt><span class="section"><a href="minmax.html#boost_integer.minmax.rationale">Rationale</a></span></dt> +<dt><span class="section"><a href="minmax.html#boost_integer.minmax.credits">Credits</a></span></dt>
+</dl></div> +<p>+ The class templates in <a href="../../../../../boost/integer/static_min_max.hpp" target="_top"><boost/integer/static_min_max.hpp></a> + provide a compile-time evaluation of the minimum or maximum of two integers.
+ These facilities are useful for generic programming problems. + </p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.minmax.synopsis"></a><a class="link" href="minmax.html#boost_integer.minmax.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">typedef</span> <span class="emphasis"><em>implementation-defined</em></span> <span class="identifier">static_min_max_signed_type</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="emphasis"><em>implementation-defined</em></span> <span class="identifier">static_min_max_unsigned_type</span><span class="special">;</span>
++<span class="keyword">template</span> <span class="special"><</span><span class="identifier">static_min_max_signed_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_min_max_signed_type</span> <span class="identifier">Value2</span> <span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">static_signed_min</span><span class="special">;</span>
++<span class="keyword">template</span> <span class="special"><</span><span class="identifier">static_min_max_signed_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_min_max_signed_type</span> <span class="identifier">Value2</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">static_signed_max</span><span class="special">;</span>
++<span class="keyword">template</span> <span class="special"><</span><span class="identifier">static_min_max_unsigned_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_min_max_unsigned_type</span> <span class="identifier">Value2</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">static_unsigned_min</span><span class="special">;</span>
++<span class="keyword">template</span> <span class="special"><</span><span class="identifier">static_min_max_unsigned_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_min_max_unsigned_type</span> <span class="identifier">Value2</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">static_unsigned_max</span><span class="special">;</span>
+ +<span class="special">}</span> +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.minmax.usage"></a><a class="link" href="minmax.html#boost_integer.minmax.usage" title="Usage">Usage</a>
+</h3></div></div></div> +<p>+ The four class templates provide the combinations for finding the minimum + or maximum of two <code class="literal">signed</code> or <code class="literal">unsigned</code> + (<code class="literal">long</code>) parameters, <span class="emphasis"><em>Value1</em></span> and <span class="emphasis"><em>Value2</em></span>, + at compile-time. Each template has a single static data member, <code class="literal">value</code>, + which is set to the respective minimum or maximum of the template's parameters.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.minmax.example"></a><a class="link" href="minmax.html#boost_integer.minmax.example" title="Example">Example</a>
+</h3></div></div></div>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">integer</span><span class="special">/</span><span class="identifier">static_min_max</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
++<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="identifier">AddendSize1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="identifier">AddendSize2</span> <span class="special">></span>
+<span class="keyword">class</span> <span class="identifier">adder</span> +<span class="special">{</span> +<span class="keyword">public</span><span class="special">:</span>+ <span class="keyword">static</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">const</span> <span class="identifier">addend1_size</span> <span class="special">=</span> <span class="identifier">AddendSize1</span><span class="special">;</span> + <span class="keyword">static</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">const</span> <span class="identifier">addend2_size</span> <span class="special">=</span> <span class="identifier">AddendSize2</span><span class="special">;</span> + <span class="keyword">static</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">const</span> <span class="identifier">sum_size</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">static_unsigned_max</span><span class="special"><</span><span class="identifier">AddendSize1</span><span class="special">,</span> <span class="identifier">AddendSize2</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">+</span> <span class="number">1</span><span class="special">;</span>
++ <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">addend1_type</span><span class="special">[</span> <span class="identifier">addend1_size</span> <span class="special">];</span> + <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">addend2_type</span><span class="special">[</span> <span class="identifier">addend2_size</span> <span class="special">];</span> + <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">sum_type</span><span class="special">[</span> <span class="identifier">sum_size</span> <span class="special">];</span>
++ <span class="keyword">void</span> <span class="keyword">operator</span> <span class="special">()(</span> <span class="identifier">addend1_type</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">addend2_type</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a2</span><span class="special">,</span> <span class="identifier">sum_type</span> <span class="special">&</span><span class="identifier">s</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+<span class="special">};</span> + +<span class="comment">//... +</span>+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>+ <span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">a1</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">0</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">3</span> <span class="special">};</span> <span class="comment">// 340 +</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">a2</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">9</span><span class="special">,</span> <span class="number">8</span> <span class="special">};</span> <span class="comment">// 89 +</span> <span class="keyword">int</span> <span class="identifier">s</span><span class="special">[</span> <span class="number">4</span> <span class="special">];</span> + <span class="identifier">adder</span><span class="special"><</span><span class="number">3</span><span class="special">,</span><span class="number">2</span><span class="special">></span> <span class="identifier">obj</span><span class="special">;</span>
++ <span class="identifier">obj</span><span class="special">(</span> <span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="identifier">s</span> <span class="special">);</span> <span class="comment">// 's' should be 429 or { 9, 2, 4, 0 }
+</span> <span class="comment">//... +</span><span class="special">}</span> +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.minmax.demonstration_program"></a><a class="link" href="minmax.html#boost_integer.minmax.demonstration_program" title="Demonstration Program">Demonstration
+ Program</a> +</h3></div></div></div> +<p>+ The program <a href="../../../test/static_min_max_test.cpp" target="_top">static_min_max_test.cpp</a> + is a simplistic demonstration of various comparisons using the compile-time
+ extrema class templates. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.minmax.rationale"></a><a class="link" href="minmax.html#boost_integer.minmax.rationale" title="Rationale">Rationale</a>
+</h3></div></div></div> +<p>+ Sometimes the minimum or maximum of several values needs to be found for + later compile-time processing, <span class="emphasis"><em>e.g.</em></span> for a bound for
+ another class template. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.minmax.credits"></a><a class="link" href="minmax.html#boost_integer.minmax.credits" title="Credits">Credits</a>
+</h3></div></div></div> +<p>+ The author of the Boost compile-time extrema class templates is <a href="http://www.boost.org/people/daryle_walker.html"; target="_top">Daryle
+ Walker</a>. + </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 © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock<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="log2.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="history.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +</body> +</html> ======================================= --- /dev/null+++ /trunk/libs/integer/doc/html/boost_integer/traits.html Mon Feb 8 07:24:10 2010
@@ -0,0 +1,215 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Integer Traits</title>+<link rel="stylesheet" href="../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="../index.html" title="Boost.Integer"> +<link rel="up" href="../index.html" title="Boost.Integer"> +<link rel="prev" href="cstdint.html" title="Standard Integer Types"> +<link rel="next" href="integer.html" title="Integer Type Selection"> +</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="cstdint.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="integer.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.traits"></a><a class="link" href="traits.html" title="Integer Traits"> Integer Traits</a>
+</h2></div></div></div> +<div class="toc"><dl>+<dt><span class="section"><a href="traits.html#boost_integer.traits.motivation">Motivation</a></span></dt> +<dt><span class="section"><a href="traits.html#boost_integer.traits.synopsis">Synopsis</a></span></dt> +<dt><span class="section"><a href="traits.html#boost_integer.traits.description">Description</a></span></dt> +<dt><span class="section"><a href="traits.html#boost_integer.traits.test_program">Test Program</a></span></dt> +<dt><span class="section"><a href="traits.html#boost_integer.traits.acknowledgements">Acknowledgements</a></span></dt>
+</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.traits.motivation"></a><a class="link" href="traits.html#boost_integer.traits.motivation" title="Motivation">Motivation</a>
+</h3></div></div></div> +<p>+ The C++ Standard Library <limits> header supplies a class template + <code class="computeroutput"><span class="identifier">numeric_limits</span><span class="special"><></span></code>
+ with specializations for each fundamental type. + </p> +<p>+ For integer types, the interesting members of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><></span></code> are:
+ </p>+<pre class="programlisting"><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">is_specialized</span><span class="special">;</span> <span class="comment">// Will be true for integer types. +</span><span class="keyword">static</span> <span class="identifier">T</span> <span class="identifier">min</span><span class="special">()</span> <span class="keyword">throw</span><span class="special">();</span> <span class="comment">// Smallest representable value. +</span><span class="keyword">static</span> <span class="identifier">T</span> <span class="identifier">max</span><span class="special">()</span> <span class="keyword">throw</span><span class="special">();</span> <span class="comment">// Largest representable value. +</span><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">digits</span><span class="special">;</span> <span class="comment">// For integers, the number of value bits. +</span><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">digits10</span><span class="special">;</span> <span class="comment">// The number of base 10 digits that can be represented. +</span><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">is_signed</span><span class="special">;</span> <span class="comment">// True if the type is signed. +</span><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">is_integer</span><span class="special">;</span> <span class="comment">// Will be true for all integer types.
+</span></pre> +<p>+ For many uses, these are sufficient. But min() and max() are problematical + because they are not constant expressions (std::5.19), yet some usages require
+ constant expressions. + </p> +<p>+ The template class <code class="literal">integer_traits</code> addresses this problem.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.traits.synopsis"></a><a class="link" href="traits.html#boost_integer.traits.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">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">integer_traits</span> <span class="special">:</span> <span class="keyword">public</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="special">{</span> + <span class="keyword">public</span><span class="special">:</span>+ <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">is_integral</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
+ <span class="comment">//+</span> <span class="comment">// These members are defined only if T is a built-in
+</span> <span class="comment">// integal type: +</span> <span class="comment">//+</span> <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">T</span> <span class="identifier">const_min</span> <span class="special">=</span> <span class="emphasis"><em>implementation-defined</em></span><span class="special">;</span> + <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">T</span> <span class="identifier">const_max</span> <span class="special">=</span> <span class="emphasis"><em>implementation-defined</em></span><span class="special">;</span>
+ <span class="special">};</span> +<span class="special">}</span> +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.traits.description"></a><a class="link" href="traits.html#boost_integer.traits.description" title="Description">Description</a>
+</h3></div></div></div> +<p>+ Template class <code class="literal">integer_traits</code> is derived from <code class="literal">std::numeric_limits</code>. + The primary specialization adds the single <code class="literal">bool</code> member + <code class="literal">is_integral</code> with the compile-time constant value <code class="literal">false</code>. + However, for all integral types <code class="literal">T</code> (std::3.9.1/7 [basic.fundamental]), + there are specializations provided with the following compile-time constants
+ defined: + </p> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + member + </p> + </th> +<th> + <p> + type + </p> + </th> +<th> + <p> + value + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="literal">is_integral</code> + </p> + </td> +<td> + <p> + bool + </p> + </td> +<td> + <p> + <code class="literal">true</code> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">const_min</code> + </p> + </td> +<td> + <p> + <code class="literal">T</code> + </p> + </td> +<td> + <p>+ equivalent to <code class="literal">std::numeric_limits<T>::min()</code>
+ </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">const_max</code> + </p> + </td> +<td> + <p> + <code class="literal">T</code> + </p> + </td> +<td> + <p>+ equivalent to <code class="literal">std::numeric_limits<T>::max()</code>
+ </p> + </td> +</tr> +</tbody> +</table></div> +<p>+ Note: The <span class="emphasis"><em>is_integral</em></span> flag is provided, because a user-defined + integer class should specialize <code class="literal">std::numeric_limits<>::is_integer + = true</code>, while compile-time constants <code class="literal">const_min</code> + and <code class="literal">const_max</code> are not provided for that user-defined class,
+ unless boost::integer_traits is also specialized. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.traits.test_program"></a><a class="link" href="traits.html#boost_integer.traits.test_program" title="Test Program">Test Program</a>
+</h3></div></div></div> +<p>+ The program <code class="literal"><a href="../../../test/integer_traits_test.cpp" target="_top">integer_traits_test.cpp</a></code>
+ exercises the <code class="literal">integer_traits</code> class. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_integer.traits.acknowledgements"></a><a class="link" href="traits.html#boost_integer.traits.acknowledgements" title="Acknowledgements">Acknowledgements</a>
+</h3></div></div></div> +<p>+ Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers discussed the integer
+ traits idea on the boost mailing list in August 1999. + </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 © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock<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="cstdint.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="integer.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div> +</body> +</html> ======================================= --- /dev/null +++ /trunk/libs/integer/doc/html/index.html Mon Feb 8 07:24:10 2010 @@ -0,0 +1,246 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Boost.Integer</title>+<link rel="stylesheet" href="../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> +<link rel="home" href="index.html" title="Boost.Integer">+<link rel="next" href="boost_integer/cstdint.html" title="Standard Integer Types">
+</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_integer/cstdint.html"><img src="../../../../doc/html/images/next.png" alt="Next"></a></div>
+<div class="article" lang="en"> +<div class="titlepage"> +<div> +<div><h2 class="title"> +<a name="boost_integer"></a>Boost.Integer</h2></div> +<div><div class="authorgroup"> +<div class="author"><h3 class="author"> +<span class="firstname">Beman</span> <span class="surname">Dawes</span> +</h3></div> +<div class="author"><h3 class="author"> +<span class="firstname">Daryle</span> <span class="surname">Walker</span> +</h3></div> +<div class="author"><h3 class="author"> +<span class="firstname">Gennaro</span> <span class="surname">Prota</span> +</h3></div> +<div class="author"><h3 class="author"> +<span class="firstname">John</span> <span class="surname">Maddock</span> +</h3></div> +</div></div>+<div><p class="copyright">Copyright © 2001 -2009 Beman Dawes, Daryle Walker, Gennaro Prota,
+ John Maddock</p></div> +<div><div class="legalnotice"> +<a name="id771218"></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> +<hr> +</div> +<div class="toc"> +<p><b>Table of Contents</b></p> +<dl>+<dt><span class="section"><a href="index.html#boost_integer.overview"> Overview</a></span></dt> +<dt><span class="section"><a href="boost_integer/cstdint.html"> Standard Integer Types</a></span></dt> +<dt><span class="section"><a href="boost_integer/traits.html"> Integer Traits</a></span></dt> +<dt><span class="section"><a href="boost_integer/integer.html"> Integer Type Selection</a></span></dt> +<dt><span class="section"><a href="boost_integer/mask.html"> Integer Masks</a></span></dt> +<dt><span class="section"><a href="boost_integer/log2.html"> Compile Time log2 Calculation</a></span></dt> +<dt><span class="section"><a href="boost_integer/minmax.html"> Compile time min/max calculation</a></span></dt> +<dt><span class="section"><a href="boost_integer/history.html"> History</a></span></dt>
+</dl> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_integer.overview"></a><a class="link" href="index.html#boost_integer.overview" title="Overview"> Overview</a>
+</h2></div></div></div> +<p>+ Boost.Integer provides integer type support, particularly helpful in generic + programming. It provides standard C99 integer types, such as might be found + in <stdint.h>, without requiring that header. It provides the means to + select an integer type based upon its properties, like the number of bits or + the maximum supported value, as well as compile-time bit mask selection. There + is a derivative of std::numeric_limits that provides integral constant expressions + for <code class="computeroutput"><span class="identifier">min</span></code> and <code class="computeroutput"><span class="identifier">max</span></code>. + Finally, it provides two compile-time algorithms: determining the highest power + of two in a compile-time value; and computing min and max of constant expressions.
+ </p> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Component + </p> + </th> +<th> + <p> + Header + </p> + </th> +<th> + <p> + Purpose + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + Forward Declarations. + </p> + </td> +<td> + <p>+ <code class="literal"><a href="../../../../boost/integer_fwd.hpp" target="_top"><boost/integer_fwd.hpp></a></code>
+ </p> + </td> +<td> + <p>+ Forward declarations of classes and class templates - for use when
+ just the name of a class is needed. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <a class="link" href="boost_integer/cstdint.html" title="Standard Integer Types">Standard Integer Types</a>.
+ </p> + </td> +<td> + <p>+ <code class="literal"><a href="../../../../boost/cstdint.hpp" target="_top"><boost/cstdint.hpp></a></code>
+ </p> + </td> +<td> + <p>+ Provides typedef's based on the 1999 C Standard header <code class="computeroutput"><span class="special"><</span><span class="identifier">stdint</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span></code>, wrapped in namespace boost. This + implementation may #include the compiler supplied <code class="computeroutput"><span class="special"><</span><span class="identifier">stdint</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span></code>,
+ if present. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <a class="link" href="boost_integer/traits.html" title="Integer Traits">Integer Traits</a>.
+ </p> + </td> +<td> + <p>+ <code class="literal"><a href="../../../../boost/integer_traits.hpp" target="_top"><boost/integer_traits.hpp></a></code>
+ </p> + </td> +<td> + <p>+ Class template <code class="literal">boost::integer_traits</code>, derives from + <code class="literal">std::numeric_limits</code> and adds <code class="literal">const_min</code>
+ and <code class="literal">const_max</code> members. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <a class="link" href="boost_integer/integer.html" title="Integer Type Selection">Integer Type Selection</a>.
+ </p> + </td> +<td> + <p>+ <code class="literal"><a href="../../../../boost/hpp" target="_top"><boost/integer.hpp></a></code>
+ </p> + </td> +<td> + <p>+ Templates for integer type selection based on properties such as maximum + value or number of bits: Use to select the type of an integer when + some property such as maximum value or number of bits is known. Useful
+ for generic programming. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <a class="link" href="boost_integer/mask.html" title="Integer Masks">Integer Masks</a>.
+ </p> + </td> +<td> + <p>+ <code class="literal"><a href="../../../../boost/integer/integer_mask.hpp" target="_top"><boost/integer/integer_mask.hpp></a></code>
+ </p> + </td> +<td> + <p>+ Templates for the selection of integer masks, single or lowest group, + based on the number of bits: Use to select a particular mask when the + bit position(s) are based on a compile-time variable. Useful for generic
+ programming. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <a class="link" href="boost_integer/log2.html" title="Compile Time log2 Calculation">Compile time log2 Calculation</a>.
+ </p> + </td> +<td> + <p>+ <code class="literal"><a href="../../../../boost/integer/static_log2.hpp" target="_top"><boost/integer/static_log2.hpp></a></code>
+ </p> + </td> +<td> + <p>+ Template for finding the highest power of two in a number: Use to find + the bit-size/range based on a maximum value. Useful for generic programming.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <a class="link" href="boost_integer/minmax.html" title="Compile time min/max calculation">Compile time min/max calculation</a>.
+ </p> + </td> +<td> + <p>+ <code class="literal"><a href="../../../../boost/integer/static_min_max.hpp" target="_top"><boost/integer/static_min_max.hpp></a></code>
+ </p> + </td> +<td> + <p>+ Templates for finding the extrema of two numbers: Use to find a bound + based on a minimum or maximum value. Useful for generic programming.
+ </p> + </td> +</tr> +</tbody> +</table></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: December 11, 2009 at 17:54:58 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_integer/cstdint.html"><img src="../../../../doc/html/images/next.png" alt="Next"></a></div>
+</body> +</html> ======================================= --- /dev/null +++ /trunk/libs/integer/doc/integer.qbk Mon Feb 8 07:24:10 2010 @@ -0,0 +1,840 @@ +[article Boost.Integer + [quickbook 1.5]+ [copyright 2001-2009 Beman Dawes, Daryle Walker, Gennaro Prota, John Maddock]
+ [purpose Integer Type Selection] + [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]) + ]+ [authors [Dawes, Beman], [Walker, Daryle], [Prota, Gennaro], [Maddock, John]]
+ [/last-revision $Date: 2008-02-21 12:58:15 +0000 (Thu, 21 Feb 2008) $] +] + +[template super[x]'''<superscript>'''[x]'''</superscript>'''] + +[section:overview Overview] ++Boost.Integer provides integer type support, particularly helpful in generic programming. It provides standard +C99 integer types, such as might be found in <stdint.h>, without requiring that header. +It provides the means to select an integer type based upon its properties, like the number of bits or +the maximum supported value, as well as compile-time bit mask selection. There is a derivative of +std::numeric_limits that provides integral constant expressions for `min` and `max`. +Finally, it provides two compile-time algorithms: determining the highest power of two in a
+compile-time value; and computing min and max of constant expressions. + +[table + [[Component][Header][Purpose]] + [ + [Forward Declarations.] + [[^[@../../../../boost/integer_fwd.hpp <boost/integer_fwd.hpp>]]]+ [Forward declarations of classes and class templates - for use when just the name of a class is needed.]
+ ] + [ + [[link boost_integer.cstdint Standard Integer Types].] + [[^[@../../../../boost/cstdint.hpp <boost/cstdint.hpp>]]]+ [Provides typedef's based on the 1999 C Standard header `<stdint.h>`, wrapped in namespace boost. + This implementation may #include the compiler supplied `<stdint.h>`, if present.]
+ ] + [ + [[link boost_integer.traits Integer Traits].]+ [[^[@../../../../boost/integer_traits.hpp <boost/integer_traits.hpp>]]] + [Class template [^boost::integer_traits], derives from [^std::numeric_limits] and adds [^const_min] and [^const_max] members.]
+ ] + [ + [[link boost_integer.integer Integer Type Selection].] + [[^[@../../../../boost/hpp <boost/integer.hpp>]]]+ [Templates for integer type selection based on properties such as maximum value or number of bits: + Use to select the type of an integer when some property such as maximum value or number of bits is known.
+ Useful for generic programming. ] + ] + [ + [[link boost_integer.mask Integer Masks].]+ [[^[@../../../../boost/integer/integer_mask.hpp <boost/integer/integer_mask.hpp>]]] + [Templates for the selection of integer masks, single or lowest group, based on the number of bits: + Use to select a particular mask when the bit position(s) are based on a compile-time variable. Useful for generic programming. ]
+ ] + [ + [[link boost_integer.log2 Compile time log2 Calculation].]+ [[^[@../../../../boost/integer/static_log2.hpp <boost/integer/static_log2.hpp>]]]
+ [Template for finding the highest power of two in a number:+ Use to find the bit-size/range based on a maximum value. Useful for generic programming. ]
+ ] + [ + [[link boost_integer.minmax Compile time min/max calculation].]+ [[^[@../../../../boost/integer/static_min_max.hpp <boost/integer/static_min_max.hpp>]]]
+ [Templates for finding the extrema of two numbers:+ Use to find a bound based on a minimum or maximum value. Useful for generic programming. ]
+ ] +] + +[endsect] + +[section:cstdint Standard Integer Types] + +[section Overview] ++The header [^[@../../../../boost/cstdint.hpp <boost/cstdint.hpp>]] provides the typedef's useful +for writing portable code that requires certain integer widths. All typedef's are in namespace boost.
++The specifications for these types are based on the ISO/IEC 9899:1999 C Language standard header <stdint.h>. +The 64-bit types required by the C standard are ['not required] in the boost header, +and may not be supplied for all platforms/compilers, because [^long long] is not [yet] included in the C++ standard.
+ +See [@../../test/cstdint_test.cpp cstdint_test.cpp] for a test program. + +[endsect] + +[section:rationale Rationale] ++The organization of the Boost.Integer headers and classes is designed to take advantage of <stdint.h> types from the +1999 C standard without causing undefined behavior in terms of the 1998 C++ standard. +The header <boost/cstdint.hpp> makes the standard integer types safely available in namespace [^boost] +without placing any names in namespace [^std]. The intension is to complement rather than compete +with the C++ Standard Library. Should some future C++ standard include <stdint.h> and <cstdint>, +then <boost/cstdint.hpp> will continue to function, but will become redundant and may be safely deprecated.
++Because these are boost headers, their names conform to boost header naming conventions rather than
+C++ Standard Library header naming conventions. + +[endsect] + +[section:ce ['Caveat emptor]] ++As an implementation artifact, certain C <limits.h> macro names may possibly be +visible to users of <boost/cstdint.hpp>. Don't use these macros; they are not part of +any Boost-specified interface. Use [^boost::integer_traits<>] or [^std::numeric_limits<>] instead.
++As another implementation artifact, certain C <stdint.h> typedef names may possibly be visible +in the global namespace to users of <boost/cstdint.hpp>. Don't use these names, they are not part of +any Boost-specified interface. Use the respective names in namespace [^boost] instead.
+ +[endsect] + +[section Exact-width integer types] ++The typedef [^int#_t], with # replaced by the width, designates a signed integer type of exactly # bits; +for example [^int8_t] denotes an 8-bit signed integer type. Similarly, the typedef [^uint#_t] designates an unsigned
+integer type of exactly # bits. ++These types are optional. However, if a platform supports integer types with widths of +8, 16, 32, 64, or any combination thereof, then <boost/cstdint.hpp> does provide the
+corresponding typedefs. ++The absence of int64_t and uint64_t is indicated by the macro `BOOST_NO_INT64_T`.
+ +[endsect] + +[section Minimum-width integer types] ++The typedef [^int_least#_t], with # replaced by the width, designates a signed integer type with a width +of at least # bits, such that no signed integer type with lesser size has at least the specified width. +Thus, [^int_least32_t] denotes the smallest signed integer type with a width of at least 32 bits. +Similarly, the typedef name [^uint_least#_t] designates an unsigned integer type with a width of at least # bits, +such that no unsigned integer type with lesser size has at least the specified width.
+ +The following minimum-width integer types are provided for all platforms: + +* [^int_least8_t] +* [^int_least16_t] +* [^int_least32_t] +* [^uint_least8_t] +* [^uint_least16_t] +* [^uint_least32_t] ++The following types are available only if, after including <boost/cstdint.hpp>, the macro BOOST_NO_INT64_T is not defined:
+ +* [^int_least64_t] +* [^uint_least64_t] + + +All other minimum-width integer types are optional. + +[endsect] + +[section Fastest minimum-width integer types] ++The typedef [^int_fast#_t], with # replaced by the width, designates the fastest signed integer type +with a width of at least # bits. Similarly, the typedef name [^uint_fast#_t] designates the fastest
+unsigned integer type with a width of at least # bits. ++There is no guarantee that these types are fastest for all purposes. In any case, however, they satisfy
+the signedness and width requirements. ++The following fastest minimum-width integer types are provided for all platforms:
+ +* [^int_fast8_t] +* [^int_fast16_t] +* [^int_fast32_t] +* [^uint_fast8_t] +* [^uint_fast16_t] +* [^uint_fast32_t] ++The following types are available only if, after including <boost/cstdint.hpp>, the macro BOOST_NO_INT64_T is not defined:
+ +* [^int_fast64_t] +* [^uint_fast64_t] + +All other fastest minimum-width integer types are optional. + +[endsect] + +[section Greatest-width integer types] ++The typedef [^intmax_t ]designates a signed integer type capable of representing any value of any signed integer type.
++The typedef [^uintmax_t] designates an unsigned integer type capable of representing any value of any unsigned integer type.
+ +These types are provided for all platforms. + +[endsect] + +[section Integer Constant Macros] ++The following macros are always defined after inclusion of this header, these allow
+integer constants of at least the specified width to be declared: +INT8_C, UINT8_C, INT16_C, UINT16_C, INT32_C, UINT32_C, INTMAX_C, UINTMAX_C. ++The macros INT64_C and UINT64_C are also defined if the the macro BOOST_NO_INT64_T is not defined.
++The C99 macro __STDC_CONSTANT_MACROS is also defined as an artifact of the implementation.
+ +For example: + + #include <boost/cstdint.hpp> + + // Here the constant 0x1FFFFFFFF has the correct suffix applied: + static const boost::uint64_t c = INT64_C(0x1FFFFFFFF); + +[endsect] + +[endsect] + +[section:traits Integer Traits] + +[section Motivation] ++The C++ Standard Library <limits> header supplies a class template `numeric_limits<>` with specializations for each fundamental type.
+ +For integer types, the interesting members of `std::numeric_limits<>` are: ++ static const bool is_specialized; // Will be true for integer types.
+ static T min() throw(); // Smallest representable value. + static T max() throw(); // Largest representable value.+ static const int digits; // For integers, the number of value bits. + static const int digits10; // The number of base 10 digits that can be represented.
+ static const bool is_signed; // True if the type is signed.+ static const bool is_integer; // Will be true for all integer types.
+ +For many uses, these are sufficient.+But min() and max() are problematical because they are not constant expressions (std::5.19),
+yet some usages require constant expressions. + +The template class [^integer_traits] addresses this problem. + +[endsect] + +[section Synopsis] + + namespace boost { + template<class T> + class integer_traits : public std::numeric_limits<T> + { + public: + static const bool is_integral = false; + // + // These members are defined only if T is a built-in + // integal type: + // + static const T const_min = ``['implementation-defined]``; + static const T const_max = ``['implementation-defined]``; + }; + } + +[endsect] + +[section Description] ++Template class [^integer_traits] is derived from [^std::numeric_limits]. The primary specialization adds the single +[^bool] member [^is_integral] with the compile-time constant value [^false]. +However, for all integral types [^T] (std::3.9.1/7 [basic.fundamental]), there are specializations
+provided with the following compile-time constants defined: + +[table + [[member][type][value]] + [[[^is_integral]][bool][[^true]]] + [[[^const_min]][[^T]][equivalent to [^std::numeric_limits<T>::min()]]] + [[[^const_max]][[^T]][equivalent to [^std::numeric_limits<T>::max()]]] +] ++Note: The /is_integral/ flag is provided, because a user-defined integer class should specialize
+[^std::numeric_limits<>::is_integer = true], while compile-time constants+[^const_min] and [^const_max] are not provided for that user-defined class, unless boost::integer_traits is also specialized.
+ +[endsect] + +[section Test Program] ++The program [^[@../../test/integer_traits_test.cpp integer_traits_test.cpp]] exercises the [^integer_traits] class.
+ +[endsect] + +[section Acknowledgements] ++Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers discussed the integer traits idea on the boost mailing list in August 1999.
+ +[endsect] +[endsect] + +[section:integer Integer Type Selection] ++The [@../../../../boost/integer.hpp <boost/integer.hpp>] type selection templates allow +integer types to be selected based on desired characteristics such as number of bits or maximum value. +This facility is particularly useful for solving generic programming problems.
+ +[section:synopsis Synopsis] + + namespace boost + { + // fast integers from least integers + template<typename LeastInt> + struct int_fast_t + { + typedef ``['implementation-defined-type]`` type; + }; + + // signed + template<int Bits> + struct int_t + { + /* Member exact may or may not be defined depending upon Bits */ + typedef ``['implementation-defined-type]`` exact; + typedef ``['implementation-defined-type]`` least; + typedef int_fast_t<least>::fast fast; + }; + + // unsigned + template<int Bits> + struct uint_t + { + /* Member exact may or may not be defined depending upon Bits */ + typedef ``['implementation-defined-type]`` exact; + typedef ``['implementation-defined-type]`` least; + typedef int_fast_t<least>::fast fast; + }; + + // signed + template<long long MaxValue> + struct int_max_value_t + { + typedef ``['implementation-defined-type]`` least; + typedef int_fast_t<least>::fast fast; + }; + + template<long long MinValue> + struct int_min_value_t + { + typedef ``['implementation-defined-type]`` least; + typedef int_fast_t<least>::fast fast; + }; + + // unsigned + template<unsigned long long Value> + struct uint_value_t + { + typedef ``['implementation-defined-type]`` least; + typedef int_fast_t<least>::fast fast; + }; + } // namespace boost + +[endsect] + +[section:easiest Easiest-to-Manipulate Types] ++The [^int_fast_t] class template maps its input type to the next-largest type that the processor +can manipulate the easiest, or to itself if the input type is already an easy-to-manipulate type. +For instance, processing a bunch of [^char] objects may go faster if they were converted to [^int] objects before processing. +The input type, passed as the only template parameter, must be a built-in integral type, except [^bool].
+Unsigned integral types can be used, as well as signed integral types. +The output type is given as the nested type [^fast]. + +[*Implementation Notes:]+By default, the output type is identical to the input type. Eventually, this code's implementation should +be customized for each platform to give accurate mappings between the built-in types and the easiest-to-manipulate +built-in types. Also, there is no guarantee that the output type actually is easier to manipulate than the input type.
+ +[endsect] + +[section:sized Sized Types] ++The [^int_t], [^uint_t], [^int_max_value_t], [^int_min_value_t], and [^uint_value_t] class templates find +the most appropiate built-in integral type for the given template parameter. This type is given by the +nested type [^least]. The easiest-to-manipulate version of that type is given by the nested type [^fast].
+The following table describes each template's criteria. + +[table Criteria for the Sized Type Class Templates + [ + [Class Template][Template Parameter Mapping] + ] + [ + [[^boost::int_t<N>::least]]+ [The smallest, built-in, signed integral type with at least /N/ bits, including the sign bit. + The parameter should be a positive number. A compile-time error results if the parameter is
+ larger than the number of bits in the largest integer type.] + ] + [ + [[^boost::int_t<N>::fast]]+ [The easiest-to-manipulate, built-in, signed integral type with at least /N/ bits, including the sign bit. + The parameter should be a positive number. A compile-time error results if the parameter is
+ larger than the number of bits in the largest integer type.] + ] + [ + [[^boost::int_t<N>::exact]]+ [A built-in, signed integral type with exactly /N/ bits, including the sign bit. + The parameter should be a positive number. Note that the member /exact/ is defined
+ [*only] if there exists a type with exactly /N/ bits.] + ] + [ + [[^boost::uint_t<N>::least]]+ [The smallest, built-in, unsigned integral type with at least /N/ bits. + The parameter should be a positive number. A compile-time error results if the + parameter is larger than the number of bits in the largest integer type.]
+ ] + [ + [[^boost::uint_t<N>::fast]]+ [The easiest-to-manipulate, built-in, unsigned integral type with at least /N/ bits. + The parameter should be a positive number. A compile-time error results if the + parameter is larger than the number of bits in the largest integer type.]
+ ] + [ + [[^boost::uint_t<N>::exact]] + [A built-in, unsigned integral type with exactly /N/ bits.+ The parameter should be a positive number. A compile-time error results if the + parameter is larger than the number of bits in the largest integer type.
+ Note that the member /exact/ is defined + [*only] if there exists a type with exactly N bits.] + ] + [ + [[^boost::int_max_value_t<V>::last]]+ [The smallest, built-in, signed integral type that can hold all the values in the inclusive range ['0 - V].
+ The parameter should be a positive number.] + ] + [ + [[^boost::int_max_value_t<V>::fast]]+ [The easiest-to-manipulate, built-in, signed integral type that can hold all the values in the inclusive range ['0 - V].
+ The parameter should be a positive number.] + ] + [ + [[^boost::int_min_value_t<V>::least]]+ [The smallest, built-in, signed integral type that can hold all the values in the inclusive range ['V - 0].
+ The parameter should be a negative number.] + ] + [ + [[^boost::int_min_value_t<V>::fast]]+ [The easiest-to-manipulate, built-in, signed integral type that can hold all the values in the inclusive range ['V - 0].
+ The parameter should be a negative number.] + ] + [ + [[^boost::uint_value_t<V>::least]]+ [The smallest, built-in, unsigned integral type that can hold all positive values
+ up to and including /V/. The parameter should be a positive number.] + ] + [ + [[^boost::uint_value_t<V>::fast]]+ [The easiest-to-manipulate, built-in, unsigned integral type that can hold all positive values
+ up to and including /V/. The parameter should be a positive number.] + ] +] + +[endsect] + +[section Example] + + #include <boost/integer.hpp> + + //... + + int main() + { + boost::int_t<24>::least my_var; // my_var has at least 24-bits + //... + // This one is guarenteed not to be truncated: + boost::int_max_value_t<1000>::least my1000 = 1000; + //... + // This one is guarenteed not to be truncated, and as fast + // to manipulate as possible, its size may be greater than + // that of my1000: + boost::int_max_value_t<1000>::fast my_fast1000 = 1000; + } + +[endsect] + +[section Demonstration Program] ++The program [@../../test/integer_test.cpp integer_test.cpp] is a simplistic demonstration of the results from instantiating
+various examples of the sized type class templates. + +[endsect] + +[section Rationale] + +The rationale for the design of the templates in this header includes: ++* Avoid recursion because of concern about C++'s limited guaranteed recursion depth (17).
+* Avoid macros on general principles. +* Try to keep the design as simple as possible. + +[endsect] + +[section Alternative] ++If the number of bits required is known beforehand, it may be more appropriate to use the types supplied
+in [@../../../../boost/cstdint.hpp <boost/cstdint.hpp>]. + +[endsect] + +[section Credits] + +The author of most of the Boost integer type choosing templates is +[@http://www.boost.org/people/beman_dawes.html Beman Dawes].+He gives thanks to Valentin Bonnard and [@http://www.boost.org/people/kevlin_henney.htm Kevlin Henney]
+for sharing their designs for similar templates.+[@http://www.boost.org/people/daryle_walker.html Daryle Walker] designed the value-based sized templates.
+ +[endsect] +[endsect] + + + +[section:mask Integer Masks] + +[section Overview] ++The class templates in [@../../../../boost/integer/integer_mask.hpp <boost/integer/integer_mask.hpp>] +provide bit masks for a certain bit position or a contiguous-bit pack of a certain size. +The types of the masking constants come from the [link boost_integer.integer integer type selection templates] header.
+ +[endsect] + +[section Synopsis] + + #include <cstddef> // for std::size_t + + namespace boost + { + + template <std::size_t Bit> + struct high_bit_mask_t + { + typedef ``['implementation-defined-type]`` least; + typedef ``['implementation-defined-type]`` fast; ++ static const least high_bit = ``['implementation-defined]``; + static const fast high_bit_fast = ``['implementation-defined]``;
+ + static const std::size_t bit_position = Bit; + }; + + template <std::size_t Bits> + struct low_bits_mask_t + { + typedef ``['implementation-defined-type]`` least; + typedef ``['implementation-defined-type]`` fast; ++ static const least sig_bits = ``['implementation-defined]``; + static const fast sig_bits_fast = ``['implementation-defined]``;
+ + static const std::size_t bit_count = Bits; + }; + + // Specializations for low_bits_mask_t exist for certain bit counts. + + } // namespace boost + +[endsect] + +[section Single Bit-Mask Class Template] ++The [^boost::high_bit_mask_t] class template provides constants for bit masks representing the bit at a +certain position. The masks are equivalent to the value 2[super Bit], where [^Bit] is the template parameter. +The bit position must be a nonnegative number from zero to ['Max], where Max is one less than the +number of bits supported by the largest unsigned built-in integral type. The following table describes
+the members of an instantiation of [^high_bit_mask_t]. + +[table Members of the `boost::high_bit_mask_t` Class Template + [[Member][Meaning]]+ [[[^least]][The smallest, unsigned, built-in type that supports the given bit position.]]
+ [[[^fast]][The easiest-to-manipulate analog of [^least].]] + [[[^high_bit]][A [^least] constant of the value 2[super Bit].]] + [[[^high_bit_fast]][A [^fast] analog of [^high_bit].]]+ [[[^bit_position]][The value of the template parameter, in case its needed from a renamed instantiation of the class template.]]
+] + +[endsect] + +[section Group Bit-Mask Class Template] ++The [^boost::low_bits_mask_t] class template provides constants for bit masks +equivalent to the value (2[super Bits] - 1), where [^Bits] is the template parameter.
+The parameter [^Bits] must be a non-negative integer from+zero to ['Max], where Max is the number of bits supported by the largest, unsigned, built-in integral type.
+The following table describes the members of [^low_bits_mask_t]. + +[table Members of the [^boost::low_bits_mask_t] Class Template +[[Member][Meaning]]+[[[^least]][The smallest, unsigned built-in type that supports the given bit count.]]
+[[[^fast]][The easiest-to-manipulate analog of [^least].]] +[[[^sig_bits]][A [^least] constant of the desired bit-masking value.]] +[[[^sig_bits_fast]][A [^fast] analog of [^sig_bits].]]+[[[^bit_count]][The value of the template parameter, in case its needed from a renamed instantiation of the class template.]]
+] + +[endsect] + +[section Implementation Notes] ++When [^Bits] is the exact size of a built-in unsigned type, the implementation has to change to +prevent undefined behavior. Therefore, there are specializations of [^low_bits_mask_t] at those bit counts.
+ +[endsect] + +[section Example] + + #include <boost/integer/integer_mask.hpp> + + //... + + int main() + { + typedef boost::high_bit_mask_t<29> mask1_type; + typedef boost::low_bits_mask_t<15> mask2_type; + + mask1_type::least my_var1; + mask2_type::fast my_var2; + //... + + my_var1 |= mask1_type::high_bit; + my_var2 &= mask2_type::sig_bits_fast; + + //... + } + +[endsect] + +[section Demonstration Program] ++The program [@../../test/integer_mask_test.cpp integer_mask_test.cpp] is a simplistic demonstration of the +results from instantiating various examples of the bit mask class templates.
+ +[endsect] + +[section Rationale] ++The class templates in this header are an extension of the [link boost_integer.integer integer type selection class templates]. +The new class templates provide the same sized types, but also convenient masks to use when extracting the +highest or all the significant bits when the containing built-in type contains more bits.
+This prevents contamination of values by the higher, unused bits. + +[endsect] + +[section Credits] ++The author of the Boost bit mask class templates is [@http://www.boost.org/people/daryle_walker.html Daryle Walker].
+ +[endsect] +[endsect] + +[section:log2 Compile Time log2 Calculation] ++The class template in [@../../../../boost/integer/static_log2.hpp <boost/integer/static_log2.hpp>] +determines the position of the highest bit in a given value. This facility is useful for solving generic programming problems.
+ +[section Synopsis] + + namespace boost + { + + typedef ``['implementation-defined]`` static_log2_argument_type; + typedef ``['implementation-defined]`` static_log2_result_type; + + template <static_log2_argument_type arg> + struct static_log2 + {+ static const static_log2_result_type value = ``['implementation-defined]``;
+ }; + + + template < > + struct static_log2< 0 > + { + // The logarithm of zero is undefined. + }; + + + } // namespace boost + +[endsect] + +[section Usage] ++The [^boost::static_log2] class template takes one template parameter, a value of type +[^static_log2_argument_type]. The template only defines one member, [^value], which gives the
+truncated, base-two logarithm of the template argument. ++Since the logarithm of zero, for any base, is undefined, there is a specialization of [^static_log2] +for a template argument of zero. This specialization has no members, so an attempt to use the base-two
+logarithm of zero results in a compile-time error. + +Note: ++* [^static_log2_argument_type] is an ['unsigned integer type] (C++ standard, 3.9.1p3).
+* [^static_log2_result_type] is an ['integer type] (C++ standard, 3.9.1p7). + +[endsect] + +[section Demonstration Program] ++The program [@../../test/static_log2_test.cpp static_log2_test.cpp] is a simplistic +demonstration of the results from instantiating various examples of the binary logarithm class template.
+ +[endsect] + +[section Rationale] ++The base-two (binary) logarithm, abbreviated lb, function is occasionally used to give order-estimates +of computer algorithms. The truncated logarithm can be considered the highest power-of-two in a value, +which corresponds to the value's highest set bit (for binary integers). Sometimes the highest-bit position +could be used in generic programming, which requires the position to be available statically (['i.e.] at compile-time).
+ +[endsect] + +[section Credits] + +The original version of the Boost binary logarithm class template was+written by [@http://www.boost.org/people/daryle_walker.html Daryle Walker] and then +enhanced by Giovanni Bajo with support for compilers without partial template specialization. +The current version was suggested, together with a reference implementation, by Vesa Karvonen.
+Gennaro Prota wrote the actual source file. + +[endsect] +[endsect] + +[section:minmax Compile time min/max calculation] ++The class templates in [@../../../../boost/integer/static_min_max.hpp <boost/integer/static_min_max.hpp>] +provide a compile-time evaluation of the minimum or maximum of two integers. These facilities are useful
+for generic programming problems. + +[section Synopsis] + + namespace boost + { + + typedef ``['implementation-defined]`` static_min_max_signed_type; + typedef ``['implementation-defined]`` static_min_max_unsigned_type; ++ template <static_min_max_signed_type Value1, static_min_max_signed_type Value2 >
+ struct static_signed_min; ++ template <static_min_max_signed_type Value1, static_min_max_signed_type Value2>
+ struct static_signed_max; ++ template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Value2>
+ struct static_unsigned_min; ++ template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Value2>
+ struct static_unsigned_max; + + } + +[endsect] + +[section Usage] ++The four class templates provide the combinations for finding the minimum or maximum of two [^signed] or +[^unsigned] ([^long]) parameters, /Value1/ and /Value2/, at compile-time. Each template has a single static data member, +[^value], which is set to the respective minimum or maximum of the template's parameters.
+ +[endsect] + +[section Example] + + #include <boost/integer/static_min_max.hpp> + + template < unsigned long AddendSize1, unsigned long AddendSize2 > + class adder + { + public: + static unsigned long const addend1_size = AddendSize1; + static unsigned long const addend2_size = AddendSize2;+ static unsigned long const sum_size = boost::static_unsigned_max<AddendSize1, AddendSize2>::value + 1;
+ + typedef int addend1_type[ addend1_size ]; + typedef int addend2_type[ addend2_size ]; + typedef int sum_type[ sum_size ]; ++ void operator ()( addend1_type const &a1, addend2_type const &a2, sum_type &s ) const;
+ }; + + //... + + int main() + { + int const a1[] = { 0, 4, 3 }; // 340 + int const a2[] = { 9, 8 }; // 89 + int s[ 4 ]; + adder<3,2> obj; + + obj( a1, a2, s ); // 's' should be 429 or { 9, 2, 4, 0 } + //... + } + +[endsect] + +[section Demonstration Program] ++The program [@../../test/static_min_max_test.cpp static_min_max_test.cpp] is a simplistic demonstration of
+various comparisons using the compile-time extrema class templates. + +[endsect] + +[section Rationale] ++Sometimes the minimum or maximum of several values needs to be found for later compile-time processing,
+['e.g.] for a bound for another class template. + +[endsect] + +[section Credits] ++The author of the Boost compile-time extrema class templates is [@http://www.boost.org/people/daryle_walker.html Daryle Walker].
+ +[endsect] +[endsect] + +[section:history History] + +[h4 1.42.0] + +* Reverted Trunk to release branch state (i.e. a "known good state"). +* Fixed issues: [@https://svn.boost.org/trac/boost/ticket/653 653], +[@https://svn.boost.org/trac/boost/ticket/3084 3084], +[@https://svn.boost.org/trac/boost/ticket/3177 3177], +[@https://svn.boost.org/trac/boost/ticket/3180 3180], +[@https://svn.boost.org/trac/boost/ticket/3548 3568], +[@https://svn.boost.org/trac/boost/ticket/3657 3657], +[@https://svn.boost.org/trac/boost/ticket/2134 2134].+* Added long long support to [^boost::static_log2], [^boost::static_signed_min], [^boost::static_signed_max],
+[^boost::static_unsigned_min][^boost::static_unsigned_max], when available.+* The argument type and the result type of [^boost::static_signed_min] etc are now typedef'd. +Formerly, they were hardcoded as [^unsigned long] and [^int] respectively. Please, use the
+provided typedefs in new code (and update old code as soon as possible). + +[h4 1.32.0] ++* The argument type and the result type of [^boost::static_log2] are now typedef'd. +Formerly, they were hardcoded as [^unsigned long] and [^int] respectively. Please, use the
+provided typedefs in new code (and update old code as soon as possible). + +[endsect] + ======================================= --- /dev/null +++ /trunk/libs/integer/test/Jamfile.v2 Mon Feb 8 07:24:10 2010 @@ -0,0 +1,25 @@ +#~ Copyright Rene Rivera 2008 +#~ 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 ; + +project : requirements <warnings>all <toolset>gcc:<cxxflags>-Wextra ; + +test-suite integer + :+ [ run cstdint_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-long-long <toolset>darwin:<cxxflags>-Wno-long-long ] + [ run cstdint_test2.cpp : : : <toolset>gcc:<cxxflags>-Wno-long-long <toolset>darwin:<cxxflags>-Wno-long-long ]
+ [ run integer_traits_test.cpp ]+ [ run integer_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-long-long <toolset>darwin:<cxxflags>-Wno-long-long <toolset>sun:<cxxflags>"-Qoption ccfe -tmpldepth=128" ]
+ [ run integer_mask_test.cpp ] + [ run static_log2_test.cpp ] + [ run static_min_max_test.cpp ] + [ compile cstdint_include_test.cpp ] + [ compile integer_traits_include_test.cpp ] + [ compile integer_include_test.cpp ] + [ compile integer_mask_include_test.cpp ] + [ compile static_log2_include_test.cpp ] + [ compile static_min_max_include_test.cpp ] + [ compile integer_fwd_include_test.cpp ] + ; ======================================= --- /dev/null+++ /trunk/libs/integer/test/cstdint_include_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,69 @@ +// Copyright John Maddock 2009. +// 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) + +#define __STDC_CONSTANT_MACROS +#include <boost/cstdint.hpp> // must be the only #include! + +int main() +{ + boost::int8_t i8 = INT8_C(0); + (void)i8; + boost::uint8_t ui8 = UINT8_C(0); + (void)ui8; + boost::int16_t i16 = INT16_C(0); + (void)i16; + boost::uint16_t ui16 = UINT16_C(0); + (void)ui16; + boost::int32_t i32 = INT32_C(0); + (void)i32; + boost::uint32_t ui32 = UINT32_C(0); + (void)ui32; +#ifndef BOOST_NO_INT64_T + boost::int64_t i64 = 0; + (void)i64; + boost::uint64_t ui64 = 0; + (void)ui64; +#endif + boost::int_least8_t i8least = INT8_C(0); + (void)i8least; + boost::uint_least8_t ui8least = UINT8_C(0); + (void)ui8least; + boost::int_least16_t i16least = INT16_C(0); + (void)i16least; + boost::uint_least16_t ui16least = UINT16_C(0); + (void)ui16least; + boost::int_least32_t i32least = INT32_C(0); + (void)i32least; + boost::uint_least32_t ui32least = UINT32_C(0); + (void)ui32least; +#ifndef BOOST_NO_INT64_T + boost::int_least64_t i64least = 0; + (void)i64least; + boost::uint_least64_t ui64least = 0; + (void)ui64least; +#endif + boost::int_fast8_t i8fast = INT8_C(0); + (void)i8fast; + boost::uint_fast8_t ui8fast = UINT8_C(0); + (void)ui8fast; + boost::int_fast16_t i16fast = INT16_C(0); + (void)i16fast; + boost::uint_fast16_t ui16fast = UINT16_C(0); + (void)ui16fast; + boost::int_fast32_t i32fast = INT32_C(0); + (void)i32fast; + boost::uint_fast32_t ui32fast = UINT32_C(0); + (void)ui32fast; +#ifndef BOOST_NO_INT64_T + boost::int_fast64_t i64fast = 0; + (void)i64fast; + boost::uint_fast64_t ui64fast = 0; + (void)ui64fast; +#endif + boost::intmax_t im = 0; + (void)im; + boost::uintmax_t uim = 0; + (void)uim; +} ======================================= --- /dev/null +++ /trunk/libs/integer/test/cstdint_test.cpp Mon Feb 8 07:24:10 2010 @@ -0,0 +1,238 @@+// boost cstdint.hpp test program ------------------------------------------//
+ +// Copyright Beman Dawes 2000. 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/integer for documentation. + +// Revision History+// 11 Sep 01 Adapted to work with macros defined in native stdint.h (John Maddock)
+// 12 Nov 00 Adapted to merged <boost/cstdint.hpp>+// 23 Sep 00 Added INTXX_C constant macro support + int64_t support (John Maddock).
+// 28 Jun 00 Initial version + +//+// There are two ways to test this: in version 1, we include cstdint.hpp as the first +// include, which means we get decide whether __STDC_CONSTANT_MACROS is defined. +// In version two we include stdint.h with __STDC_CONSTANT_MACROS *NOT* defined first, +// and check that we still end up with compatible definitions for the INT#_C macros.
+// +// This is version 1. +// ++#if defined(__GNUC__) && (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) +// We can't suppress this warning on the command line as not all GCC versions support -Wno-type-limits :
+#pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +#include <boost/cstdint.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// +// the following class is designed to verify +// that the various INTXX_C macros can be used +// in integral constant expressions: +// +struct integral_constant_checker +{ + static const boost::int8_t int8 = INT8_C(-127); + static const boost::int_least8_t int_least8 = INT8_C(-127); + static const boost::int_fast8_t int_fast8 = INT8_C(-127); + + static const boost::uint8_t uint8 = UINT8_C(255); + static const boost::uint_least8_t uint_least8 = UINT8_C(255); + static const boost::uint_fast8_t uint_fast8 = UINT8_C(255); + + static const boost::int16_t int16 = INT16_C(-32767); + static const boost::int_least16_t int_least16 = INT16_C(-32767); + static const boost::int_fast16_t int_fast16 = INT16_C(-32767); + + static const boost::uint16_t uint16 = UINT16_C(65535); + static const boost::uint_least16_t uint_least16 = UINT16_C(65535); + static const boost::uint_fast16_t uint_fast16 = UINT16_C(65535); + + static const boost::int32_t int32 = INT32_C(-2147483647); + static const boost::int_least32_t int_least32 = INT32_C(-2147483647); + static const boost::int_fast32_t int_fast32 = INT32_C(-2147483647); + + static const boost::uint32_t uint32 = UINT32_C(4294967295); + static const boost::uint_least32_t uint_least32 = UINT32_C(4294967295); + static const boost::uint_fast32_t uint_fast32 = UINT32_C(4294967295); + + static void check(); +}; + +void integral_constant_checker::check() +{ + BOOST_TEST( int8 == -127 ); + BOOST_TEST( int_least8 == -127 ); + BOOST_TEST( int_fast8 == -127 ); + BOOST_TEST( uint8 == 255u ); + BOOST_TEST( uint_least8 == 255u ); + BOOST_TEST( uint_fast8 == 255u ); + BOOST_TEST( int16 == -32767 ); + BOOST_TEST( int_least16 == -32767 ); + BOOST_TEST( int_fast16 == -32767 ); + BOOST_TEST( uint16 == 65535u ); + BOOST_TEST( uint_least16 == 65535u ); + BOOST_TEST( uint_fast16 == 65535u ); + BOOST_TEST( int32 == -2147483647 ); + BOOST_TEST( int_least32 == -2147483647 ); + BOOST_TEST( int_fast32 == -2147483647 ); + BOOST_TEST( uint32 == 4294967295u ); + BOOST_TEST( uint_least32 == 4294967295u ); + BOOST_TEST( uint_fast32 == 4294967295u ); +} +#endif // BOOST_NO_INCLASS_MEMBER_INITIALIZATION + +// +// the following function simply verifies that the type +// of an integral constant is correctly defined: +// +#ifdef __BORLANDC__ +#pragma option -w-8008 +#pragma option -w-8066 +#endif +template <class T1, class T2> +void integral_constant_type_check(T1, T2) +{ + // + // the types T1 and T2 may not be exactly + // the same type, but they should be the + // same size and signedness. We could use + // numeric_limits to verify this, but + // numeric_limits implementations currently + // vary too much, or are incomplete or missing. + // + T1 t1 = static_cast<T1>(-1); // cast suppresses warnings + T2 t2 = static_cast<T2>(-1); // ditto +#if defined(BOOST_HAS_STDINT_H) + // if we have a native stdint.h + // then the INTXX_C macros may define + // a type that's wider than required: + BOOST_TEST(sizeof(T1) <= sizeof(T2)); +#else + BOOST_TEST(sizeof(T1) == sizeof(T2)); + BOOST_TEST(t1 == t2); +#endif +#if defined(BOOST_HAS_STDINT_H) + // native headers are permitted to promote small + // unsigned types to type int: + if(sizeof(T1) >= sizeof(int)) + { + if(t1 > 0) + BOOST_TEST(t2 > 0); + else + BOOST_TEST(!(t2 > 0)); + } + else if(t1 < 0) + BOOST_TEST(!(t2 > 0)); +#else + if(t1 > 0) + BOOST_TEST(t2 > 0); + else + BOOST_TEST(!(t2 > 0)); +#endif +} + + +int main(int, char*[]) +{ +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION + integral_constant_checker::check(); +#endif + // + // verify the types of the integral constants: + // + integral_constant_type_check(boost::int8_t(0), INT8_C(0)); + integral_constant_type_check(boost::uint8_t(0), UINT8_C(0)); + integral_constant_type_check(boost::int16_t(0), INT16_C(0)); + integral_constant_type_check(boost::uint16_t(0), UINT16_C(0)); + integral_constant_type_check(boost::int32_t(0), INT32_C(0)); + integral_constant_type_check(boost::uint32_t(0), UINT32_C(0)); +#ifndef BOOST_NO_INT64_T + integral_constant_type_check(boost::int64_t(0), INT64_C(0)); + integral_constant_type_check(boost::uint64_t(0), UINT64_C(0)); +#endif + // + boost::int8_t int8 = INT8_C(-127); + boost::int_least8_t int_least8 = INT8_C(-127); + boost::int_fast8_t int_fast8 = INT8_C(-127); + + boost::uint8_t uint8 = UINT8_C(255); + boost::uint_least8_t uint_least8 = UINT8_C(255); + boost::uint_fast8_t uint_fast8 = UINT8_C(255); + + boost::int16_t int16 = INT16_C(-32767); + boost::int_least16_t int_least16 = INT16_C(-32767); + boost::int_fast16_t int_fast16 = INT16_C(-32767); + + boost::uint16_t uint16 = UINT16_C(65535); + boost::uint_least16_t uint_least16 = UINT16_C(65535); + boost::uint_fast16_t uint_fast16 = UINT16_C(65535); + + boost::int32_t int32 = INT32_C(-2147483647); + boost::int_least32_t int_least32 = INT32_C(-2147483647); + boost::int_fast32_t int_fast32 = INT32_C(-2147483647); + + boost::uint32_t uint32 = UINT32_C(4294967295); + boost::uint_least32_t uint_least32 = UINT32_C(4294967295); + boost::uint_fast32_t uint_fast32 = UINT32_C(4294967295); + +#ifndef BOOST_NO_INT64_T + boost::int64_t int64 = INT64_C(-9223372036854775807); + boost::int_least64_t int_least64 = INT64_C(-9223372036854775807); + boost::int_fast64_t int_fast64 = INT64_C(-9223372036854775807); + + boost::uint64_t uint64 = UINT64_C(18446744073709551615); + boost::uint_least64_t uint_least64 = UINT64_C(18446744073709551615); + boost::uint_fast64_t uint_fast64 = UINT64_C(18446744073709551615); + + boost::intmax_t intmax = INTMAX_C(-9223372036854775807); + boost::uintmax_t uintmax = UINTMAX_C(18446744073709551615); +#else + boost::intmax_t intmax = INTMAX_C(-2147483647); + boost::uintmax_t uintmax = UINTMAX_C(4294967295); +#endif + + BOOST_TEST( int8 == -127 ); + BOOST_TEST( int_least8 == -127 ); + BOOST_TEST( int_fast8 == -127 ); + BOOST_TEST( uint8 == 255u ); + BOOST_TEST( uint_least8 == 255u ); + BOOST_TEST( uint_fast8 == 255u ); + BOOST_TEST( int16 == -32767 ); + BOOST_TEST( int_least16 == -32767 ); + BOOST_TEST( int_fast16 == -32767 ); + BOOST_TEST( uint16 == 65535u ); + BOOST_TEST( uint_least16 == 65535u ); + BOOST_TEST( uint_fast16 == 65535u ); + BOOST_TEST( int32 == -2147483647 ); + BOOST_TEST( int_least32 == -2147483647 ); + BOOST_TEST( int_fast32 == -2147483647 ); + BOOST_TEST( uint32 == 4294967295u ); + BOOST_TEST( uint_least32 == 4294967295u ); + BOOST_TEST( uint_fast32 == 4294967295u ); + +#ifndef BOOST_NO_INT64_T + BOOST_TEST( int64 == INT64_C(-9223372036854775807) ); + BOOST_TEST( int_least64 == INT64_C(-9223372036854775807) ); + BOOST_TEST( int_fast64 == INT64_C(-9223372036854775807) ); + BOOST_TEST( uint64 == UINT64_C(18446744073709551615) ); + BOOST_TEST( uint_least64 == UINT64_C(18446744073709551615) ); + BOOST_TEST( uint_fast64 == UINT64_C(18446744073709551615) ); + BOOST_TEST( intmax == INT64_C(-9223372036854775807) ); + BOOST_TEST( uintmax == UINT64_C(18446744073709551615) ); +#else + BOOST_TEST( intmax == -2147483647 ); + BOOST_TEST( uintmax == 4294967295u ); +#endif + + + std::cout << "OK\n"; + return boost::report_errors(); +} ======================================= --- /dev/null +++ /trunk/libs/integer/test/cstdint_test2.cpp Mon Feb 8 07:24:10 2010 @@ -0,0 +1,248 @@+// boost cstdint.hpp test program ------------------------------------------//
+ +// Copyright Beman Dawes 2000. 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/integer for documentation. + +// Revision History+// 11 Sep 01 Adapted to work with macros defined in native stdint.h (John Maddock)
+// 12 Nov 00 Adapted to merged <boost/cstdint.hpp>+// 23 Sep 00 Added INTXX_C constant macro support + int64_t support (John Maddock).
+// 28 Jun 00 Initial version + +//+// There are two ways to test this: in version 1, we include cstdint.hpp as the first +// include, which means we get decide whether __STDC_CONSTANT_MACROS is defined. +// In version two we include stdint.h with __STDC_CONSTANT_MACROS *NOT* defined first, +// and check that we still end up with compatible definitions for the INT#_C macros.
+// +// This is version 2. +// ++#if defined(__GNUC__) && (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) +// We can't suppress this warning on the command line as not all GCC versions support -Wno-type-limits :
+#pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +#include <boost/config.hpp> + +#ifdef BOOST_HAS_STDINT_H +#ifdef __hpux +# include <inttypes.h> +#else +# include <stdint.h> +#endif +#endif + +#include <boost/cstdint.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// +// the following class is designed to verify +// that the various INTXX_C macros can be used +// in integral constant expressions: +// +struct integral_constant_checker +{ + static const boost::int8_t int8 = INT8_C(-127); + static const boost::int_least8_t int_least8 = INT8_C(-127); + static const boost::int_fast8_t int_fast8 = INT8_C(-127); + + static const boost::uint8_t uint8 = UINT8_C(255); + static const boost::uint_least8_t uint_least8 = UINT8_C(255); + static const boost::uint_fast8_t uint_fast8 = UINT8_C(255); + + static const boost::int16_t int16 = INT16_C(-32767); + static const boost::int_least16_t int_least16 = INT16_C(-32767); + static const boost::int_fast16_t int_fast16 = INT16_C(-32767); + + static const boost::uint16_t uint16 = UINT16_C(65535); + static const boost::uint_least16_t uint_least16 = UINT16_C(65535); + static const boost::uint_fast16_t uint_fast16 = UINT16_C(65535); + + static const boost::int32_t int32 = INT32_C(-2147483647); + static const boost::int_least32_t int_least32 = INT32_C(-2147483647); + static const boost::int_fast32_t int_fast32 = INT32_C(-2147483647); + + static const boost::uint32_t uint32 = UINT32_C(4294967295); + static const boost::uint_least32_t uint_least32 = UINT32_C(4294967295); + static const boost::uint_fast32_t uint_fast32 = UINT32_C(4294967295); + + static void check(); +}; + +void integral_constant_checker::check() +{ + BOOST_TEST( int8 == -127 ); + BOOST_TEST( int_least8 == -127 ); + BOOST_TEST( int_fast8 == -127 ); + BOOST_TEST( uint8 == 255u ); + BOOST_TEST( uint_least8 == 255u ); + BOOST_TEST( uint_fast8 == 255u ); + BOOST_TEST( int16 == -32767 ); + BOOST_TEST( int_least16 == -32767 ); + BOOST_TEST( int_fast16 == -32767 ); + BOOST_TEST( uint16 == 65535u ); + BOOST_TEST( uint_least16 == 65535u ); + BOOST_TEST( uint_fast16 == 65535u ); + BOOST_TEST( int32 == -2147483647 ); + BOOST_TEST( int_least32 == -2147483647 ); + BOOST_TEST( int_fast32 == -2147483647 ); + BOOST_TEST( uint32 == 4294967295u ); + BOOST_TEST( uint_least32 == 4294967295u ); + BOOST_TEST( uint_fast32 == 4294967295u ); +} +#endif // BOOST_NO_INCLASS_MEMBER_INITIALIZATION + +// +// the following function simply verifies that the type +// of an integral constant is correctly defined: +// +#ifdef __BORLANDC__ +#pragma option -w-8008 +#pragma option -w-8066 +#endif +template <class T1, class T2> +void integral_constant_type_check(T1, T2) +{ + // + // the types T1 and T2 may not be exactly + // the same type, but they should be the + // same size and signedness. We could use + // numeric_limits to verify this, but + // numeric_limits implementations currently + // vary too much, or are incomplete or missing. + // + T1 t1 = static_cast<T1>(-1); // cast suppresses warnings + T2 t2 = static_cast<T2>(-1); // ditto +#if defined(BOOST_HAS_STDINT_H) + // if we have a native stdint.h + // then the INTXX_C macros may define + // a type that's wider than required: + BOOST_TEST(sizeof(T1) <= sizeof(T2)); +#else + BOOST_TEST(sizeof(T1) == sizeof(T2)); + BOOST_TEST(t1 == t2); +#endif +#if defined(BOOST_HAS_STDINT_H) + // native headers are permitted to promote small + // unsigned types to type int: + if(sizeof(T1) >= sizeof(int)) + { + if(t1 > 0) + BOOST_TEST(t2 > 0); + else + BOOST_TEST(!(t2 > 0)); + } + else if(t1 < 0) + BOOST_TEST(!(t2 > 0)); +#else + if(t1 > 0) + BOOST_TEST(t2 > 0); + else + BOOST_TEST(!(t2 > 0)); +#endif +} + + +int main(int, char*[]) +{ +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION + integral_constant_checker::check(); +#endif + // + // verify the types of the integral constants: + // + integral_constant_type_check(boost::int8_t(0), INT8_C(0)); + integral_constant_type_check(boost::uint8_t(0), UINT8_C(0)); + integral_constant_type_check(boost::int16_t(0), INT16_C(0)); + integral_constant_type_check(boost::uint16_t(0), UINT16_C(0)); + integral_constant_type_check(boost::int32_t(0), INT32_C(0)); + integral_constant_type_check(boost::uint32_t(0), UINT32_C(0)); +#ifndef BOOST_NO_INT64_T + integral_constant_type_check(boost::int64_t(0), INT64_C(0)); + integral_constant_type_check(boost::uint64_t(0), UINT64_C(0)); +#endif + // + boost::int8_t int8 = INT8_C(-127); + boost::int_least8_t int_least8 = INT8_C(-127); + boost::int_fast8_t int_fast8 = INT8_C(-127); + + boost::uint8_t uint8 = UINT8_C(255); + boost::uint_least8_t uint_least8 = UINT8_C(255); + boost::uint_fast8_t uint_fast8 = UINT8_C(255); + + boost::int16_t int16 = INT16_C(-32767); + boost::int_least16_t int_least16 = INT16_C(-32767); + boost::int_fast16_t int_fast16 = INT16_C(-32767); + + boost::uint16_t uint16 = UINT16_C(65535); + boost::uint_least16_t uint_least16 = UINT16_C(65535); + boost::uint_fast16_t uint_fast16 = UINT16_C(65535); + + boost::int32_t int32 = INT32_C(-2147483647); + boost::int_least32_t int_least32 = INT32_C(-2147483647); + boost::int_fast32_t int_fast32 = INT32_C(-2147483647); + + boost::uint32_t uint32 = UINT32_C(4294967295); + boost::uint_least32_t uint_least32 = UINT32_C(4294967295); + boost::uint_fast32_t uint_fast32 = UINT32_C(4294967295); + +#ifndef BOOST_NO_INT64_T + boost::int64_t int64 = INT64_C(-9223372036854775807); + boost::int_least64_t int_least64 = INT64_C(-9223372036854775807); + boost::int_fast64_t int_fast64 = INT64_C(-9223372036854775807); + + boost::uint64_t uint64 = UINT64_C(18446744073709551615); + boost::uint_least64_t uint_least64 = UINT64_C(18446744073709551615); + boost::uint_fast64_t uint_fast64 = UINT64_C(18446744073709551615); + + boost::intmax_t intmax = INTMAX_C(-9223372036854775807); + boost::uintmax_t uintmax = UINTMAX_C(18446744073709551615); +#else + boost::intmax_t intmax = INTMAX_C(-2147483647); + boost::uintmax_t uintmax = UINTMAX_C(4294967295); +#endif + + BOOST_TEST( int8 == -127 ); + BOOST_TEST( int_least8 == -127 ); + BOOST_TEST( int_fast8 == -127 ); + BOOST_TEST( uint8 == 255u ); + BOOST_TEST( uint_least8 == 255u ); + BOOST_TEST( uint_fast8 == 255u ); + BOOST_TEST( int16 == -32767 ); + BOOST_TEST( int_least16 == -32767 ); + BOOST_TEST( int_fast16 == -32767 ); + BOOST_TEST( uint16 == 65535u ); + BOOST_TEST( uint_least16 == 65535u ); + BOOST_TEST( uint_fast16 == 65535u ); + BOOST_TEST( int32 == -2147483647 ); + BOOST_TEST( int_least32 == -2147483647 ); + BOOST_TEST( int_fast32 == -2147483647 ); + BOOST_TEST( uint32 == 4294967295u ); + BOOST_TEST( uint_least32 == 4294967295u ); + BOOST_TEST( uint_fast32 == 4294967295u ); + +#ifndef BOOST_NO_INT64_T + BOOST_TEST( int64 == INT64_C(-9223372036854775807) ); + BOOST_TEST( int_least64 == INT64_C(-9223372036854775807) ); + BOOST_TEST( int_fast64 == INT64_C(-9223372036854775807) ); + BOOST_TEST( uint64 == UINT64_C(18446744073709551615) ); + BOOST_TEST( uint_least64 == UINT64_C(18446744073709551615) ); + BOOST_TEST( uint_fast64 == UINT64_C(18446744073709551615) ); + BOOST_TEST( intmax == INT64_C(-9223372036854775807) ); + BOOST_TEST( uintmax == UINT64_C(18446744073709551615) ); +#else + BOOST_TEST( intmax == -2147483647 ); + BOOST_TEST( uintmax == 4294967295u ); +#endif + + + std::cout << "OK\n"; + return boost::report_errors(); +} ======================================= --- /dev/null+++ /trunk/libs/integer/test/integer_fwd_include_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,22 @@ +// Copyright John Maddock 2009. +// 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/integer_fwd.hpp> // must be the only #include! + +// just declare some functions that use the incomplete types in the header: + +void f1(const boost::integer_traits<char>*); +void f2(const boost::int_fast_t<char>*); +void f3(const boost::int_t<12>*); +void f4(const boost::uint_t<31>*); +void f5(const boost::int_max_value_t<100>*); +void f6(const boost::int_min_value_t<-100>*); +void f7(const boost::uint_value_t<100>*); +void f8(const boost::high_bit_mask_t<10>*); +void f9(const boost::low_bits_mask_t<10>*);+void f10(boost::static_log2_argument_type, boost::static_log2_result_type, boost::static_log2<10>*); +void f11(boost::static_min_max_signed_type, boost::static_min_max_unsigned_type);
+void f12(boost::static_signed_min<1, 2>*, boost::static_signed_max<1,2>*);+void f13(boost::static_unsigned_min<1,2>*, boost::static_unsigned_min<1,2>*);
======================================= --- /dev/null+++ /trunk/libs/integer/test/integer_include_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,36 @@ +// Copyright John Maddock 2009. +// 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/integer.hpp> // must be the only #include! + +int main() +{ + boost::int_fast_t<char>::fast f = 0; + (void)f; + boost::int_t<16>::fast f2 = 0; + (void)f2; + boost::int_t<32>::exact e = 0; + (void)e; + boost::int_t<12>::least l = 0; + (void)l; + boost::uint_t<16>::fast uf2 = 0; + (void)uf2; + boost::uint_t<32>::exact ue = 0; + (void)ue; + boost::uint_t<12>::least ul = 0; + (void)ul; + boost::int_max_value_t<200>::fast v1 = 0; + (void)v1; + boost::int_max_value_t<2000>::least v2 = 0; + (void)v2; + boost::int_min_value_t<-200>::fast v3 = 0; + (void)v3; + boost::int_min_value_t<-2000>::least v4 = 0; + (void)v4; + boost::uint_value_t<200>::fast v5 = 0; + (void)v5; + boost::uint_value_t<2000>::least v6 = 0; + (void)v6; +} ======================================= --- /dev/null+++ /trunk/libs/integer/test/integer_mask_include_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,18 @@ +// Copyright John Maddock 2009. +// 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/integer/integer_mask.hpp> // must be the only #include! + +int main() +{+ boost::high_bit_mask_t<20>::least l = boost::high_bit_mask_t<20>::high_bit; + boost::high_bit_mask_t<12>::fast f = boost::high_bit_mask_t<12>::high_bit_fast;
+ l += f + boost::high_bit_mask_t<12>::bit_position; + (void)l;+ boost::low_bits_mask_t<20>::least l2 = boost::low_bits_mask_t<20>::sig_bits; + boost::low_bits_mask_t<12>::fast f2 = boost::low_bits_mask_t<12>::sig_bits_fast;
+ l2 += f2 + boost::low_bits_mask_t<12>::bit_count; + (void)l2; +} ======================================= --- /dev/null +++ /trunk/libs/integer/test/integer_test.cpp Mon Feb 8 07:24:10 2010 @@ -0,0 +1,263 @@+// boost integer.hpp test program ------------------------------------------//
+ +// Copyright Beman Dawes 1999. +// Copyright Daryle Walker 2001. +// Copyright John Maddock 2009. +// 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/integer for documentation. + +// Revision History +// 04 Oct 01 Added tests for new templates; rewrote code (Daryle Walker) +// 10 Mar 01 Boost Test Library now used for tests (Beman Dawes) +// 31 Aug 99 Initial version + +#include <boost/detail/lightweight_test.hpp> // for main, BOOST_TEST +#include <boost/integer.hpp> // for boost::int_t, boost::uint_t +#include <boost/type_traits/is_same.hpp> + +#include <climits> // for ULONG_MAX, LONG_MAX, LONG_MIN +#include <iostream> // for std::cout (std::endl indirectly) +#include <typeinfo> // for std::type_info + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) // conditional expression is constant +#endif +#if defined( __BORLANDC__ ) +# pragma option -w-8008 -w-8066 // condition is always true +#endif + +// +// Keep track of error count, so we can print out detailed +// info only if we need it: +// +int last_error_count = 0; +// +// Helpers to print out the name of a type, +// we use these as typeid(X).name() doesn't always +// return a human readable string: +//+template <class T> const char* get_name_of_type(T){ return typeid(T).name(); }
+const char* get_name_of_type(signed char){ return "signed char"; } +const char* get_name_of_type(unsigned char){ return "unsigned char"; } +const char* get_name_of_type(short){ return "short"; } +const char* get_name_of_type(unsigned short){ return "unsigned short"; } +const char* get_name_of_type(int){ return "int"; } +const char* get_name_of_type(unsigned int){ return "unsigned int"; } +const char* get_name_of_type(long){ return "long"; } +const char* get_name_of_type(unsigned long){ return "unsigned long"; } +#ifdef BOOST_HAS_LONG_LONG+const char* get_name_of_type(boost::long_long_type){ return "boost::long_long_type"; } +const char* get_name_of_type(boost::ulong_long_type){ return "boost::ulong_long_type"; }
+#endif + +template <int Bits> +void do_test_exact(boost::mpl::true_ const&) +{ + // Test the ::exact member: + typedef typename boost::int_t<Bits>::exact int_exact; + typedef typename boost::uint_t<Bits>::exact uint_exact; + typedef typename boost::int_t<Bits>::least least_int; + typedef typename boost::uint_t<Bits>::least least_uint; + + BOOST_TEST((boost::is_same<int_exact, least_int>::value)); + BOOST_TEST((boost::is_same<uint_exact, least_uint>::value)); +} +template <int Bits> +void do_test_exact(boost::mpl::false_ const&) +{ + // Nothing to do, type does not have an ::extact member. +} + +template <int Bits> +void do_test_bits() +{ + // + // Recurse to next smallest number of bits: + // + do_test_bits<Bits - 1>(); + // + // Test exact types if we have them: + // + do_test_exact<Bits>( + boost::mpl::bool_< + (sizeof(unsigned char) * CHAR_BIT == Bits) + || (sizeof(unsigned short) * CHAR_BIT == Bits) + || (sizeof(unsigned int) * CHAR_BIT == Bits) + || (sizeof(unsigned long) * CHAR_BIT == Bits) +#ifdef BOOST_HAS_LONG_LONG + || (sizeof(boost::ulong_long_type) * CHAR_BIT == Bits) +#endif + >()); + //+ // We need to check all aspects of the members of int_t<Bits> and uint_t<Bits>:
+ // + typedef typename boost::int_t<Bits>::least least_int; + typedef typename boost::int_t<Bits>::least fast_int; + typedef typename boost::uint_t<Bits>::least least_uint; + typedef typename boost::uint_t<Bits>::fast fast_uint; + + if(std::numeric_limits<least_int>::is_specialized) + { + BOOST_TEST(std::numeric_limits<least_int>::digits + 1 >= Bits); + } + if(std::numeric_limits<least_uint>::is_specialized) + { + BOOST_TEST(std::numeric_limits<least_uint>::digits >= Bits); + } + BOOST_TEST(sizeof(least_int) * CHAR_BIT >= Bits); + BOOST_TEST(sizeof(least_uint) * CHAR_BIT >= Bits); + BOOST_TEST(sizeof(fast_int) >= sizeof(least_int)); + BOOST_TEST(sizeof(fast_uint) >= sizeof(least_uint)); + //+ // There should be no type smaller than least_* that also has enough bits:
+ // + if(!boost::is_same<signed char, least_int>::value) + { + BOOST_TEST(std::numeric_limits<signed char>::digits < Bits); + if(!boost::is_same<short, least_int>::value) + { + BOOST_TEST(std::numeric_limits<short>::digits < Bits); + if(!boost::is_same<int, least_int>::value) + { + BOOST_TEST(std::numeric_limits<int>::digits < Bits); + if(!boost::is_same<long, least_int>::value) + { + BOOST_TEST(std::numeric_limits<long>::digits < Bits); + } + } + } + } + // And again, but unsigned: + if(!boost::is_same<unsigned char, least_uint>::value) + { + BOOST_TEST(std::numeric_limits<unsigned char>::digits < Bits); + if(!boost::is_same<unsigned short, least_uint>::value) + { + BOOST_TEST(std::numeric_limits<unsigned short>::digits < Bits); + if(!boost::is_same<unsigned int, least_uint>::value) + { + BOOST_TEST(std::numeric_limits<unsigned int>::digits < Bits); + if(!boost::is_same<unsigned long, least_uint>::value) + {+ BOOST_TEST(std::numeric_limits<unsigned long>::digits < Bits);
+ } + } + } + } + + if(boost::detail::test_errors() != last_error_count) + { + last_error_count = boost::detail::test_errors();+ std::cout << "Errors occured while testing with bit count = " << Bits << std::endl; + std::cout << "Type int_t<" << Bits << ">::least was " << get_name_of_type(least_int(0)) << std::endl; + std::cout << "Type int_t<" << Bits << ">::fast was " << get_name_of_type(fast_int(0)) << std::endl; + std::cout << "Type uint_t<" << Bits << ">::least was " << get_name_of_type(least_uint(0)) << std::endl; + std::cout << "Type uint_t<" << Bits << ">::fast was " << get_name_of_type(fast_uint(0)) << std::endl;
+ } +} +template <> +void do_test_bits<-1>() +{ + // Nothing to do here!! +} + +template <class Traits, class Expected> +void test_min_max_type(Expected val) +{ + typedef typename Traits::least least_type; + typedef typename Traits::fast fast_type; + BOOST_TEST((boost::is_same<least_type, Expected>::value)); + BOOST_TEST(sizeof(fast_type) >= sizeof(least_type)); + BOOST_TEST((std::numeric_limits<least_type>::min)() <= val); + BOOST_TEST((std::numeric_limits<least_type>::max)() >= val); + + if(boost::detail::test_errors() != last_error_count) + { + last_error_count = boost::detail::test_errors();+ std::cout << "Traits type is: " << typeid(Traits).name() << std::endl; + std::cout << "Least type is: " << get_name_of_type(least_type(0)) << std::endl; + std::cout << "Fast type is: " << get_name_of_type(fast_type(0)) << std::endl; + std::cout << "Expected type is: " << get_name_of_type(Expected(0)) << std::endl;
+ std::cout << "Required value is: " << val << std::endl; + } +} + +// Test program +int main(int, char*[]) +{ + // Test int_t and unint_t first: + if(std::numeric_limits<boost::intmax_t>::is_specialized) + do_test_bits<std::numeric_limits<boost::uintmax_t>::digits>(); + else + do_test_bits<std::numeric_limits<long>::digits>(); + + // + // Test min and max value types: + //+ test_min_max_type<boost::int_max_value_t<SCHAR_MAX>, signed char>(SCHAR_MAX); + test_min_max_type<boost::int_min_value_t<SCHAR_MIN>, signed char>(SCHAR_MIN); + test_min_max_type<boost::uint_value_t<UCHAR_MAX>, unsigned char>(UCHAR_MAX);
+#if(USHRT_MAX != UCHAR_MAX)+ test_min_max_type<boost::int_max_value_t<SCHAR_MAX+1>, short>(SCHAR_MAX+1); + test_min_max_type<boost::int_min_value_t<SCHAR_MIN-1>, short>(SCHAR_MIN-1); + test_min_max_type<boost::uint_value_t<UCHAR_MAX+1>, unsigned short>(UCHAR_MAX+1);
+ test_min_max_type<boost::int_max_value_t<SHRT_MAX>, short>(SHRT_MAX); + test_min_max_type<boost::int_min_value_t<SHRT_MIN>, short>(SHRT_MIN);+ test_min_max_type<boost::uint_value_t<USHRT_MAX>, unsigned short>(USHRT_MAX);
+#endif +#if(UINT_MAX != USHRT_MAX)+ test_min_max_type<boost::int_max_value_t<SHRT_MAX+1>, int>(SHRT_MAX+1); + test_min_max_type<boost::int_min_value_t<SHRT_MIN-1>, int>(SHRT_MIN-1); + test_min_max_type<boost::uint_value_t<USHRT_MAX+1>, unsigned int>(USHRT_MAX+1);
+ test_min_max_type<boost::int_max_value_t<INT_MAX>, int>(INT_MAX); + test_min_max_type<boost::int_min_value_t<INT_MIN>, int>(INT_MIN);+ test_min_max_type<boost::uint_value_t<UINT_MAX>, unsigned int>(UINT_MAX);
+#endif +#if(ULONG_MAX != UINT_MAX)+ test_min_max_type<boost::int_max_value_t<INT_MAX+1L>, long>(INT_MAX+1L); + test_min_max_type<boost::int_min_value_t<INT_MIN-1L>, long>(INT_MIN-1L); + test_min_max_type<boost::uint_value_t<UINT_MAX+1uL>, unsigned long>(UINT_MAX+1uL);
+ test_min_max_type<boost::int_max_value_t<LONG_MAX>, long>(LONG_MAX); + test_min_max_type<boost::int_min_value_t<LONG_MIN>, long>(LONG_MIN);+ test_min_max_type<boost::uint_value_t<ULONG_MAX>, unsigned long>(ULONG_MAX);
+#endif +#ifndef BOOST_NO_INTEGRAL_INT64_T+#if defined(BOOST_HAS_LONG_LONG) && (defined(ULLONG_MAX) && (ULLONG_MAX != ULONG_MAX)) + test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); + test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); + test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); + test_min_max_type<boost::int_max_value_t<LLONG_MAX>, boost::long_long_type>(LLONG_MAX); + test_min_max_type<boost::int_min_value_t<LLONG_MIN>, boost::long_long_type>(LLONG_MIN); + test_min_max_type<boost::uint_value_t<ULLONG_MAX>, boost::ulong_long_type>(ULLONG_MAX);
+#endif+#if defined(BOOST_HAS_LONG_LONG) && (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX != ULONG_MAX)) + test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); + test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); + test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); + test_min_max_type<boost::int_max_value_t<LONG_LONG_MAX>, boost::long_long_type>(LONG_LONG_MAX); + test_min_max_type<boost::int_min_value_t<LONG_LONG_MIN>, boost::long_long_type>(LONG_LONG_MIN); + test_min_max_type<boost::uint_value_t<ULONG_LONG_MAX>, boost::ulong_long_type>(ULONG_LONG_MAX);
+#endif+#if defined(BOOST_HAS_LONG_LONG) && (defined(ULONGLONG_MAX) && (ULONGLONG_MAX != ULONG_MAX)) + test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); + test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); + test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); + test_min_max_type<boost::int_max_value_t<LONGLONG_MAX>, boost::long_long_type>(LONGLONG_MAX); + test_min_max_type<boost::int_min_value_t<LONGLONG_MIN>, boost::long_long_type>(LONGLONG_MAX); + test_min_max_type<boost::uint_value_t<ULONGLONG_MAX>, boost::ulong_long_type>(ULONGLONG_MAX);
+#endif+#if defined(BOOST_HAS_LONG_LONG) && (defined(_ULLONG_MAX) && defined(_LLONG_MIN) && (_ULLONG_MAX != ULONG_MAX)) + test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); + test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); + test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); + test_min_max_type<boost::int_max_value_t<_LLONG_MAX>, boost::long_long_type>(_LLONG_MAX); + test_min_max_type<boost::int_min_value_t<_LLONG_MIN>, boost::long_long_type>(_LLONG_MIN); + test_min_max_type<boost::uint_value_t<_ULLONG_MAX>, boost::ulong_long_type>(_ULLONG_MAX);
+#endif // BOOST_HAS_LONG_LONG +#endif // BOOST_NO_INTEGRAL_INT64_T + return boost::report_errors(); +} ======================================= --- /dev/null+++ /trunk/libs/integer/test/integer_traits_include_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,37 @@ +// Copyright John Maddock 2009. +// 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/integer_traits.hpp> // must be the only #include! + +template <class T> +void check_numeric_limits_derived(const std::numeric_limits<T>&){} + +template <class T> +void check() +{ + typedef boost::integer_traits<T> traits; + check_numeric_limits_derived(traits()); + bool b = traits::is_integral; + (void)b; + T v = traits::const_min + traits::const_max; + (void)v; +} + +int main() +{ + check<signed char>(); + check<unsigned char>(); + check<char>(); + check<short>(); + check<unsigned short>(); + check<int>(); + check<unsigned int>(); + check<signed long>(); + check<unsigned long>(); +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + check<boost::long_long_type>(); + check<boost::ulong_long_type>(); +#endif +} ======================================= --- /dev/null+++ /trunk/libs/integer/test/integer_traits_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,101 @@ +/* boost integer_traits.hpp tests + * + * Copyright Jens Maurer 2000 + * 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) + * + * $Id: integer_traits_test.cpp 58381 2009-12-14 18:14:48Z johnmaddock $ + * + * Revision history + * 2000-02-22 Small improvements by Beman Dawes + * 2000-06-27 Rework for better MSVC and BCC co-operation + */ + +#include <iostream> +#include <boost/integer_traits.hpp> +// use int64_t instead of long long for better portability +#include <boost/cstdint.hpp> + +#include <boost/detail/lightweight_test.hpp> + +/* + * General portability note: + * MSVC mis-compiles explicit function template instantiations. + * For example, f<A>() and f<B>() are both compiled to call f<A>(). + * BCC is unable to implicitly convert a "const char *" to a std::string + * when using explicit function template instantiations. + * + * Therefore, avoid explicit function template instantiations. + */ + +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)+template<typename T> inline T make_char_numeric_for_streaming(T x) { return x; }
+namespace fix{ +inline int make_char_numeric_for_streaming(char c) { return c; } +inline int make_char_numeric_for_streaming(signed char c) { return c; } +inline int make_char_numeric_for_streaming(unsigned char c) { return c; } +} +using namespace fix; +#else+template<typename T> inline T make_char_numeric_for_streaming(T x) { return x; }
+inline int make_char_numeric_for_streaming(char c) { return c; } +inline int make_char_numeric_for_streaming(signed char c) { return c; } +inline int make_char_numeric_for_streaming(unsigned char c) { return c; } +#endif + +template<class T> +void runtest(const char * type, T) +{ + typedef boost::integer_traits<T> traits; + std::cout << "Checking " << type+ << "; min is " << make_char_numeric_for_streaming((traits::min)()) + << ", max is " << make_char_numeric_for_streaming((traits::max)())
+ << std::endl; + BOOST_TEST(traits::is_specialized); +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1200) + // MSVC++ 6.0 issues a LNK1179 error (duplicate comdat) when the compiler + // generates different symbol names with a very long common prefix:+ // the dummy "&& true" disambiguates between the symbols generated by this
+ // BOOST_TEST instantiation and the preceding one. + BOOST_TEST(traits::is_integer && true); +#else + BOOST_TEST(traits::is_integer); +#endif + BOOST_TEST(traits::is_integral == true); + BOOST_TEST(traits::const_min == (traits::min)()); + BOOST_TEST(traits::const_max == (traits::max)()); +} + +int main(int, char*[]) +{ + runtest("bool", bool()); + runtest("char", char()); + typedef signed char signed_char; + runtest("signed char", signed_char()); + typedef unsigned char unsigned_char; + runtest("unsigned char", unsigned_char()); + runtest("wchar_t", wchar_t()); + runtest("short", short()); + typedef unsigned short unsigned_short; + runtest("unsigned short", unsigned_short()); + runtest("int", int()); + typedef unsigned int unsigned_int; + runtest("unsigned int", unsigned_int()); + runtest("long", long()); + typedef unsigned long unsigned_long; + runtest("unsigned long", unsigned_long()); +#ifndef BOOST_NO_INTEGRAL_INT64_T + // + // MS/Borland compilers can't support 64-bit member constants+ // BeOS doesn't have specialisations for long long in SGI's <limits> header.
+ runtest("int64_t (possibly long long)", boost::int64_t()); + runtest("uint64_t (possibly unsigned long long)", boost::uint64_t()); +#else + std::cout << "Skipped int64_t and uint64_t" << std::endl; +#endif + // Some compilers don't pay attention to std:3.6.1/5 and issue a + // warning here if "return 0;" is omitted. + return boost::report_errors(); +} + ======================================= --- /dev/null+++ /trunk/libs/integer/test/static_log2_include_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,14 @@ +// Copyright John Maddock 2009. +// 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/integer/static_log2.hpp> // must be the only #include! + +int main() +{ + boost::static_log2_argument_type arg = 0; + (void)arg; + boost::static_log2_result_type result = boost::static_log2<30>::value; + (void)result; +} ======================================= --- /dev/null+++ /trunk/libs/integer/test/static_min_max_include_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,14 @@ +// Copyright John Maddock 2009. +// 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/integer/static_min_max.hpp> // must be the only #include! + +int main() +{+ boost::static_min_max_signed_type m = boost::static_signed_min<2, 3>::value + boost::static_signed_max<2, 3>::value;
+ (void)m;+ boost::static_min_max_unsigned_type u = boost::static_unsigned_min<2, 3>::value + boost::static_unsigned_max<2, 3>::value;
+ (void)u; +} ======================================= --- /dev/null +++ /trunk/libs/multi_index/test/Jamfile.v2 Mon Feb 8 07:24:10 2010 @@ -0,0 +1,57 @@ +# Boost.MultiIndex tests Jamfile +# +# Copyright 2003-2007 Joaquín M López Muñoz. +# 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/multi_index for library home page. + +import os ; +import type ; + +# Windows Vista UAC has an heuristic by which executable files whose name +# contains any of the words "install", "setup", "update", etc. are assumed +# to be installation packages needing administrative rights, which causes +# the system to bring up a window asking for execution confirmation by the +# user, thus interferring in the unattended bjam process. +# Problem bypassed by changing the EXE names containing a taboo word. +# Thanks to Rene Rivera for guidance on the use of the <tag> feature. + +rule change-test_update-exe-name ( name : type ? : property-set ) +{ + if [ os.on-windows ] && [ type.is-subtype $(type) EXE ] + { + return test_updat.exe ; + } +} + +test-suite "multi_index" : + [ run test_basic.cpp test_basic_main.cpp ] + [ run test_capacity.cpp test_capacity_main.cpp ] + [ run test_comparison.cpp test_comparison_main.cpp ] + [ run test_composite_key.cpp test_composite_key_main.cpp ] + [ run test_conv_iterators.cpp test_conv_iterators_main.cpp ] + [ run test_copy_assignment.cpp test_copy_assignment_main.cpp ] + [ run test_hash_ops.cpp test_hash_ops_main.cpp ] + [ run test_iterators.cpp test_iterators_main.cpp ] + [ run test_key_extractors.cpp test_key_extractors_main.cpp ] + [ run test_list_ops.cpp test_list_ops_main.cpp ] + [ run test_modifiers.cpp test_modifiers_main.cpp ] + [ run test_mpl_ops.cpp test_mpl_ops_main.cpp ] + [ run test_observers.cpp test_observers_main.cpp ] + [ run test_projection.cpp test_projection_main.cpp ] + [ run test_range.cpp test_range_main.cpp ] + [ run test_rearrange.cpp test_rearrange_main.cpp ] + [ run test_safe_mode.cpp test_safe_mode_main.cpp ] + [ run test_serialization.cpp test_serialization1.cpp + test_serialization2.cpp test_serialization3.cpp + test_serialization_main.cpp + /boost/serialization//boost_serialization ] + [ run test_set_ops.cpp test_set_ops_main.cpp ] + [ run test_special_set_ops.cpp test_special_set_ops_main.cpp ] + [ run test_update.cpp test_update_main.cpp + : : : + -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag + <tag>@change-test_update-exe-name ] + ; ======================================= --- /dev/null +++ /trunk/libs/numeric/conversion/doc/Jamfile.v2 Mon Feb 8 07:24:10 2010 @@ -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>boost.libraries=../../../../libraries.htm + <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
+ ; + + ======================================= --- /dev/null +++ /trunk/libs/numeric/conversion/doc/bounds.qbk Mon Feb 8 07:24:10 2010 @@ -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] + + + + + + + + + + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/doc/conversion.qbk Mon Feb 8 07:24:10 2010
@@ -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] + + + + + + + + + + + + + + + + + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/doc/conversion_traits.qbk Mon Feb 8 07:24:10 2010
@@ -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] + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/doc/converter.qbk Mon Feb 8 07:24:10 2010
@@ -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] + + + + + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/doc/converter_policies.qbk Mon Feb 8 07:24:10 2010
@@ -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] + + + + + + + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/doc/definitions.qbk Mon Feb 8 07:24:10 2010
@@ -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] + + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/doc/numeric_cast.qbk Mon Feb 8 07:24:10 2010
@@ -0,0 +1,124 @@ +[/ + 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. + +`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 + typename boost::numeric::converter<Target,Source>::result_type + numeric_cast ( Source arg ) + { + return boost::numeric::converter<Target,Source>::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 exception is +thrown (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 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] ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/doc/requirements.qbk Mon Feb 8 07:24:10 2010
@@ -0,0 +1,110 @@ +[/ + 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.numeric_converter_policy_classes.policy_userrangechecker UserRangeChecker] policy for details.
++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] + +[endsect] + ======================================= --- /dev/null +++ /trunk/libs/numeric/conversion/test/Jamfile.v2 Mon Feb 8 07:24:10 2010 @@ -0,0 +1,17 @@ +# 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) + + 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 ] + ; + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/bounds_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,101 @@ +// (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) + +// See library home page at http://www.boost.org/libs/numeric/conversion +// +// Contact the author at: fernando_cacciola@xxxxxxxxxxx +// +#include<typeinfo> +#include<iostream> +#include<iomanip> + +#include "boost/numeric/conversion/bounds.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" + +using namespace std ; +using namespace boost ; +using namespace numeric ; + +// Test the fields of boost::numeric::bounds<> against the expected values. +// +template<class T>+void test_bounds( T expected_lowest, T expected_highest, T expected_smallest )
+{ + T lowest = bounds<T>::lowest () ; + 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_CHECK_MESSAGE ( highest == expected_highest,+ "bounds<" << typeid(T).name() << ">::highest() = " << printable(highest) << ". Expected " << printable(expected_highest)
+ ) ; + + BOOST_CHECK_MESSAGE ( smallest == expected_smallest,+ "bounds<" << typeid(T).name() << ">::smallest() = " << printable(smallest) << ". Expected " << printable(expected_smallest)
+ ) ; +} + + +template<class T> +void test_bounds_integer( MATCH_FNTPL_ARG(T) ) +{ + test_bounds( numeric_limits<T>::min BOOST_PREVENT_MACRO_SUBSTITUTION() + , numeric_limits<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION() + , static_cast<T>(1) + ) ; +} +template<class T> +void test_bounds_float( MATCH_FNTPL_ARG(T)) +{ + test_bounds( -numeric_limits<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION () + , numeric_limits<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION () + , numeric_limits<T>::min BOOST_PREVENT_MACRO_SUBSTITUTION () + ) ; +} + +void test_bounds_integers() +{ + test_bounds_integer( SET_FNTPL_ARG(unsigned char) ) ; + test_bounds_integer( SET_FNTPL_ARG(signed char) ) ; + test_bounds_integer( SET_FNTPL_ARG(char) ) ; + test_bounds_integer( SET_FNTPL_ARG(unsigned short) ) ; + test_bounds_integer( SET_FNTPL_ARG(short) ) ; + test_bounds_integer( SET_FNTPL_ARG(unsigned int) ) ; + test_bounds_integer( SET_FNTPL_ARG(int) ) ; + test_bounds_integer( SET_FNTPL_ARG(unsigned long) ) ; + test_bounds_integer( SET_FNTPL_ARG(long) ) ; +} + +void test_bounds_floats() +{ + test_bounds_float( SET_FNTPL_ARG(float) ); + test_bounds_float( SET_FNTPL_ARG(double) ); + test_bounds_float( SET_FNTPL_ARG(long double) ); +} + +void test_bounds() +{ + test_bounds_integers() ; + test_bounds_floats () ; +} + + +int test_main( int, char * [] ) +{ + cout << setprecision( std::numeric_limits<long double>::digits10 ) ; + + test_bounds(); + + return 0; +} + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/converter_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,562 @@ +// (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) + +// See library home page at http://www.boost.org/libs/numeric/conversion +// +// Contact the author at: fernando_cacciola@xxxxxxxxxxx +// +#include<cstdlib> +#include<iostream> +#include<iomanip> +#include<string> +#include<typeinfo> +#include<vector> +#include<algorithm> + +#include "boost/config.hpp" +#include "boost/cstdint.hpp" +#include "boost/utility.hpp" + +// +// Borland 5.5 lacks the following math overloads +// +#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551) +namespace std +{ ++inline float ceil (float x) { return std::ceil ( static_cast<double>(x)); } +inline float floor (float x) { return std::floor ( static_cast<double>(x)); }
+inline long double ceil (long double x) { return std::ceill (x); } +inline long double floor (long double x) { return std::floorl(x); } + +} // namespace std +#endif + +#include "boost/numeric/conversion/converter.hpp" +#include "boost/numeric/conversion/cast.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" +#include "test_helpers2.cpp" +#include "test_helpers3.cpp" + +#include "boost/mpl/alias.hpp" + +using std::cout ; + +// A generic 'abs' function. +template<class N> inline N absG ( N v ) +{ + return v < static_cast<N>(0) ? static_cast<N>(-v) : v ; +}+template<> inline unsigned char absG<unsigned char> ( unsigned char v ) { return v ; } +template<> inline unsigned short absG<unsigned short> ( unsigned short v ) { return v ; } +template<> inline unsigned int absG<unsigned int> ( unsigned int v ) { return v ; } +template<> inline unsigned long absG<unsigned long> ( unsigned long v ) { return v ; }
+ +template<class T> inline void unused_variable ( T const& ) {} +// +// The following function excersizes specific conversions that cover +// usual and boundary cases for each relevant combination. +// +void test_conversions() +{ + using namespace boost ; + using namespace numeric ; + + // To help the test found possible bugs a random numbers are used. +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::rand ; +#endif + + boost::int16_t v16 ; + boost::uint16_t uv16 ; + boost::int32_t v32 ; + boost::uint32_t uv32 ; ++ volatile float fv ; // avoid this to be cached internally in some fpu register + volatile double dv ; // avoid this to be cached internally in some fpu register
+ + // + // sample (representative) conversions: + // + cout << "Testing representative conversions\n"; + + // integral to integral + + // signed to signed + + // not subranged + v16 = static_cast<boost::int16_t>(rand());+ TEST_SUCCEEDING_CONVERSION_DEF(boost::int32_t,boost::int16_t,v16,v16);
+ + // subranged + v16 = static_cast<boost::int16_t>(rand());+ TEST_SUCCEEDING_CONVERSION_DEF(boost::int16_t,boost::int32_t,v16,v16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int16_t,boost::int32_t,bounds<boost::int16_t>::highest() + boost::int32_t(1) ) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(boost::int16_t,boost::int32_t,bounds<boost::int16_t>::lowest() - boost::int32_t(1) ) ;
+ + // signed to unsigned + + // subranged + v32 = absG(static_cast<boost::int32_t>(rand())); + v16 = absG(static_cast<boost::int16_t>(rand()));+ TEST_SUCCEEDING_CONVERSION_DEF(boost::uint32_t,boost::int32_t,v32,v32); + TEST_SUCCEEDING_CONVERSION_DEF(boost::uint16_t,boost::int32_t,v16,v16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::uint16_t,boost::int32_t,bounds<boost::uint16_t>::highest() + boost::int32_t(1) ) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(boost::uint32_t,boost::int32_t,boost::int32_t(-1) ) ;
+ + // unsigned to signed + + // not subranged + v32 = absG(static_cast<boost::int32_t>(rand()));+ TEST_SUCCEEDING_CONVERSION_DEF(boost::int32_t,boost::uint32_t,v32,v32);
+ + // subranged + v16 = absG(static_cast<boost::int16_t>(rand()));+ TEST_SUCCEEDING_CONVERSION_DEF(boost::int16_t,boost::uint32_t,v16,v16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int32_t,boost::uint32_t,bounds<boost::uint32_t>::highest() ) ; + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int16_t,boost::uint32_t,bounds<boost::uint32_t>::highest() ) ;
+ + // unsigned to unsigned + + // not subranged + uv16 = static_cast<boost::uint16_t>(rand());+ TEST_SUCCEEDING_CONVERSION_DEF(boost::uint32_t,boost::uint16_t,uv16,uv16);
+ + // subranged + uv16 = static_cast<boost::uint16_t>(rand());+ TEST_SUCCEEDING_CONVERSION_DEF(boost::uint16_t,boost::uint32_t,uv16,uv16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::uint16_t,boost::uint32_t,bounds<boost::uint32_t>::highest() ) ;
+ + // integral to float + + // from signed integral + v32 = static_cast<boost::int32_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(double,boost::int32_t,v32,v32); + + // from uint32_tegral + uv32 = static_cast<boost::uint32_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(double,boost::uint32_t,uv32,uv32); + + // float to integral + + // to signed integral + v32 = static_cast<boost::int32_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(boost::int32_t,double,v32,v32); + + dv = static_cast<double>(bounds<boost::uint32_t>::highest()) + 1.0 ; + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int32_t,double,dv) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(boost::int32_t,double,-dv) ; + + // float to float + + // not subranged + fv = static_cast<float>(rand()) / static_cast<float>(3) ; + TEST_SUCCEEDING_CONVERSION_DEF(double,float,fv,fv); + + + // subranged + fv = static_cast<float>(rand()) / static_cast<float>(3) ; + TEST_SUCCEEDING_CONVERSION_DEF(float,double,fv,fv);+ TEST_POS_OVERFLOW_CONVERSION_DEF(float,double,bounds<double>::highest()) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(float,double,bounds<double>::lowest ()) ;
+} + +// Custom OverflowHandler +struct custom_overflow_handler +{ + void operator() ( boost::numeric::range_check_result r ) + { + if ( r == boost::numeric::cNegOverflow ) + cout << "negative_overflow detected!\n" ; + else if ( r == boost::numeric::cPosOverflow ) + cout << "positive_overflow detected!\n" ; + } +} ; + +template<class T, class S,class OverflowHandler>+void test_overflow_handler( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S), MATCH_FNTPL_ARG(OverflowHandler),
+ PostCondition pos, + PostCondition neg + ) +{ + typedef boost::numeric::conversion_traits<T,S> traits ; + typedef boost::numeric::converter<T,S,traits,OverflowHandler> converter ; + + static const S psrc = boost::numeric::bounds<S>::highest(); + static const S nsrc = boost::numeric::bounds<S>::lowest (); + + static const T pres = static_cast<T>(psrc); + static const T nres = static_cast<T>(nsrc); + + test_conv_base ( ConversionInstance<converter>(pres,psrc,pos) ) ; + test_conv_base ( ConversionInstance<converter>(nres,nsrc,neg) ) ; +} + +template<class T, class S> +void test_overflow_handlers( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S) ) +{ + cout << "Testing Silent Overflow Handler policy\n"; + + test_overflow_handler( SET_FNTPL_ARG(T), + SET_FNTPL_ARG(S),+ SET_FNTPL_ARG(boost::numeric::silent_overflow_handler),
+ c_converted, + c_converted + ) ; + + cout << "Testing Default Overflow Handler policy\n"; + + test_overflow_handler( SET_FNTPL_ARG(T), + SET_FNTPL_ARG(S),+ SET_FNTPL_ARG(boost::numeric::def_overflow_handler),
+ c_pos_overflow, + c_neg_overflow + ) ; + + cout << "Testing Custom (User-Defined) Overflow Handler policy\n"; + + test_overflow_handler( SET_FNTPL_ARG(T), + SET_FNTPL_ARG(S), + SET_FNTPL_ARG(custom_overflow_handler), + c_converted, + c_converted + ) ; +} ++// For a given float-type number 'n' of integer value (n.0), check the conversions
+// within the range [n-1,n+1] taking values at: (n-1,n-0.5,n,n+0.5,n+1).+// For each sampled value there is an expected result and a PostCondition according to the
+// specified round_style. +// +template<class T, class S, class Float2IntRounder>+void test_rounding_conversion ( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(Float2IntRounder),
+ S s, + PostCondition resl1, + PostCondition resl0, + PostCondition res, + PostCondition resr0, + PostCondition resr1 + ) +{ + typedef boost::numeric::conversion_traits<T,S> Traits ; ++ typedef boost::numeric::converter<T,S, Traits, boost::numeric::def_overflow_handler,Float2IntRounder>
+ Converter ; + + S sl1 = s - static_cast<S>(1); + S sl0 = s - static_cast<S>(0.5); + S sr0 = s + static_cast<S>(0.5); + S sr1 = s + static_cast<S>(1); + + T tl1 = static_cast<T>( Converter::nearbyint(sl1) ); + T tl0 = static_cast<T>( Converter::nearbyint(sl0) ); + T t = static_cast<T>( Converter::nearbyint(s) ); + T tr0 = static_cast<T>( Converter::nearbyint(sr0) ); + T tr1 = static_cast<T>( Converter::nearbyint(sr1) ); + + test_conv_base ( ConversionInstance<Converter>(tl1,sl1,resl1) ) ; + test_conv_base ( ConversionInstance<Converter>(tl0,sl0,resl0) ) ; + test_conv_base ( ConversionInstance<Converter>(t,s,res) ) ; + test_conv_base ( ConversionInstance<Converter>(tr0,sr0,resr0) ) ; + test_conv_base ( ConversionInstance<Converter>(tr1,sr1,resr1) ) ; +} + + +template<class T,class S> +void test_round_style( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S) ) +{ + S min = boost::numeric::bounds<T>::lowest(); + S max = boost::numeric::bounds<T>::highest(); + + cout << "Testing 'Trunc' Float2IntRounder policy\n"; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Trunc<S>), + min, + c_neg_overflow, + c_converted, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Trunc<S>), + max, + c_converted, + c_converted, + c_converted, + c_converted, + c_pos_overflow + ) ; + + cout << "Testing 'RoundEven' Float2IntRounder policy\n"; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::RoundEven<S>), + min, + c_neg_overflow, + c_converted, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::RoundEven<S>), + max, + c_converted, + c_converted, + c_converted, + c_pos_overflow, + c_pos_overflow + ) ; + + cout << "Testing 'Ceil' Float2IntRounder policy\n"; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Ceil<S>), + min, + c_neg_overflow, + c_converted, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Ceil<S>), + max, + c_converted, + c_converted, + c_converted, + c_pos_overflow, + c_pos_overflow + ) ; + + cout << "Testing 'Floor' Float2IntRounder policy\n" ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Floor<S>), + min, + c_neg_overflow, + c_neg_overflow, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Floor<S>), + max, + c_converted, + c_converted, + c_converted, + c_converted, + c_pos_overflow + ) ; + +} + +void test_round_even( double n, double x ) +{ + double r = boost::numeric::RoundEven<double>::nearbyint(n); + BOOST_CHECK( r == x ) ; +} + +void test_round_even() +{ + cout << "Testing 'RoundEven' tie-breaking\n"; + + double min = boost::numeric::bounds<double>::lowest(); + double max = boost::numeric::bounds<double>::highest(); + +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor ; + using std::ceil ; +#endif + test_round_even(min, floor(min)); + test_round_even(max, ceil (max)); + test_round_even(2.0, 2.0); + test_round_even(2.3, 2.0); + test_round_even(2.5, 2.0); + test_round_even(2.7, 3.0); + test_round_even(3.0, 3.0); + test_round_even(3.3, 3.0); + test_round_even(3.5, 4.0); + test_round_even(3.7, 4.0); +} + +int double_to_int ( double n ) { return static_cast<int>(n) ; } + +void test_converter_as_function_object() +{ + cout << "Testing converter as function object.\n"; + + // Create a sample sequence of double values. + std::vector<double> S ; + for ( int i = 0 ; i < 10 ; ++ i ) + S.push_back( i * ( 18.0 / 19.0 ) ); ++ // Create a sequence of int values from 's' using the standard conversion.
+ std::vector<int> W ; + std::transform(S.begin(),S.end(),std::back_inserter(W),double_to_int); ++ // Create a sequence of int values from s using a default numeric::converter
+ std::vector<int> I ; + std::transform(S.begin(), + S.end(), + std::back_inserter(I), + boost::numeric::converter<int,double>() + ) ; + + // 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");
++ // Create a sequence of double values from s using a default numeric::converter (which should be the trivial conv).
+ std::vector<double> D ; + std::transform(S.begin(), + S.end(), + std::back_inserter(D), + boost::numeric::converter<double,double>() + ) ; + + // 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");
+} + +#if BOOST_WORKAROUND(__IBMCPP__, <= 600 ) // VCAPP6 +# define UNOPTIMIZED +#else +# define UNOPTIMIZED volatile +#endif + +void test_optimizations() +{ + using namespace boost; + using namespace numeric; + + float fv0 = 18.0f / 19.0f ; + + // This code deosn't produce any output.+ // It is intended to show the optimization of numeric::converter<> by manual inspection
+ // of the generated code. + // Each test shows first the equivalent hand-coded version.+ // The numeric_cast<> code should be the same if full compiler optimization/inlining is used.
+ + //--------------------------------- + // trivial conversion. + // + // equivalent code: + UNOPTIMIZED float fv1a = fv0 ; + + float fv1b = numeric_cast<float>(fv0); + unused_variable(fv1a); + unused_variable(fv1b); + // + //--------------------------------- + + //--------------------------------- + // nonsubranged conversion. + // + // equivalent code: + UNOPTIMIZED double dv1a = static_cast<double>(fv0); + + double dv1b = numeric_cast<double>(fv0); + unused_variable(dv1a); + unused_variable(dv1b); + // + //--------------------------------- + + //------------------------------------------------------ + // subranged conversion with both-sided range checking. + // + + // equivalent code: + + { + double const& s = dv1b ; + // range checking+ range_check_result r = s < static_cast<double>(bounds<float>::lowest())
+ ? cNegOverflow : cInRange ; + if ( r == cInRange ) + {+ r = s > static_cast<double>(bounds<float>::highest()) ? cPosOverflow : cInRange ;
+ } + if ( r == cNegOverflow ) + throw negative_overflow() ; + else if ( r == cPosOverflow ) + throw positive_overflow() ; + // conversion + UNOPTIMIZED float fv2a = static_cast<float>(s); + unused_variable(fv2a); + } + + float fv2b = numeric_cast<float>(dv1b); + unused_variable(fv2b); + // + //--------------------------------- + + + //--------------------------------- + // subranged rounding conversion + // + // equivalent code: + + { + double const& s = dv1b ; + // range checking+ range_check_result r = s <= static_cast<double>(bounds<int>::lowest()) - static_cast<double>(1.0)
+ ? cNegOverflow : cInRange ; + if ( r == cInRange ) + {+ r = s >= static_cast<double>(bounds<int>::highest()) + static_cast<double>(1.0)
+ ? cPosOverflow : cInRange ; + } + if ( r == cNegOverflow ) + throw negative_overflow() ; + else if ( r == cPosOverflow ) + throw positive_overflow() ; + // rounding + +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor ; +#endif + + double s1 = floor(dv1b + 0.5); + + // conversion + UNOPTIMIZED int iv1a = static_cast<int>(s1); + unused_variable(iv1a); + } + + int iv1b = numeric_cast<int>(dv1b); + unused_variable(iv1b); + // + //--------------------------------- +} + +int test_main( int, char* argv[] ) +{+ std::cout << std::setprecision( std::numeric_limits<long double>::digits10 ) ;
+ + test_conversions();+ test_overflow_handlers( SET_FNTPL_ARG(boost::int16_t), SET_FNTPL_ARG(boost::int32_t));
+ test_round_style(SET_FNTPL_ARG(boost::int32_t), SET_FNTPL_ARG(double) ) ; + test_round_even() ; + test_converter_as_function_object(); + test_optimizations() ; + + return 0; +} +//--------------------------------------------------------------------------- + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/numeric_cast_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,97 @@+// boost utility cast test program -----------------------------------------//
++// (C) Copyright Beman Dawes, Dave Abrahams 1999. 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 for most recent version including documentation.
+ +// Revision History +// 28 Set 04 taken from the old cast library (Fernando Cacciola) + +#include <iostream> +#include <climits> +#include <cfloat> // for DBL_MAX (Peter Schmid) + +#include <boost/numeric/conversion/cast.hpp> + +#include "boost/test/minimal.hpp" + +# if SCHAR_MAX == LONG_MAX +# error "This test program doesn't work if SCHAR_MAX == LONG_MAX" +# endif + +using namespace boost; +using std::cout; + +int test_main( int argc, char * argv[] ) +{ + +# ifdef NDEBUG + cout << "NDEBUG is defined\n"; +# else + cout << "NDEBUG is not defined\n"; +# endif + + cout << "\nBeginning tests...\n"; ++// test implicit_cast and numeric_cast -------------------------------------//
+ + // tests which should succeed + long small_value = 1; + long small_negative_value = -1; + long large_value = LONG_MAX; + long large_negative_value = LONG_MIN; + signed char c = 0; + + c = large_value; // see if compiler generates warning + + c = numeric_cast<signed char>( small_value ); + BOOST_CHECK( c == 1 ); + c = 0; + c = numeric_cast<signed char>( small_value ); + BOOST_CHECK( c == 1 ); + c = 0; + c = numeric_cast<signed char>( small_negative_value ); + BOOST_CHECK( c == -1 ); ++ // These tests courtesy of Joe R NWP Swatosh<joe.r.swatosh@xxxxxxxxxxxxxx>
+ BOOST_CHECK( 0.0f == numeric_cast<float>( 0.0 ) ); + BOOST_CHECK( 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 ); + + 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 ); + + 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 ); + + 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 ); + + 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 ); + + return 0 ; + +} // main ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/test_helpers.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,152 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + + +// +// NOTE: This file is intended to be used ONLY by the test files +// from the Numeric Conversions Library +// +// +#include <cmath> + +#include "boost/limits.hpp" +#include "boost/utility.hpp" + +#include "boost/test/included/test_exec_monitor.hpp" + +// Convenience macros to help with compilers which don't parse +// explicit template function instantiations (MSVC6) +#define MATCH_FNTPL_ARG(t) t const* +#define SET_FNTPL_ARG(t) (static_cast< t const* >(0)) + +// +// *Minimal* example of a User Defined Numeric Type +// +// +namespace MyUDT +{ + +template<class T> +struct UDT +{ + typedef T builtin_type ; + + UDT ( T v_ ) : v (v_) {} + + T to_builtin() const { return v ; } + + friend bool operator == ( UDT const& lhs, UDT const& rhs ) + { return lhs.to_builtin() == rhs.to_builtin() ; } + + // NOTE: This operator is *required* by the Numeric Conversion Library + // if Turnc<> is used as the Float2IntRounder policy. + friend bool operator < ( UDT const& lhs, UDT const& rhs ) + { return lhs.to_builtin() < rhs.to_builtin() ; } + + friend std::ostream& operator << ( std::ostream& os, UDT const& n ) + { return os << n.to_builtin() ; } + + T v ; +} ; + +typedef UDT<int> MyInt ; +typedef UDT<double> MyFloat ; + +//+// The Float2IntRounder policies *require* a visible 'ceil' or 'floor' math function
+// with standard semantics.+// In a conformant compiler, ADL can pick these functions even if they are defined
+// within a user namespace, as below. +// +inline MyInt ceil ( MyInt const& x ) { return x ; } +inline MyInt floor ( MyInt const& x ) { return x ; } + +inline MyFloat floor ( MyFloat const& x ) +{ +#if !defined(BOOST_NO_STDC_NAMESPACE) + return MyFloat ( std::floor(x.to_builtin()) ) ; +#else + return MyFloat ( ::floor(x.to_builtin()) ) ; +#endif +} + +inline MyFloat ceil ( MyFloat const& x ) +{ +#if !defined(BOOST_NO_STDC_NAMESPACE) + return MyFloat ( std::ceil(x.to_builtin()) ) ; +#else + return MyFloat ( ::ceil(x.to_builtin()) ) ; +#endif +} + +} // namespace MyUDT + + +// +// The Numeric Conversion Library *requires* User Defined Numeric Types +// to properly specialize std::numeric_limits<> +// +namespace std +{ + +template<> +class numeric_limits<MyUDT::MyInt> : public numeric_limits<int> +{ + public : + + BOOST_STATIC_CONSTANT(bool, is_specialized = false); +} ; + +template<> +class numeric_limits<MyUDT::MyFloat> : public numeric_limits<double> +{ + public : + + BOOST_STATIC_CONSTANT(bool, is_specialized = false); +} ; + +} // namespace std + + + +// +// The functions floor and ceil defined within namespace MyUDT +// should be found by koenig loopkup, but some compilers don't do it right +// so we inyect them into namespace std so ordinary overload resolution +// can found them.+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || defined(__BORLANDC__) | | defined(__GNUC__)
+namespace std { +using MyUDT::floor ; +using MyUDT::ceil ; +} // namespace std +#endif + + +std::string to_string( bool arg ) +{ + return arg ? "true" : "false" ; +} ++std::string to_string( ... ) { throw std::runtime_error("to_string() called with wrong type!") ; }
+ +// +// This is used to print 'char' values as numbers instead of characters. +// +template<class T> struct printable_number_type { typedef T type ; } ;+template<> struct printable_number_type<signed char> { typedef int type ; } ; +template<> struct printable_number_type<unsigned char> { typedef unsigned type ; } ; +template<> struct printable_number_type<char> { typedef int type ; } ;
+ +template<class T> +inline +typename printable_number_type<T>::type +printable( T n ) { return n ; } + + +// +/////////////////////////////////////////////////////////////////////////////////////////////// + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/test_helpers2.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,60 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + + +// +// NOTE: This file is intended to be used ONLY by the test files +// from the Numeric Conversions Library +// + +// +// The following 'to_string' helpers are provided to give readable names +// to the various enums used by the library.+// NOTE: specializations of boost::lexical_cast<> were not used since some compilers had
+// trouble dealing with such specializations for different enumerations. +// + +std::string to_string ( boost::numeric::int_float_mixture_enum arg ) +{ + switch ( arg ) + {+ case boost::numeric::integral_to_integral : return "integral_to_integral" ; + case boost::numeric::integral_to_float : return "integral_to_float" ; + case boost::numeric::float_to_integral : return "float_to_integral" ;
+ case boost::numeric::float_to_float : return "float_to_float" ; + } + return "(Unknown result!)" ; +} + + +std::string to_string ( boost::numeric::sign_mixture_enum arg ) +{ + switch ( arg ) + {+ case boost::numeric::unsigned_to_unsigned : return "unsigned_to_unsigned" ;
+ case boost::numeric::signed_to_signed : return "signed_to_signed" ;+ case boost::numeric::signed_to_unsigned : return "signed_to_unsigned" ; + case boost::numeric::unsigned_to_signed : return "unsigned_to_signed" ;
+ } + return "(Unknown result!)" ; +} + +std::string to_string ( boost::numeric::udt_builtin_mixture_enum arg ) +{ + switch ( arg ) + { + case boost::numeric::builtin_to_builtin : return "builtin_to_builtin" ; + case boost::numeric::builtin_to_udt : return "builtin_to_udt" ; + case boost::numeric::udt_to_builtin : return "udt_to_builtin" ; + case boost::numeric::udt_to_udt : return "udt_to_udt" ; + } + return "(Unknown result!)" ; +} + +// +/////////////////////////////////////////////////////////////////////////////////////////////// + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/test_helpers3.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,144 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + + +// +// NOTE: This file is intended to be used ONLY by the test files +// from the Numeric Conversions Library +// ++// The conversion test is performed using a class whose instances encapsulate
+// a particular specific conversion defnied explicitely. +// A ConversionInstance object includes the source type, the target type, +// the source value and the expected result, including possible exceptions. +// ++enum PostCondition { c_converted, c_overflow, c_neg_overflow, c_pos_overflow } ;
+ +template<class Converter> +struct ConversionInstance +{ + typedef Converter converter ; + + typedef typename Converter::argument_type argument_type ; + typedef typename Converter::result_type result_type ; + + typedef typename Converter::traits traits ; + typedef typename traits::target_type target_type ; + typedef typename traits::source_type source_type ; ++ ConversionInstance ( result_type a_result, argument_type a_source, PostCondition a_post)
+ : + source(a_source), + result(a_result), + post(a_post) + {} + + std::string to_string() const + { + return std::string("converter<") + + typeid(target_type).name() + + std::string(",") + + typeid(source_type).name() + + std::string(">::convert(") ; + } + + argument_type source ; + result_type result ; + PostCondition post ; +} ; + +// +// Main conversion test point. +// Exercises a specific conversion described by 'conv'. +// +template<class Instance> +void test_conv_base( Instance const& conv ) +{ + typedef typename Instance::argument_type argument_type ; + typedef typename Instance::result_type result_type ; + typedef typename Instance::converter converter ; + + argument_type source = conv.source ; + + try + { + result_type result = converter::convert(source); + + if ( 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" )
+ ) ; + } + } + 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) ) ;
+ } + } + 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) ) ;
+ } + } + 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) ) ;
+ } + } +} + + +#define TEST_SUCCEEDING_CONVERSION(Conv,typeT,typeS,valueT,valueS) \+ test_conv_base( ConversionInstance< Conv >(valueT, valueS, c_converted ) )
+ +#define TEST_POS_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \+ test_conv_base( ConversionInstance< Conv >( static_cast< typeT
(0), valueS, c_pos_overflow ) )
+ +#define TEST_NEG_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \+ test_conv_base( ConversionInstance< Conv >( static_cast< typeT
(0), valueS, c_neg_overflow ) )
+ +#define DEF_CONVERTER(T,S) boost::numeric::converter< T , S > + +#define TEST_SUCCEEDING_CONVERSION_DEF(typeT,typeS,valueT,valueS) \+ TEST_SUCCEEDING_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueT, valueS )
+ +#define TEST_POS_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \+ TEST_POS_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS )
+ +#define TEST_NEG_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \+ TEST_NEG_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS )
+ + +// +/////////////////////////////////////////////////////////////////////////////////////////////// + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/traits_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,341 @@ +// 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) +// +// +#include<iostream> +#include<iomanip> +#include<string> +#include<typeinfo> +#include<vector> +#include<algorithm> + +#include <boost/cstdint.hpp> +#include <boost/utility.hpp> +#include <boost/preprocessor/cat.hpp> + +#include <boost/numeric/conversion/conversion_traits.hpp> +#include <boost/numeric/conversion/int_float_mixture.hpp> +#include <boost/numeric/conversion/sign_mixture.hpp> +#include <boost/numeric/conversion/udt_builtin_mixture.hpp> +#include <boost/numeric/conversion/is_subranged.hpp> + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" +#include "test_helpers2.cpp" + +using namespace std ; +using namespace boost ; +using namespace numeric; +using namespace MyUDT ; + +// These helpers are used by generate_expected_traits<T,S>.+// Unlike the similar helpers in the implementation, they are specialized by extension.
+// +template<class T, class S> struct my_is_subranged ; +template<class T, class S> struct my_is_trivial ; +template<class T, class S> struct my_int_float_mixture ; +template<class T, class S> struct my_sign_mixture ; +template<class T, class S> struct my_udt_builtin_mixture ; + +// This macro is used to define the properties of each conversion between +// the builtin arithmetric types +//+// It defines the specialization of the helper traits used by 'generate_expected_traits'
+//+#define DEFINE_CONVERSION(Target,Source,Trivial,Mixture,SignMixture,UdtMixture,SubRanged) \
+ \ + template<> struct my_is_subranged<Target,Source> \ + { typedef mpl::bool_< (SubRanged) > type ; } ; \ + \ + template<> struct my_is_trivial<Target,Source> \ + { typedef mpl::bool_< (Trivial) > type ; } ; \+ \ + template<> struct my_int_float_mixture<Target,Source> \ + { typedef mpl::integral_c<boost::numeric::int_float_mixture_enum, (Mixture) > type ; } ; \ + \ + template<> struct my_sign_mixture<Target,Source> \ + { typedef mpl::integral_c<boost::numeric::sign_mixture_enum, (SignMixture) > type ; } ; \ + \ + template<> struct my_udt_builtin_mixture<Target,Source> \ + { typedef mpl::integral_c<boost::numeric::udt_builtin_mixture_enum, (UdtMixture) > type ; }
+ + +#define cSubRanged true +#define cTrivial true ++// The following test assumes a specific relation between the sizes of the types being used; +// therefore, use specific fixed-width types instead built-in types directly.
+ +// NOTE --> TARGET,SOURCE +//+DEFINE_CONVERSION(boost::uint8_t , boost::uint8_t, cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::int8_t, cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::int8_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::uint16_t, cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::int16_t, cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::int16_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::uint32_t, cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::int32_t, cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::int32_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , float, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , float, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , float, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , float, cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , float, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(float) > sizeof(double) ) ); +DEFINE_CONVERSION(long double , float, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(float) > sizeof(long double) ) ); +DEFINE_CONVERSION(MyInt , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , float, !cTrivial, float_to_float , signed_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(double) > sizeof(float) ) ); +DEFINE_CONVERSION(double , double, cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(double) > sizeof(long double) ) ); +DEFINE_CONVERSION(MyInt , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , double, !cTrivial, float_to_float , signed_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , long double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , long double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , long double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , long double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(long double) > sizeof(float) ) ); +DEFINE_CONVERSION(double , long double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(long double) > sizeof(double) ) ); +DEFINE_CONVERSION(long double , long double, cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , long double, !cTrivial, float_to_float , signed_to_signed , builtin_to_udt , !cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , MyInt, !cTrivial, integral_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , MyInt, !cTrivial, integral_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , MyInt, !cTrivial, integral_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , MyInt, !cTrivial, integral_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , MyInt, !cTrivial, integral_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , MyInt, !cTrivial, integral_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(float , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(double , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(long double , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(MyInt , MyInt, cTrivial, integral_to_integral, signed_to_signed , udt_to_udt ,!cSubRanged ); +DEFINE_CONVERSION(MyFloat , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_udt ,!cSubRanged );
++DEFINE_CONVERSION(boost::uint8_t , MyFloat, !cTrivial, float_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , MyFloat, !cTrivial, float_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , MyFloat, !cTrivial, float_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(float , MyFloat, !cTrivial, float_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(double , MyFloat, !cTrivial, float_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(long double , MyFloat, !cTrivial, float_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(MyInt , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_udt ,!cSubRanged ); +DEFINE_CONVERSION(MyFloat , MyFloat, cTrivial, float_to_float , signed_to_signed , udt_to_udt ,!cSubRanged );
+ +// +// The test is performed by comparing each field of +// boost::numeric::conversion_traits<T,S> +// with the fields of +// expected_traits<T,S> +// which is a traits class constructed explicitely for each combination +// of the built-in arithmetic types. +// +template<class T, + class S, + class Supertype, + class Subtype, + class Subranged, + class Trivial + > +struct expected_traits +{ + typedef typename my_int_float_mixture <T,S>::type int_float_mixture ; + typedef typename my_sign_mixture <T,S>::type sign_mixture ; + typedef typename my_udt_builtin_mixture <T,S>::type udt_builtin_mixture ; + + typedef Subranged subranged ; + typedef Trivial trivial ; + typedef Supertype supertype ; + typedef Subtype subtype ; +} ; ++// This is used by the test engine to generate a expected_traits from T and S.
+// +template<class T, class S> +struct generate_expected_traits +{ + typedef expected_traits<T, S, T, S, mpl::false_, mpl::true_ > trivial ;+ typedef expected_traits<T, S, S, T, mpl::true_ , mpl::false_ > subranged ; + typedef expected_traits<T, S, T, S, mpl::false_, mpl::false_ > non_subranged ;
+ + typedef typename my_is_subranged<T,S>::type IsSubranged ; + typedef typename my_is_trivial <T,S>::type IsTrivial ; ++ typedef typename mpl::if_<IsSubranged,subranged,non_subranged>::type non_trivial ;
+ + typedef typename mpl::if_<IsTrivial,trivial,non_trivial>::type type ; +} ; + +// This macro generates the code that compares a non-type field +// in boost::numeric::conversion_traits<> with its corresponding field +// in 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) \
+ ) ; + +// This macro generates the code that compares a type field +// in numeric::conversion_traits<> with its corresponding field +// in 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() \
+ ) ; + +// +// Test core. +// Compares each field of boost::numeric::conversion_traits<T,S> +// with the corresponding field of expected_traits<T,S> +// +template<class T, class S> +void test_traits_base( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S) ) +{ + typedef boost::numeric::conversion_traits<T,S> traits ; + typedef typename generate_expected_traits<T,S>::type expected ; + + TEST_VALUE_FIELD(int_float_mixture) ; + TEST_VALUE_FIELD(sign_mixture) ; + TEST_VALUE_FIELD(udt_builtin_mixture) ; + TEST_VALUE_FIELD(subranged) ; + TEST_VALUE_FIELD(trivial) ; + TEST_TYPE_FIELD (supertype) ; + TEST_TYPE_FIELD (subtype) ; +} + + +template<class S> +void test_traits_from( MATCH_FNTPL_ARG(S) ) +{ + test_traits_base( SET_FNTPL_ARG(boost::uint8_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::int8_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::uint16_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::int16_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::uint32_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::int32_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(float) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(double) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(long double) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(MyInt) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(MyFloat) ,SET_FNTPL_ARG(S) ); +} + +void test_traits() +{ + test_traits_from( SET_FNTPL_ARG(boost::uint8_t) ); + test_traits_from( SET_FNTPL_ARG(boost::int8_t) ); + test_traits_from( SET_FNTPL_ARG(boost::uint16_t) ); + test_traits_from( SET_FNTPL_ARG(boost::int16_t) ); + test_traits_from( SET_FNTPL_ARG(boost::uint32_t) ); + test_traits_from( SET_FNTPL_ARG(boost::int32_t) ); + test_traits_from( SET_FNTPL_ARG(float) ); + test_traits_from( SET_FNTPL_ARG(double) ); + test_traits_from( SET_FNTPL_ARG(long double) ); + test_traits_from( SET_FNTPL_ARG(MyInt) ); + test_traits_from( SET_FNTPL_ARG(MyFloat) ); +} + +int test_main( int, char * []) +{+ std::cout << std::setprecision( std::numeric_limits<long double>::digits10 ) ;
+ + test_traits(); + + return 0; +} +//--------------------------------------------------------------------------- + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/udt_example_0.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,242 @@ +// 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 +// http://www.boost.org/LICENSE_1_0.txt) +// +// +#include "boost/config.hpp" +#include "boost/utility.hpp" +#include "boost/limits.hpp" +#include "boost/utility.hpp" + +#include<iostream> +#include<iomanip> +#include<string> +#include<cmath> + + +#include "boost/test/included/test_exec_monitor.hpp" + +#include "boost/numeric/conversion/cast.hpp" + +using namespace std ; +using namespace boost; +using namespace numeric; + +//+// This example illustrates how to add support for user defined types (UDTs)
+// to the Boost Numeric Conversion Library. +// It is assumed that you are familiar with the following documentation: +// +// + +//+// The minimum requirement is that boost::is_arithmetic<UDT> evaluates to false +// (Otherwise the converter code will try to examine the UDT as a built-in type)
+// + +//+// Let's start with the simpliest case of an UDT which supports standard conversions
+// +struct Double +{ + Double( double v ) : mV(v) {} + + operator double() const { return mV ; } + + double mV ; +} ; + +double dv = (numeric_limits<double>::max)() ; +double fv = (numeric_limits<float >::max)() ; +Double Dv(dv); +Double Fv(fv); + +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 ) ) ;
++ // 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 ) ;
+ + + + // + // 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_CHECK( numeric_cast<float> (Dv) == static_cast<float> (Dv) ) ; + BOOST_CHECK( 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) ); + +} + +//+// The conversion_traits<> class and therefore the converter<> class looks at +// numeric_limits<UDT>::is_integer/is_signed to generate the proper float_in and sign mixtures. +// In most implementations, is_integer/is_signed are both false for UDTs if there is no explicit specialization for it. +// Therefore, the converter<> will see any UDT for which numeric_limits<> is not specialized as Float AND unsigned. +// Signess is used in the converter<> for range checking, but range checking is disabled by default for UDTs, so, +// normally, signess is mostly irrelevant as far as the library is concerned, except for the numeric_traits<>::sign_mixture
+// entry.+// is_integer, however, is relevant in that if the conversion is from a float type to an integer type, the conversion is
+// "rounding" and the rounder policies will participate.+// ALL implemented rounder policies require proper definitions for floor(udt) and ceil(udt). +// These names will be searched for using ADL, so, if you need to convert TO integral types from a UDT, +// you need to supply those functions along with the UDT in right namespace (that is, any namespace that allows
+// ADL to find them) + +// If your UDT doesn't supply floor/ceil, conversions to integer types +// won't compile unless a custom Float2IntRounder is used. + +Double floor ( Double v ) { return Double(std::floor(v.mV)) ; } +Double ceil ( Double v ) { return Double(std::ceil (v.mV)) ; } + +void rounding() +{ + BOOST_CHECK( numeric_cast<int>(Dv) == static_cast<int>(Dv) ) ; +} + + +//+// If your UDT can't or won't provide floor/ceil you can set-up and use your own +// Float2IntRounder policy (though doing this is not always required as shown so far)
+// +struct DoubleToInt +{+ static Double nearbyint ( Double const& s ) { return Double(static_cast<int>(s)); }
++ typedef mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style ;
+} ; + +void custom_rounding() +{ + typedef converter<int + ,Double + ,conversion_traits<int,Double>+ ,void // By default UDT disable range checking so this won't be used
+ ,DoubleToInt + > + DoubleToIntConverter ; ++ BOOST_CHECK( DoubleToIntConverter::convert(Dv) == static_cast<int>(Dv) ) ;
+} + +//+// In the next Level of complexity, your UDTs might not support conversion operators
+// +struct Float +{ + Float( float v ) : mV(v) {} + + float mV ; +} ; + +struct Int +{ + Int( int v ) : mV(v) {} + + int mV ; +} ; + +typedef conversion_traits<Int,Float> Float2IntTraits ; +typedef conversion_traits<Float,Int> Int2FloatTraits ; + +namespace boost { namespace numeric +{ +//+// Though static_cast<> won't work with them you can still use numeric_cast<> by specializing
+// raw_converter as follows: +// +template<> struct raw_converter<Float2IntTraits> +{ + typedef Float2IntTraits::result_type result_type ; + typedef Float2IntTraits::argument_type argument_type ; ++ static result_type low_level_convert ( argument_type s ) { return Int((int)s.mV); }
+} ; +template<> struct raw_converter<Int2FloatTraits> +{ + typedef Int2FloatTraits::result_type result_type ; + typedef Int2FloatTraits::argument_type argument_type ; ++ static result_type low_level_convert ( argument_type s ) { return Float(s.mV); }
+} ; + +} } + +void custom_raw_converter() +{ + Float f (12.34); + Int i (12); + Float fi(12); + + BOOST_CHECK(numeric_cast<Int> (f).mV == i .mV ) ; + BOOST_CHECK(numeric_cast<Float>(i).mV == fi.mV ) ; +} + +//+// Alterntively, the custom raw_converter classes can be defined non-instrusively
+// (not as specializations) and passed along as policies +// +struct Float2IntRawConverter +{+ static Int low_level_convert ( Float const& s ) { return Int((int)s.mV); }
+} ; +struct Int2FloatRawConverter +{ + static Float low_level_convert ( Int const& s ) { return Float(s.mV); } +} ; + +void custom_raw_converter2() +{ + Float f (12.34); + Int i (12); + Float fi(12); + + typedef converter<Int + ,Float + ,Float2IntTraits+ ,void // By default UDT disable range checking so this won't be used + ,void // Float2Int Rounder won't be used if Int isn't marked as integer via numeric_limits<>
+ ,Float2IntRawConverter + > + Float2IntConverter ; + + BOOST_CHECK(Float2IntConverter::convert(f).mV == i .mV ) ; +} + +int test_main( int, char* [] ) +{ + cout << setprecision( numeric_limits<long double>::digits10 ) ; + + simplest_case(); + rounding(); + custom_rounding(); + custom_raw_converter(); + custom_raw_converter2(); + + return 0; +} + + + + + + ======================================= --- /dev/null+++ /trunk/libs/numeric/conversion/test/udt_support_test.cpp Mon Feb 8 07:24:10 2010
@@ -0,0 +1,309 @@ +// (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 +// http://www.boost.org/LICENSE_1_0.txt) +// +// +#include<iostream> +#include<iomanip> +#include<string> +#include<typeinfo> +#include<vector> +#include<algorithm> + +#include "boost/numeric/conversion/converter.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" +#include "test_helpers2.cpp" +#include "test_helpers3.cpp" + +using namespace std ; +using namespace boost ; +using namespace numeric ; +using namespace MyUDT ; + +//------------------------------------------------------------------------- +// These are the typical steps that are required to install support for +// conversions from/to UDT which need special treatment. +//------------------------------------------------------------------------- + + + +// +// (1) Instantiate specific convesions traits. +// This step is only for convenience.+// These traits instances are required in order to define the specializations +// that follow (and which *are required* to make the library work with MyInt and MyFloat)
+// +namespace MyUDT { + +typedef conversion_traits<double , MyFloat> MyFloat_to_double_Traits; +typedef conversion_traits<int , MyFloat> MyFloat_to_int_Traits; +typedef conversion_traits<MyInt , MyFloat> MyFloat_to_MyInt_Traits; +typedef conversion_traits<int , MyInt > MyInt_to_int_Traits; +typedef conversion_traits<MyFloat, MyInt > MyInt_to_MyFloat_Traits; +typedef conversion_traits<MyInt , double > double_to_MyInt_Traits; + +} // namespace MyUDT + + +// +// (2) Define suitable raw converters. +// +// Our sample UDTs don't support implicit conversions. +// Therefore, the default raw_converter<> doesn't work, +// and we need to define our own. +// +// There are two ways of doing this: +//+// (a) One is to simply specialize boost::numeric::raw_converter<> directly. +// This way, the default converter will work out of the box, which means, for instance,
+// that numeric_cast<> can be used with these UDTs. +//+// (b) Define a user class with the appropriate interface and supply it explicitely
+// as a policy to a converter instance. +// +// This test uses chice (a). +// +namespace boost { + +namespace numeric { + +template<> +struct raw_converter<MyUDT::MyFloat_to_double_Traits> +{ + static double low_level_convert ( MyUDT::MyFloat const& s ) + { return s.to_builtin() ; } +} ; + +template<> +struct raw_converter<MyUDT::MyFloat_to_int_Traits> +{ + static int low_level_convert ( MyUDT::MyFloat const& s ) + { return static_cast<int>( s.to_builtin() ) ; } +} ; + +template<> +struct raw_converter<MyUDT::MyFloat_to_MyInt_Traits> +{ + static MyUDT::MyInt low_level_convert ( MyUDT::MyFloat const& s ) + { return MyUDT::MyInt( static_cast<int>(s.to_builtin()) ) ; } +} ; + +template<> +struct raw_converter<MyUDT::MyInt_to_int_Traits> +{+ static int low_level_convert ( MyUDT::MyInt const& s ) { return s.to_builtin() ; }
+} ; + +template<> +struct raw_converter<MyUDT::MyInt_to_MyFloat_Traits> +{ + static MyUDT::MyFloat low_level_convert ( MyUDT::MyInt const& s ) + { + return MyUDT::MyFloat( static_cast<double>(s.to_builtin()) ) ; + } +} ; + +template<> +struct raw_converter<MyUDT::double_to_MyInt_Traits> +{ + static MyUDT::MyInt low_level_convert ( double s ) + { return MyUDT::MyInt( static_cast<int>(s) ) ; } +} ; + +} // namespace numeric + +} // namespace boost + + + +// +// (3) Define suitable range checkers +//+// By default, if a UDT is involved in a conversion, internal range checking is disabled. +// This is so because a UDT type can have any sort of range, even unbounded, thus +// the library doesn't attempt to automatically figure out the appropriate range checking logic.
+// (as it does when builtin types are involved)+// However, this situation is a bit unsufficient in practice, specially from doing narrowing (subranged)
+// conversions from UDTs.+// The library provides a rudimentary hook to help this out: The user can plug in his own
+// range checker to the converter instance. +// +// This test shows how to define and use a custom range checker. +// + +namespace MyUDT { + +// +// The following are metaprogramming tools to allow us the implement the +// MyCustomRangeChecker generically, for either builtin or UDT types. +// + +// get_builtin_type<N>::type extracts the built-in type of our UDT's +// +template<class N> struct get_builtin_type { typedef N type ; } ; +template<> struct get_builtin_type<MyInt> { typedef int type ; } ; +template<> struct get_builtin_type<MyFloat> { typedef double type ; } ; ++// U extract_builtin ( T s ) returns 's' converted to the corresponding built-in type U.
+// +template<class N> +struct extract_builtin +{ + static N apply ( N n ) { return n ; } +} ; +template<> +struct extract_builtin<MyInt> +{ + static int apply ( MyInt const& n ) { return n.to_builtin() ; } +} ; +template<> +struct extract_builtin<MyFloat> +{ + static double apply ( MyFloat const& n ) { return n.to_builtin() ; } +} ; + +template<class Traits> +struct MyCustomRangeChecker +{ + typedef typename Traits::argument_type argument_type ; ++ // This custom range checker uses the fact that our 'fake' UDT are merely wrappers + // around builtin types; so it just forward the logic to the correspoding range
+ // checkers for the wrapped builtin types. + // + typedef typename Traits::source_type S ; + typedef typename Traits::target_type T ; + + // NOTE: S and/or T can be either UDT or builtin types. + + typedef typename get_builtin_type<S>::type builtinS ; + typedef typename get_builtin_type<T>::type builtinT ; ++ // NOTE: The internal range checker used by default is *built* when you instantiate + // a converter<> with a given Traits according to the properties of the involved types. + // Currently, there is no way to instantiate this range checker as a separate class.
+ // However, you can see it as part of the interface of the converter + // (since the converter inherits from it)+ // Therefore, here we instantiate a converter corresponding to the builtin types to access
+ // their associated builtin range checker. + // + typedef boost::numeric::converter<builtinT,builtinS> InternalConverter ; + + static range_check_result out_of_range ( argument_type s ) + {+ return InternalConverter::out_of_range( extract_builtin<S>::apply(s) );
+ } + + static void validate_range ( argument_type s ) + {+ return InternalConverter::validate_range( extract_builtin<S>::apply(s) );
+ } +} ; + +} // namespace MyUDT + + + + + + + + +// +// Test here +// + +void test_udt_conversions_with_defaults() +{ + cout << "Testing UDT conversion with default policies\n" ; + + // MyInt <--> int + + int mibv = rand(); + MyInt miv(mibv); + TEST_SUCCEEDING_CONVERSION_DEF(MyInt,int,miv,mibv); + TEST_SUCCEEDING_CONVERSION_DEF(int,MyInt,mibv,miv); + + // MyFloat <--> double + + double mfbv = static_cast<double>(rand()) / 3.0 ; + MyFloat mfv (mfbv); + TEST_SUCCEEDING_CONVERSION_DEF(MyFloat,double,mfv,mfbv); + TEST_SUCCEEDING_CONVERSION_DEF(double,MyFloat,mfbv,mfv); + + // MyInt <--> MyFloat + + MyInt miv2 ( static_cast<int>(mfbv) ); + MyFloat miv2F ( static_cast<int>(mfbv) ); + MyFloat mfv2 ( static_cast<double>(mibv) ); + MyInt mfv2I ( static_cast<double>(mibv) ); + TEST_SUCCEEDING_CONVERSION_DEF(MyFloat,MyInt,miv2F,miv2); + TEST_SUCCEEDING_CONVERSION_DEF(MyInt,MyFloat,mfv2I,mfv2); +} + +template<class T, class S> +struct GenerateCustomConverter +{ + typedef conversion_traits<T,S> Traits; + + typedef def_overflow_handler OverflowHandler ; + typedef Trunc<S> Float2IntRounder ; + typedef raw_converter<Traits> RawConverter ; + typedef MyCustomRangeChecker<Traits> RangeChecker ; ++ typedef converter<T,S,Traits,OverflowHandler,Float2IntRounder,RawConverter,RangeChecker> type ;
+} ; + +void test_udt_conversions_with_custom_range_checking() +{ + cout << "Testing UDT conversions with custom range checker\n" ; + + int mibv = rand(); + MyFloat mfv ( static_cast<double>(mibv) ); + + typedef GenerateCustomConverter<MyFloat,int>::type int_to_MyFloat_Conv ; ++ TEST_SUCCEEDING_CONVERSION( int_to_MyFloat_Conv, MyFloat, int, mfv, mibv );
+ + int mibv2 = rand(); + MyInt miv (mibv2); + MyFloat mfv2 ( static_cast<double>(mibv2) ); ++ typedef GenerateCustomConverter<MyFloat,MyInt>::type MyInt_to_MyFloat_Conv ;
++ TEST_SUCCEEDING_CONVERSION( MyInt_to_MyFloat_Conv, MyFloat, MyInt, mfv2, miv );
+ + double mfbv = bounds<double>::highest();+ typedef GenerateCustomConverter<MyInt,double>::type double_to_MyInt_Conv ;
++ TEST_POS_OVERFLOW_CONVERSION( double_to_MyInt_Conv, MyInt, double, mfbv );
+ + MyFloat mfv3 ( bounds<double>::lowest() ) ; + typedef GenerateCustomConverter<int,MyFloat>::type MyFloat_to_int_Conv ; + + TEST_NEG_OVERFLOW_CONVERSION( MyFloat_to_int_Conv, int, MyFloat, mfv3 ); +} + + +int test_main( int, char* [] ) +{ + cout << setprecision( numeric_limits<long double>::digits10 ) ; + + test_udt_conversions_with_defaults(); + test_udt_conversions_with_custom_range_checking(); + + return 0; +} + + + + + + ======================================= --- /dev/null +++ /trunk/libs/optional/doc/Jamfile.v2 Mon Feb 8 07:24:10 2010 @@ -0,0 +1,35 @@ +# 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) + + +# Quickbook+# -----------------------------------------------------------------------------
+ +import quickbook ; + +path-constant images : html ; + +xml optional + : + optional.qbk + ; + +boostbook standalone + : + optional + : + <xsl:param>boost.root=../../../.. + <xsl:param>boost.libraries=../../../libraries.htm + <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/optional/doc/html
+ ; + + ======================================= --- /dev/null +++ /trunk/libs/optional/doc/acknowledgments.qbk Mon Feb 8 07:24:10 2010 @@ -0,0 +1,60 @@ +[/ + 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 Acknowledgments] + +[heading Pre-formal review] + +* Peter Dimov suggested the name 'optional', and was the first to point out +the need for aligned storage. +* Douglas Gregor developed 'type_with_alignment', and later Eric Friedman +coded 'aligned_storage', which are the core of the optional class +implementation. +* Andrei Alexandrescu and Brian Parker also worked with aligned storage +techniques and their work influenced the current implementation. +* Gennadiy Rozental made extensive and important comments which shaped the +design. +* Vesa Karvonen and Douglas Gregor made quite useful comparisons between +optional, variant and any; and made other relevant comments. +* Douglas Gregor and Peter Dimov commented on comparisons and evaluation +in boolean contexts. +* Eric Friedman helped understand the issues involved with aligned storage, +move/copy operations and exception safety. +* Many others have participated with useful comments: Aleksey Gurotov, +Kevlin Henney, David Abrahams, and others I can't recall. + +[heading Post-formal review] + +* William Kempf carefully considered the originally proposed interface+and suggested the new interface which is currently used. He also started and
+fueled the discussion about the analogy optional<>/smart pointer and about +relational operators. +* Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson +focused on the relational semantics of optional (originally undefined); +concluding with the fact that the pointer-like interface doesn't make it a +pointer so it shall have deep relational operators.+* Augustus Saunders also explored the different relational semantics between +optional<> and a pointer and developed the OptionalPointee concept as an aid
+against potential conflicts on generic code. +* Joel de Guzman noticed that optional<> can be seen as an API on top of +variant<T,nil_t>. +* Dave Gomboc explained the meaning and usage of the Haskell analog to +optional<>: the Maybe type constructor (analogy originally pointed out by +David Sankel). +* Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, +Rob Stewart, and others. +* Joel de Guzman made the case for the support of references and helped +with the proper semantics. +* Mat Marcus shown the virtues of a value-oriented interface, influencing +the current design, and contributed the idea of "none". + +[endsect] + ======================================= --- /dev/null +++ /trunk/libs/optional/doc/dependencies.qbk Mon Feb 8 07:24:10 2010 @@ -0,0 +1,17 @@ +[/ + 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 Dependencies and Portability] + +The implementation uses `type_traits/alignment_of.hpp` and +`type_traits/type_with_alignment.hpp` + +[endsect] ======================================= --- /dev/null +++ /trunk/libs/optional/doc/development.qbk Mon Feb 8 07:24:10 2010 @@ -0,0 +1,251 @@ +[/ + 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 Development] + +[section The models] ++In C++, we can ['declare] an object (a variable) of type `T`, and we can give this
+variable an ['initial value] (through an ['initializer]. (c.f. 8.5)).+When a declaration includes a non-empty initializer (an initial value is given),
+it is said that the object has been initialized.+If the declaration uses an empty initializer (no initial value is given), and +neither default nor value initialization applies, it is said that the object is +[*uninitialized]. Its actual value exist but has an ['indeterminate initial value]
+(c.f. 8.5.9).+`optional<T>` intends to formalize the notion of initialization (or lack of it) +allowing a program to test whether an object has been initialized and stating +that access to the value of an uninitialized object is undefined behavior. That +is, when a variable is declared as `optional<T>` and no initial value is given, +the variable is ['formally] uninitialized. A formally uninitialized optional object +has conceptually no value at all and this situation can be tested at runtime. It +is formally ['undefined behavior] to try to access the value of an uninitialized +optional. An uninitialized optional can be assigned a value, in which case its initialization state changes to initialized. Furthermore, given the formal +treatment of initialization states in optional objects, it is even possible to
+reset an optional to ['uninitialized]. + +In C++ there is no formal notion of uninitialized objects, which means that +objects always have an initial value even if indeterminate. +As discussed on the previous section, this has a drawback because you need+additional information to tell if an object has been effectively initialized. +One of the typical ways in which this has been historically dealt with is via
+a special value: `EOF`, `npos`, -1, etc... This is equivalent to adding the+special value to the set of possible values of a given type. This super set of +`T` plus some ['nil_t]—were `nil_t` is some stateless POD-can be modeled in modern +languages as a [*discriminated union] of T and nil_t. Discriminated unions are +often called ['variants]. A variant has a ['current type], which in our case is either
+`T` or `nil_t`.+Using the __BOOST_VARIANT__ library, this model can be implemented in terms of `boost::variant<T,nil_t>`. +There is precedent for a discriminated union as a model for an optional value: +the __HASKELL__ [*Maybe] built-in type constructor. Thus, a discriminated union
+`T+nil_t` serves as a conceptual foundation. ++A `variant<T,nil_t>` follows naturally from the traditional idiom of extending
+the range of possible values adding an additional sentinel value with the+special meaning of ['Nothing]. However, this additional ['Nothing] value is largely
+irrelevant for our purpose since our goal is to formalize the notion of+uninitialized objects and, while a special extended value can be used to convey
+that meaning, it is not strictly necessary in order to do so. ++The observation made in the last paragraph about the irrelevant nature of the
+additional `nil_t` with respect to [_purpose] of `optional<T>` suggests an+alternative model: a ['container] that either has a value of `T` or nothing.
+ +As of this writing I don't know of any precedence for a variable-size+fixed-capacity (of 1) stack-based container model for optional values, yet I
+believe this is the consequence of the lack of practical implementations of+such a container rather than an inherent shortcoming of the container model.
+ +In any event, both the discriminated-union or the single-element container +models serve as a conceptual ground for a class representing optional—i.e. +possibly uninitialized—objects.+For instance, these models show the ['exact] semantics required for a wrapper
+of optional values: + +Discriminated-union: ++* [*deep-copy] semantics: copies of the variant implies copies of the value.
+* [*deep-relational] semantics: comparisons between variants matches both +current types and values+* If the variant's current type is `T`, it is modeling an ['initialized] optional. +* If the variant's current type is not `T`, it is modeling an ['uninitialized]
+optional.+* Testing if the variant's current type is `T` models testing if the optional
+is initialized+* Trying to extract a `T` from a variant when its current type is not `T`, models +the undefined behavior of trying to access the value of an uninitialized optional
+ +Single-element container: ++* [*deep-copy] semantics: copies of the container implies copies of the value. +* [*deep-relational] semantics: comparisons between containers compare container
+size and if match, contained value+* If the container is not empty (contains an object of type `T`), it is modeling
+an ['initialized] optional. +* If the container is empty, it is modeling an ['uninitialized] optional. +* Testing if the container is empty models testing if the optional is +initialized+* Trying to extract a `T` from an empty container models the undefined behavior
+of trying to access the value of an uninitialized optional + +[endsect] + +[section The semantics] ++Objects of type `optional<T>` are intended to be used in places where objects of +type `T` would but which might be uninitialized. Hence, `optional<T>`'s purpose is
+to formalize the additional possibly uninitialized state.+From the perspective of this role, `optional<T>` can have the same operational +semantics of `T` plus the additional semantics corresponding to this special
+state.+As such, `optional<T>` could be thought of as a ['supertype] of `T`. Of course, we
+can't do that in C++, so we need to compose the desired semantics using a +different mechanism.+Doing it the other way around, that is, making `optional<T>` a ['subtype] of `T`
+is not only conceptually wrong but also impractical: it is not allowed to +derive from a non-class type, such as a built-in type. + +We can draw from the purpose of `optional<T>` the required basic semantics: + +* [*Default Construction:] To introduce a formally uninitialized wrapped +object.+* [*Direct Value Construction via copy:] To introduce a formally initialized
+wrapped object whose value is obtained as a copy of some object. +* [*Deep Copy Construction:] To obtain a new yet equivalent wrapped object. +* [*Direct Value Assignment (upon initialized):] To assign a value to the +wrapped object.+* [*Direct Value Assignment (upon uninitialized):] To initialize the wrapped
+object with a value obtained as a copy of some object.+* [*Assignment (upon initialized):] To assign to the wrapped object the value
+of another wrapped object. +* [*Assignment (upon uninitialized):] To initialize the wrapped object with +value of another wrapped object. +* [*Deep Relational Operations (when supported by the type T):] To compare+wrapped object values taking into account the presence of uninitialized states.
+* [*Value access:] To unwrap the wrapped object. +* [*Initialization state query:] To determine if the object is formally +initialized or not. +* [*Swap:] To exchange wrapped objects. (with whatever exception safety +guarantees are provided by `T`'s swap).+* [*De-initialization:] To release the wrapped object (if any) and leave the
+wrapper in the uninitialized state. + +Additional operations are useful, such as converting constructors and +converting assignments, in-place construction and assignment, and safe +value access via a pointer to the wrapped object or null. + +[endsect] + +[section The Interface] + +Since the purpose of optional is to allow us to use objects with a formal +uninitialized additional state, the interface could try to follow the+interface of the underlying `T` type as much as possible. In order to choose +the proper degree of adoption of the native `T` interface, the following must +be noted: Even if all the operations supported by an instance of type `T` are
+defined for the entire range of values for such a type, an `optional<T>` +extends such a set of values with a new value for which most +(otherwise valid) operations are not defined in terms of `T`. ++Furthermore, since `optional<T>` itself is merely a `T` wrapper (modeling a `T` +supertype), any attempt to define such operations upon uninitialized optionals
+will be totally artificial w.r.t. `T`. ++This library chooses an interface which follows from `T`'s interface only for +those operations which are well defined (w.r.t the type `T`) even if any of the
+operands are uninitialized. These operations include: construction, +copy-construction, assignment, swap and relational operations. ++For the value access operations, which are undefined (w.r.t the type `T`) when +the operand is uninitialized, a different interface is chosen (which will be
+explained next). + +Also, the presence of the possibly uninitialized state requires additional+operations not provided by `T` itself which are supported by a special interface.
+ +[heading Lexically-hinted Value Access in the presence of possibly +untitialized optional objects: The operators * and ->] ++A relevant feature of a pointer is that it can have a [*null pointer value]. +This is a ['special] value which is used to indicate that the pointer is not
+referring to any object at all. In other words, null pointer values convey +the notion of inexistent objects. + +This meaning of the null pointer value allowed pointers to became a ['de +facto] standard for handling optional objects because all you have to do +to refer to a value which you don't really have is to use a null pointer +value of the appropriate type. Pointers have been used for decades—from+the days of C APIs to modern C++ libraries—to ['refer] to optional (that is,
+possibly inexistent) objects; particularly as optional arguments to a +function, but also quite often as optional data members. + +The possible presence of a null pointer value makes the operations that +access the pointee's value possibly undefined, therefore, expressions which+use dereference and access operators, such as: `( *p = 2 )` and `( p->foo() )`, +implicitly convey the notion of optionality, and this information is tied to +the ['syntax] of the expressions. That is, the presence of operators `*` and `->` +tell by themselves —without any additional context— that the expression will
+be undefined unless the implied pointee actually exist. ++Such a ['de facto] idiom for referring to optional objects can be formalized
+in the form of a concept: the __OPTIONAL_POINTEE__ concept. +This concept captures the syntactic usage of operators `*`, `->` and +conversion to `bool` to convey the notion of optionality. ++However, pointers are good to [_refer] to optional objects, but not particularly +good to handle the optional objects in all other respects, such as initializing
+or moving/copying them. The problem resides in the shallow-copy of pointer+semantics: if you need to effectively move or copy the object, pointers alone +are not enough. The problem is that copies of pointers do not imply copies of
+pointees. For example, as was discussed in the motivation, pointers alone+cannot be used to return optional objects from a function because the object
+must move outside from the function and into the caller's context. + +A solution to the shallow-copy problem that is often used is to resort to+dynamic allocation and use a smart pointer to automatically handle the details +of this. For example, if a function is to optionally return an object `X`, it can +use `shared_ptr<X>` as the return value. However, this requires dynamic allocation +of `X`. If `X` is a built-in or small POD, this technique is very poor in terms of
+required resources. Optional objects are essentially values so it is very +convenient to be able to use automatic storage and deep-copy semantics to +manipulate optional values just as we do with ordinary values. Pointers do +not have this semantics, so are inappropriate for the initialization and+transport of optional values, yet are quite convenient for handling the access
+to the possible undefined value because of the idiomatic aid present in the +__OPTIONAL_POINTEE__ concept incarnated by pointers. + + +[heading Optional<T> as a model of OptionalPointee] + +For value access operations `optional<>` uses operators `*` and `->` to +lexically warn about the possibly uninitialized state appealing to the +familiar pointer semantics w.r.t. to null pointers. + +[warning +However, it is particularly important to note that `optional<>` objects +are not pointers. [_`optional<>` is not, and does not model, a pointer]. +] + +For instance, `optional<>` does not have shallow-copy so does not alias:+two different optionals never refer to the ['same] value unless `T` itself is
+a reference (but may have ['equivalent] values). +The difference between an `optional<T>` and a pointer must be kept in mind, +particularly because the semantics of relational operators are different: +since `optional<T>` is a value-wrapper, relational operators are deep: they +compare optional values; but relational operators for pointers are shallow: +they do not compare pointee values. +As a result, you might be able to replace `optional<T>` by `T*` on some +situations but not always. Specifically, on generic code written for both, +you cannot use relational operators directly, and must use the template+functions __FUNCTION_EQUAL_POINTEES__ and __FUNCTION_LESS_POINTEES__ instead.
+ +[endsect] + +[endsect] ======================================= --- /dev/null +++ /trunk/libs/optional/doc/examples.qbk Mon Feb 8 07:24:10 2010 @@ -0,0 +1,102 @@ +[/ + 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 Examples] + +[section Optional return values] + + optional<char> get_async_input() + { + if ( !queue.empty() ) + return optional<char>(queue.top()); + else return optional<char>(); // uninitialized + } + + void receive_async_message() + { + optional<char> rcv ; + // The safe boolean conversion from 'rcv' is used here. + while ( (rcv = get_async_input()) && !timeout() ) + output(*rcv); + } + +[endsect] + +[section Optional local variables] + + optional<string> name ; + if ( database.open() ) + { + name.reset ( database.lookup(employer_name) ) ; + } + else + { + if ( can_ask_user ) + name.reset ( user.ask(employer_name) ) ; + } + + if ( name ) + print(*name); + else print("employer's name not found!"); + +[endsect] + +[section Optional data members] + + class figure + { + public: + + figure() + {+ // data member 'm_clipping_rect' is uninitialized at this point.
+ } + + void clip_in_rect ( rect const& rect ) + { + .... + m_clipping_rect.reset ( rect ) ; // initialized here. + } + + void draw ( canvas& cvs ) + { + if ( m_clipping_rect ) + do_clipping(*m_clipping_rect); + + cvs.drawXXX(..); + } + + // this can return NULL.+ rect const* get_clipping_rect() { return get_pointer(m_clipping_rect); }
+ + private : + + optional<rect> m_clipping_rect ; + + }; + +[endsect] + +[section Bypassing expensive unnecessary default construction] + + class ExpensiveCtor { ... } ; + class Fred + { + Fred() : mLargeVector(10000) {} + + std::vector< optional<ExpensiveCtor> > mLargeVector ; + } ; + +[endsect] + +[endsect] + + ======================================= ***Additional files exist in this changeset.***