This commit was manufactured by cvs2svn to create branch 'mpl_v2_2'.

[SVN r18675]
This commit is contained in:
nobody
2003-06-05 05:15:05 +00:00
parent 386d7a67d6
commit 60b527f7b8
9 changed files with 0 additions and 1259 deletions

150
cast.htm
View File

@@ -1,150 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Header boost/cast.hpp Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Header
<a href="../../boost/cast.hpp">boost/cast.hpp</a></h1>
<h2><a name="Cast Functions">Cast Functions</a></h2>
<p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a>
provides <a href="#Polymorphic_cast"><b>polymorphic_cast</b></a>, <a href="#Polymorphic_cast"><b>polymorphic_downcast</b></a>,
and <a href="#numeric_cast"><b>numeric_cast</b></a> function templates designed
to complement the C++ built-in casts.</p>
<p>The program <a href="cast_test.cpp">cast_test.cpp</a> can be used to
verify these function templates work as expected.</p>
<h3><a name="Polymorphic_cast">Polymorphic casts</a></h3>
<p>Pointers to polymorphic objects (objects of classes which define at least one
virtual function) are sometimes downcast or crosscast. Downcasting means
casting from a base class to a derived class. Crosscasting means casting
across an inheritance hierarchy diagram, such as from one base to the other in a
<b>Y</b> diagram hierarchy.</p>
<p>Such casts can be done with old-style casts, but this approach is never to be
recommended. Old-style casts are sorely lacking in type safety, suffer
poor readability, and are difficult to locate with search tools.</p>
<p>The C++ built-in <b>static_cast</b> can be used for efficiently downcasting
pointers to polymorphic objects, but provides no error detection for the case
where the pointer being cast actually points to the wrong derived class. The <b>polymorphic_downcast</b>
template retains the efficiency of <b>static_cast</b> for non-debug
compilations, but for debug compilations adds safety via an assert() that a <b>dynamic_cast</b>
succeeds.</p>
<p>The C++ built-in <b>dynamic_cast</b> can be used for downcasts and crosscasts
of pointers to polymorphic objects, but error notification in the form of a
returned value of 0 is inconvenient to test, or worse yet, easy to forget to
test. The <b>polymorphic_cast</b> template performs a <b>dynamic_cast</b>,
and throws an exception if the <b>dynamic_cast</b> returns 0.</p>
<p>A <b>polymorphic_downcast</b> is preferred when debug-mode tests will cover
100% of the object types possibly cast and when non-debug-mode efficiency is an
issue. If these two conditions are not present, <b>polymorphic_cast</b> is
preferred. It must also be used for crosscasts. It does an assert(
dynamic_cast&lt;Derived&gt;(x) == x ) where x is the base pointer, ensuring that
not only is a non-zero pointer returned, but also that it correct in the
presence of multiple inheritance.<b> Warning:</b>: Because <b>polymorphic_downcast</b>
uses assert(), it violates the one definition rule (ODR) if NDEBUG is inconsistently
defined across translation units. [See ISO Std 3.2]</p>
<p>The C++ built-in <b>dynamic_cast</b> must be used to cast references rather
than pointers. It is also the only cast that can be used to check whether
a given interface is supported; in that case a return of 0 isn't an error
condition.</p>
<h3>polymorphic_cast and polymorphic_downcast synopsis</h3>
<blockquote>
<pre>namespace boost {
template &lt;class Derived, class Base&gt;
inline Derived polymorphic_cast(Base* x);
// Throws: std::bad_cast if ( dynamic_cast&lt;Derived&gt;(x) == 0 )
// Returns: dynamic_cast&lt;Derived&gt;(x)
template &lt;class Derived, class Base&gt;
inline Derived polymorphic_downcast(Base* x);
// Effects: assert( dynamic_cast&lt;Derived&gt;(x) == x );
// Returns: static_cast&lt;Derived&gt;(x)
}</pre>
</blockquote>
<h3>polymorphic_downcast example</h3>
<blockquote>
<pre>#include &lt;boost/cast.hpp&gt;
...
class Fruit { public: virtual ~Fruit(){}; ... };
class Banana : public Fruit { ... };
...
void f( Fruit * fruit ) {
// ... logic which leads us to believe it is a Banana
Banana * banana = boost::polymorphic_downcast&lt;Banana*&gt;(fruit);
...</pre>
</blockquote>
<h3><a name="numeric_cast">numeric_cast</a></h3>
<p>A <b>static_cast</b> or implicit conversion will not
detect failure to preserve range for numeric casts. The <b>numeric_cast</b> function
templates are similar to <b>static_cast</b> and certain (dubious)
implicit conversions in this respect, except that they detect loss of numeric
range. An exception is thrown when a runtime value-preservation check fails.</p>
<p>The requirements on the argument and result types are:</p>
<blockquote>
<ul>
<li>Both argument and result types are CopyConstructible [ISO Std 20.1.3].</li>
<li>Both argument and result types are Numeric, defined by <code>std::numeric_limits&lt;&gt;::is_specialized</code>
being true.</li>
<li>The argument can be converted to the result type using <b>static_cast</b>.</li>
</ul>
</blockquote>
<h3>numeric_cast synopsis</h3>
<blockquote>
<pre>namespace boost {
class bad_numeric_cast : public std::bad_cast {...};
template&lt;typename Target, typename Source&gt;
inline Target numeric_cast(Source arg);
// Throws: bad_numeric_cast unless, in converting arg from Source to Target,
// there is no loss of negative range, and no underflow, and no
// overflow, as determined by std::numeric_limits
// Returns: static_cast&lt;Target&gt;(arg)
}</pre>
</blockquote>
<h3>numeric_cast example</h3>
<blockquote>
<pre>#include &lt;boost/cast.hpp&gt;
using namespace boost::cast;
void ariane(double vx)
{
...
unsigned short dx = numeric_cast&lt;unsigned short&gt;(vx);
...
}</pre>
</blockquote>
<h3>numeric_cast rationale</h3>
<p>The form of the throws condition is specified so that != is not a required
operation.</p>
<h3>History</h3>
<p><b>polymorphic_cast</b> was suggested by Bjarne Stroustrup in &quot;The C++
Programming Language&quot;.<br>
<b>polymorphic_downcast</b> was contributed by <a href="../../people/dave_abrahams.htm">Dave
Abrahams</a>.<b><br>
numeric_cast</b> was contributed by <a href="../../people/kevlin_henney.htm">Kevlin
Henney</a>.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
-->06 January, 2001<!--webbot bot="Timestamp" endspan i-checksum="38320"
--></p>
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
distribute this document is granted provided this copyright notice appears in
all copies. This document is provided &quot;as is&quot; without express or
implied warranty, and with no claim as to its suitability for any purpose.</p>
</body>
</html>

View File

@@ -1,154 +0,0 @@
// boost utility cast test program -----------------------------------------//
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright
// notice appears in all copies. This software is provided "as is" without
// express or implied warranty, and with no claim as to its suitability for
// any purpose.
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 20 Jan 01 removed use of <limits> for portability to raw GCC (David Abrahams)
// 28 Jun 00 implicit_cast removed (Beman Dawes)
// 30 Aug 99 value_cast replaced by numeric_cast
// 3 Aug 99 Initial Version
#include <iostream>
#include <climits>
#include <cfloat> // for DBL_MAX (Peter Schmid)
#include <boost/cast.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;
namespace
{
struct Base
{
virtual char kind() { return 'B'; }
};
struct Base2
{
virtual char kind2() { return '2'; }
};
struct Derived : public Base, Base2
{
virtual char kind() { return 'D'; }
};
}
int main( int argc, char * argv[] )
{
cout << "Usage: test_casts [n], where n omitted or is:\n"
" 1 = execute #1 assert failure (#ifndef NDEBUG)\n"
" 2 = execute #2 assert failure (#ifndef NDEBUG)\n"
"Example: test_casts 2\n\n";
# ifdef NDEBUG
cout << "NDEBUG is defined\n";
# else
cout << "NDEBUG is not defined\n";
# endif
cout << "\nBeginning tests...\n";
// test polymorphic_cast ---------------------------------------------------//
// tests which should succeed
Base * base = new Derived;
Base2 * base2 = 0;
Derived * derived = 0;
derived = polymorphic_downcast<Derived*>( base ); // downcast
assert( derived->kind() == 'D' );
derived = 0;
derived = polymorphic_cast<Derived*>( base ); // downcast, throw on error
assert( derived->kind() == 'D' );
base2 = polymorphic_cast<Base2*>( base ); // crosscast
assert( base2->kind2() == '2' );
// tests which should result in errors being detected
int err_count = 0;
base = new Base;
if ( argc > 1 && *argv[1] == '1' )
{ derived = polymorphic_downcast<Derived*>( base ); } // #1 assert failure
bool caught_exception = false;
try { derived = polymorphic_cast<Derived*>( base ); }
catch (std::bad_cast)
{ cout<<"caught bad_cast\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
// the following is just so generated code can be inspected
if ( derived->kind() == 'B' ) ++err_count;
// 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 );
assert( c == 1 );
c = 0;
c = numeric_cast<signed char>( small_value );
assert( c == 1 );
c = 0;
c = numeric_cast<signed char>( small_negative_value );
assert( c == -1 );
// These tests courtesy of Joe R NWP Swatosh<joe.r.swatosh@usace.army.mil>
assert( 0.0f == numeric_cast<float>( 0.0 ) );
assert( 0.0 == numeric_cast<double>( 0.0 ) );
// tests which should result in errors being detected
caught_exception = false;
try { c = numeric_cast<signed char>( large_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #1\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
caught_exception = false;
try { c = numeric_cast<signed char>( large_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #2\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
unsigned long ul;
caught_exception = false;
try { ul = numeric_cast<unsigned long>( large_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #3\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
caught_exception = false;
try { ul = numeric_cast<unsigned long>( small_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #4\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
caught_exception = false;
try { numeric_cast<int>( DBL_MAX ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
cout << err_count << " errors detected\nTest "
<< (err_count==0 ? "passed\n" : "failed\n");
return err_count;
} // main

View File

@@ -1,39 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost Conversion Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img border="0" src="../../c++boost.gif" align="center" width="277" height="86">Boost
Conversion Library</h1>
<p>The Conversion Library improves program safety and clarity by performing
otherwise messy conversions.&nbsp; It includes cast-style function templates designed to complement the C++
Standard's built-in casts.</p>
<p>To reduce coupling, particularly to standard library IOStreams, the Boost
Conversion Library is
supplied by several headers:</p>
<ul>
<li>The <a href="cast.htm">boost/cast</a> header provides <b>polymorphic_cast&lt;&gt;</b>
and <b>polymorphic_downcast&lt;&gt;</b> to perform safe casting between
polymorphic types, and <b> numeric_cast</b><i>&lt;&gt;</i> to perform safe casting
between numeric types.<br>
</li>
<li>The <a href="lexical_cast.htm">boost/lexical_cast</a> header provides <b>lexical_cast&lt;&gt;</b>
general literal text conversions, such as an <code>int</code> represented as
a <code>string</code>, or vice-versa.</li>
</ul>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED"
S-Format="%d %B, %Y" startspan -->06 January, 2001<!--webbot bot="Timestamp" endspan i-checksum="38320" -->
</p>
</body>
</html>

View File

@@ -1,223 +0,0 @@
<!-- saved from url=(0022)http://internet.e-mail -->
<!doctype html public "-//W3C//DTD HTML Transitional 4.0//EN">
<html>
<head>
<title>lexical_cast</title>
<meta name="author" content="Kevlin Henney, mailto:kevlin@curbralan.com">
<meta name="generator" content="Microsoft FrontPage 4.0">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">Header
<a href="../../boost/lexical_cast.hpp">boost/lexical_cast.hpp</a></h1>
<ul type="square">
<li>
<a href="#motivation">Motivation</a></li>
<li>
<a href="#examples">Examples</a></li>
<li>
<a href="#synopsis">Synopsis</a></li>
<li>
<a href="#lexical_cast"><code>lexical_cast</code></a></li>
<li>
<a href="#bad_lexical_cast"><code>bad_lexical_cast</code></a></li>
<li>
<a href="#changes">Changes</a></li>
</ul>
<hr>
<h2><a name="motivation">Motivation</a></h2>
Sometimes a value must be converted to a literal text form, such as an <code>int</code>
represented as a <code>string</code>, or vice-versa, when a <code>string</code>
is interpreted as an <code>int</code>. Such examples are common when converting
between data types internal to a program and representation external to a
program, such as windows and configuration files.
<p>
The standard C and C++ libraries offer a number of facilities for performing
such conversions. However, they vary with their ease of use, extensibility, and
safety.
<p>
For instance, there are a number of limitations with the family of standard C
functions typified by <code>atoi</code>:
<ul type="square">
<li>
Conversion is supported in one direction only: from text to internal data type.
Converting the other way using the C library requires either the inconvenience
and compromised safety of the <code>sprintf</code> function, or the loss of
portability associated with non-standard functions such as <code>itoa</code>.
</li>
<li>
The range of types supported is only a subset of the built-in numeric types,
namely <code>int</code>, <code>long</code>, and <code>double</code>.
</li>
<li>
The range of types cannot be extended in a uniform manner. For instance,
conversion from string representation to <code>complex</code> or <code>rational</code>.
</li>
</ul>
The standard C functions typified by <code>strtol</code> have the same basic
limitations, but offer finer control over the conversion process. However, for
the common case such control is often either not required or not used. The <code>scanf</code>
family of functions offer even greater control, but also lack safety and ease
of use.
<p>
The standard C++ library offers <code>stringstream</code> for the kind of
in-core formatting being discussed. It offers a great deal of control over the
formatting and conversion of I/O to and from arbitrary types through text.
However, for simple conversions direct use of <code>stringstream</code> can be
either clumsy (with the introduction of extra local variables and the loss of
infix-expression convenience) or obscure (where <code>stringstream</code>
objects are created as temporary objects in an expression). Facets provide a
comprehensive concept and facility for controlling textual representation, but
their perceived complexity and high entry level requires an extreme degree of
involvement for simple conversions, and excludes all but a few programmers.
<p>
The <code>lexical_cast</code> function template offers a convenient and
consistent form for supporting common conversions to and from arbitrary types
when they are represented as text. The simplification it offers is in
expression-level convenience for such conversions. For more involved
conversions, such as where precision or formatting need tighter control than is
offered by the default behavior of <code>lexical_cast</code>, the conventional <code>
stringstream</code> approach is recommended. Where the conversions are
numeric to numeric, <code><a href="cast.htm#numeric_cast">numeric_cast</a></code>
may offer more reasonable behavior than <code>lexical_cast</code>.
<p>
For a good discussion of the options and issues involved in string-based
formatting, including comparison of <code>stringstream</code>, <code>lexical_cast</code>,
and others, see Herb Sutter's article, <a href="http://www.gotw.ca/publications/mill19.htm">
<i>The String Formatters of Manor Farm</i></a>.
<p>
<hr>
<h2><a name="examples">Examples</a></h2>
The following example treats command line arguments as a sequence of numeric
data: <blockquote>
<pre>
int main(int argc, char * argv[])
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
std::vector&lt;short&gt; args;
while(*++argv)
{
try
{
args.push_back(lexical_cast&lt;short&gt;(*argv));
}
catch(bad_lexical_cast &amp;)
{
args.push_back(0);
}
}
...
}
</pre>
</blockquote>The following example uses numeric data in a string expression: <blockquote>
<pre>
void log_message(const std::string &amp;);
void log_errno(int yoko)
{
log_message(&quot;Error &quot; + boost::lexical_cast&lt;std::string&gt;(yoko) + &quot;: &quot; + strerror(yoko));
}
</pre>
</blockquote>
<hr>
<h2><a name="synopsis">Synopsis</a></h2>
Library features defined in <a href="../../boost/lexical_cast.hpp"><code>&quot;boost/lexical_cast.hpp&quot;</code></a>:
<blockquote>
<pre>
namespace boost
{
class <a href="#bad_lexical_cast">bad_lexical_cast</a>;
template&lt;typename Target, typename Source&gt;
Target <a href="#lexical_cast">lexical_cast</a>(Source arg);
}
</pre>
</blockquote>Unit test defined in <a href="lexical_cast_test.cpp"><code>&quot;lexical_cast_test.cpp&quot;</code></a>.
<p>
<hr>
<h2><a name="lexical_cast"><code>lexical_cast</code></a></h2>
<blockquote>
<pre>
template&lt;typename Target, typename Source&gt;
Target lexical_cast(Source arg);
</pre>
</blockquote>Returns the result of streaming <code>arg</code> into a
standard library string-based stream and then out as a <code>Target</code> object.
Where <code>Target</code> is either <code>std::string</code>
or <code>std::wstring</code>, stream extraction takes the whole content
of the string, including spaces, rather than relying on the default
<code>operator&gt;&gt;</code> behavior.
If the conversion is unsuccessful, a <a href="#bad_lexical_cast">
<code>bad_lexical_cast</code></a> exception is thrown.
<p>
The requirements on the argument and result types are:
<ul type="square">
<li>
<code>Source</code> is <i>OutputStreamable</i>, meaning that an <code>operator&lt;&lt;</code>
is defined that takes a <code>std::ostream</code> or <code>std::wostream</code> object on the
left hand side and an instance of the argument type on the right.
</li>
<li>
<code>Target</code> is <i>InputStreamable</i>, meaning that an <code>operator&gt;&gt;</code>
is defined that takes a <code>std::istream</code> or <code>std::wistream</code> object on the left hand side
and an instance of the result type on the right.
</li>
<li>
Both <code>Source</code> and <code>Target</code> are <i>CopyConstructible</i> [20.1.3].
</li>
<li>
<code>Target</code> is <i>DefaultConstructible</i>, meaning that it is possible
to <i>default-initialize</i> an object of that type [8.5, 20.1.4].
</li>
</ul>
The character type of the underlying stream is assumed to be <code>char</code> unless
either the <code>Source</code> or the <code>Target</code> requires wide-character
streaming, in which case the underlying stream uses <code>wchar_t</code>.
<code>Source</code> types that require wide-character streaming are <code>wchar_t</code>,
<code>wchar_t *</code>, and <code>std::wstring</code>. <code>Target</code> types that
require wide-character streaming are <code>wchar_t</code> and <code>std::wstring</code>.
<p>
Where a higher degree of control is required over conversions, <code>std::stringstream</code>
and <code>std::wstringstream</code> offer a more appropriate path. Where non-stream-based conversions are
required, <code>lexical_cast</code>
is the wrong tool for the job and is not special-cased for such scenarios.
<p>
<hr>
<h2><a name="bad_lexical_cast"><code>bad_lexical_cast</code></a></h2>
<blockquote>
<pre>
class bad_lexical_cast : public std::bad_cast
{
public:
... // <i>same member function interface as</i> std::exception
};
</pre>
</blockquote>Exception used to indicate runtime <a href="#lexical_cast"><code>lexical_cast</code></a>
failure.
<hr>
<h2><a name="changes">Changes</a></h2>
<ul type="square">
<li>The previous version of <code>lexical_cast</code> used the default stream precision for reading
and writing floating-point numbers. For numerics that have a corresponding specialization of
<code>std::numeric_limits</code>, the current version now chooses a precision to match.
<li>The previous version of <code>lexical_cast</code> did not support conversion to or from any
wide-character-based types. For compilers with full language and library support for wide characters,
<code>lexical_cast</code> now supports conversions from <code>wchar_t</code>, <code>wchar_t *</code>,
and <code>std::wstring</code> and to <code>wchar_t</code> and <code>std::wstring</code>.
<li>The previous version of <code>lexical_cast</code> assumed that the conventional stream extractor
operators were sufficient for reading values. However, string I/O is asymmetric, with the result
that spaces play the role of I/O separators rather than string content. The current version fixes
this error for <code>std::string</code> and, where supported, <code>std::wstring</code>:
<code>lexical_cast&lt;std::string&gt;("Hello, World")</code> succeeds instead of failing with
a <code>bad_lexical_cast</code> exception.
<li>The previous version of <code>lexical_cast</code> allowed unsafe and meaningless conversions to
pointers. The current version now throws a <code>bad_lexical_cast</code> for conversions to pointers:
<code>lexical_cast&lt;char *&gt;("Goodbye, World")</code> now throws an exception instead of
causing undefined behavior.
</ul>
<p>
<hr>
<div align="right"><small><i>&copy; Copyright Kevlin Henney, 2000&#150;2003</i></small></div>
</body>
</html>

View File

@@ -1,290 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Terje Sletteb<65> and Kevlin Henney, 2003.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/included/unit_test_framework.hpp>
#if defined(BOOST_NO_STRINGSTREAM) || \
defined(BOOST_NO_STD_WSTRING) || \
defined(BOOST_NO_STD_LOCALE) || \
defined(BOOST_NO_INTRINSIC_WCHAR_T)
#define DISABLE_WIDE_CHAR_SUPPORT
#endif
using namespace boost;
void test_conversion_to_char();
void test_conversion_to_int();
void test_conversion_to_double();
void test_conversion_to_bool();
void test_conversion_to_string();
void test_conversion_from_to_wchar_t_alias();
void test_conversion_to_pointer();
void test_conversion_from_wchar_t();
void test_conversion_to_wchar_t();
void test_conversion_from_wstring();
void test_conversion_to_wstring();
unit_test_framework::test_suite *init_unit_test_suite(int, char **)
{
unit_test_framework::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast unit test");
suite->add(BOOST_TEST_CASE(test_conversion_to_char));
suite->add(BOOST_TEST_CASE(test_conversion_to_int));
suite->add(BOOST_TEST_CASE(test_conversion_to_double));
suite->add(BOOST_TEST_CASE(test_conversion_to_bool));
suite->add(BOOST_TEST_CASE(test_conversion_from_to_wchar_t_alias));
suite->add(BOOST_TEST_CASE(test_conversion_to_pointer));
suite->add(BOOST_TEST_CASE(test_conversion_to_string));
#ifndef DISABLE_WIDE_CHAR_SUPPORT
suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t));
suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t));
suite->add(BOOST_TEST_CASE(test_conversion_from_wstring));
suite->add(BOOST_TEST_CASE(test_conversion_to_wstring));
#endif
return suite;
}
void test_conversion_to_char()
{
BOOST_CHECK_EQUAL('A', lexical_cast<char>('A'));
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(' '));
BOOST_CHECK_EQUAL('1', lexical_cast<char>(1));
BOOST_CHECK_EQUAL('0', lexical_cast<char>(0));
BOOST_CHECK_THROW(lexical_cast<char>(123), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL('1', lexical_cast<char>(1.0));
BOOST_CHECK_EQUAL('1', lexical_cast<char>(true));
BOOST_CHECK_EQUAL('0', lexical_cast<char>(false));
BOOST_CHECK_EQUAL('A', lexical_cast<char>("A"));
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(" "));
BOOST_CHECK_THROW(lexical_cast<char>(""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<char>("Test"), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL('A', lexical_cast<char>(std::string("A")));
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(std::string(" ")));
BOOST_CHECK_THROW(
lexical_cast<char>(std::string("")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<char>(std::string("Test")), boost::bad_lexical_cast);
}
void test_conversion_to_int()
{
BOOST_CHECK_EQUAL(1,lexical_cast<int>('1'));
BOOST_CHECK_EQUAL(0,lexical_cast<int>('0'));
BOOST_CHECK_THROW(lexical_cast<int>('A'),boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(1,lexical_cast<int>(1));
BOOST_CHECK_EQUAL(
std::numeric_limits<int>::max(),
lexical_cast<int>(std::numeric_limits<int>::max()));
BOOST_CHECK_EQUAL(1,lexical_cast<int>(1.0));
BOOST_CHECK_THROW(lexical_cast<int>(1.23), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(1e20), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(1, lexical_cast<int>(true));
BOOST_CHECK_EQUAL(0, lexical_cast<int>(false));
BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
BOOST_CHECK_THROW(
lexical_cast<int>(" 123"), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>("Test"), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
BOOST_CHECK_EQUAL(123,lexical_cast<int>(std::string("123")));
BOOST_CHECK_THROW(
lexical_cast<int>(std::string(" 123")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::string("")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::string("Test")), boost::bad_lexical_cast);
}
void test_conversion_to_double()
{
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>('1'));
BOOST_CHECK_THROW(lexical_cast<double>('A'), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(1));
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(1.23));
BOOST_CHECK_CLOSE(
std::numeric_limits<double>::max() / 2,
lexical_cast<double>(std::numeric_limits<double>::max() / 2),
std::numeric_limits<double>::epsilon());
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(true));
BOOST_CHECK_EQUAL(0.0, lexical_cast<double>(false));
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>("1.23"));
BOOST_CHECK_THROW(lexical_cast<double>(""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<double>("Test"), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(std::string("1.23")));
BOOST_CHECK_THROW(
lexical_cast<double>(std::string("")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<double>(std::string("Test")), boost::bad_lexical_cast);
}
void test_conversion_to_bool()
{
BOOST_CHECK_EQUAL(true, lexical_cast<bool>('1'));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>('0'));
BOOST_CHECK_THROW(lexical_cast<bool>('A'), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0));
BOOST_CHECK_THROW(lexical_cast<bool>(123), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1.0));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0.0));
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(true));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(false));
BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
BOOST_CHECK_THROW(lexical_cast<bool>(""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("Test"), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::string("1")));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::string("0")));
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("Test")), boost::bad_lexical_cast);
}
void test_conversion_to_string()
{
BOOST_CHECK_EQUAL("A", lexical_cast<std::string>('A'));
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(' '));
BOOST_CHECK_EQUAL("123", lexical_cast<std::string>(123));
BOOST_CHECK_EQUAL("1.23", lexical_cast<std::string>(1.23));
BOOST_CHECK_EQUAL("1.111111111", lexical_cast<std::string>(1.111111111));
BOOST_CHECK_EQUAL("1",lexical_cast<std::string>(true));
BOOST_CHECK_EQUAL("0",lexical_cast<std::string>(false));
BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>("Test"));
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(" "));
BOOST_CHECK_EQUAL("", lexical_cast<std::string>(""));
BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>(std::string("Test")));
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(std::string(" ")));
BOOST_CHECK_EQUAL("", lexical_cast<std::string>(std::string("")));
}
void test_conversion_from_to_wchar_t_alias()
{
BOOST_CHECK_EQUAL(123, lexical_cast<unsigned short>("123"));
BOOST_CHECK_EQUAL(123, lexical_cast<unsigned int>("123"));
BOOST_CHECK_EQUAL(123, lexical_cast<unsigned long>("123"));
BOOST_CHECK_EQUAL(std::string("123"),
lexical_cast<std::string>(static_cast<unsigned short>(123)));
BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123u));
BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123ul));
}
void test_conversion_to_pointer()
{
BOOST_CHECK_THROW(lexical_cast<char *>("Test"), boost::bad_lexical_cast);
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), boost::bad_lexical_cast);
#endif
}
void test_conversion_from_wchar_t()
{
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK_EQUAL(1, lexical_cast<int>(L'1'));
BOOST_CHECK_THROW(lexical_cast<int>(L'A'), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(123, lexical_cast<int>(L"123"));
BOOST_CHECK_THROW(lexical_cast<int>(L""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(L"Test"), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(L'1'));
BOOST_CHECK_THROW(lexical_cast<double>(L'A'), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(L"1.23"));
BOOST_CHECK_THROW(lexical_cast<double>(L""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<double>(L"Test"), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L'1'));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L'0'));
BOOST_CHECK_THROW(lexical_cast<bool>(L'A'), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L"1"));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L"0"));
BOOST_CHECK_THROW(lexical_cast<bool>(L""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(L"Test"), boost::bad_lexical_cast);
#endif
}
void test_conversion_to_wchar_t()
{
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0));
BOOST_CHECK_THROW(lexical_cast<wchar_t>(123), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1.0));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0.0));
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(true));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(false));
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L'A'));
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L' '));
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L"A"));
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L" "));
BOOST_CHECK_THROW(lexical_cast<wchar_t>(L""), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<wchar_t>(L"Test"), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(std::wstring(L"A")));
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(std::wstring(L" ")));
BOOST_CHECK_THROW(
lexical_cast<wchar_t>(std::wstring(L"")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<wchar_t>(std::wstring(L"Test")), boost::bad_lexical_cast);
#endif
}
void test_conversion_from_wstring()
{
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::wstring(L"123")));
BOOST_CHECK_THROW(
lexical_cast<int>(std::wstring(L"")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::wstring(L"Test")), boost::bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::wstring(L"1")));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::wstring(L"0")));
BOOST_CHECK_THROW(
lexical_cast<bool>(std::wstring(L"")), boost::bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::wstring(L"Test")), boost::bad_lexical_cast);
#endif
}
void test_conversion_to_wstring()
{
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK(L"123" == lexical_cast<std::wstring>(123));
BOOST_CHECK(L"1.23" == lexical_cast<std::wstring>(1.23));
BOOST_CHECK(L"1.111111111" == lexical_cast<std::wstring>(1.111111111));
BOOST_CHECK(L"1" == lexical_cast<std::wstring>(true));
BOOST_CHECK(L"0" == lexical_cast<std::wstring>(false));
BOOST_CHECK(L"A" == lexical_cast<std::wstring>(L'A'));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L' '));
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(L"Test"));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L" "));
BOOST_CHECK(L"" == lexical_cast<std::wstring>(L""));
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(std::wstring(L"Test")));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(std::wstring(L" ")));
BOOST_CHECK(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
#endif
}

312
test.hpp
View File

@@ -1,312 +0,0 @@
// what: simple unit test framework
// who: developed by Kevlin Henney
// when: November 2000
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91
//
// ChangeLog:
// 20 Jan 2001 - Fixed a warning for MSVC (Dave Abrahams)
#ifndef TEST_INCLUDED
#define TEST_INCLUDED
#include <exception>
#include <iostream>
#include <strstream> // for out-of-the-box g++
#include <string>
namespace test // test tuple comprises name and nullary function (object)
{
template<typename string_type, typename function_type>
struct test
{
string_type name;
function_type action;
static test make(string_type name, function_type action)
{
test result; // MSVC aggreggate initializer bugs
result.name = name;
result.action = action;
return result;
}
};
}
namespace test // failure exception used to indicate checked test failures
{
class failure : public std::exception
{
public: // struction (default cases are OK)
failure(const std::string & why)
: reason(why)
{
}
// std::~string has no exception-specification (could throw anything),
// but we need to be compatible with std::~exception's empty one
// see std::15.4p13 and std::15.4p3
~failure() throw()
{
}
public: // usage
virtual const char * what() const throw()
{
return reason.c_str();
}
private: // representation
std::string reason;
};
}
namespace test // not_implemented exception used to mark unimplemented tests
{
class not_implemented : public std::exception
{
public: // usage (default ctor and dtor are OK)
virtual const char * what() const throw()
{
return "not implemented";
}
};
}
namespace test // test utilities
{
inline void check(bool condition, const std::string & description)
{
if(!condition)
{
throw failure(description);
}
}
inline void check_true(bool value, const std::string & description)
{
check(value, "expected true: " + description);
}
inline void check_false(bool value, const std::string & description)
{
check(!value, "expected false: " + description);
}
template<typename lhs_type, typename rhs_type>
void check_equal(
const lhs_type & lhs, const rhs_type & rhs,
const std::string & description)
{
check(lhs == rhs, "expected equal values: " + description);
}
template<typename lhs_type, typename rhs_type>
void check_unequal(
const lhs_type & lhs, const rhs_type & rhs,
const std::string & description)
{
check(lhs != rhs, "expected unequal values: " + description);
}
inline void check_null(const void* ptr, const std::string & description)
{
check(!ptr, "expected null pointer: " + description);
}
inline void check_non_null(const void* ptr, const std::string & description)
{
check(ptr != 0, "expected non-null pointer: " + description);
}
}
#define TEST_CHECK_THROW(expression, exception, description) \
try \
{ \
expression; \
throw ::test::failure(description); \
} \
catch(exception &) \
{ \
}
namespace test // memory tracking (enabled if test new and delete linked in)
{
class allocations
{
public: // singleton access
static allocations & instance()
{
static allocations singleton;
return singleton;
}
public: // logging
void clear()
{
alloc_count = dealloc_count = 0;
}
void allocation()
{
++alloc_count;
}
void deallocation()
{
++dealloc_count;
}
public: // reporting
unsigned long allocated() const
{
return alloc_count;
}
unsigned long deallocated() const
{
return dealloc_count;
}
bool balanced() const
{
return alloc_count == dealloc_count;
}
private: // structors (default dtor is fine)
allocations()
: alloc_count(0), dealloc_count(0)
{
}
private: // prevention
allocations(const allocations &);
allocations & operator=(const allocations &);
private: // state
unsigned long alloc_count, dealloc_count;
};
}
namespace test // tester is the driver class for a sequence of tests
{
template<typename test_iterator>
class tester
{
public: // structors (default destructor is OK)
tester(test_iterator first_test, test_iterator after_last_test)
: begin(first_test), end(after_last_test)
{
}
public: // usage
bool operator()(); // returns true if all tests passed
private: // representation
test_iterator begin, end;
private: // prevention
tester(const tester &);
tester &operator=(const tester &);
};
template<typename test_iterator>
bool tester<test_iterator>::operator()()
{
using namespace std;
unsigned long passed = 0, failed = 0, unimplemented = 0;
for(test_iterator current = begin; current != end; ++current)
{
cerr << "[" << current->name << "] " << flush;
string result = "passed"; // optimistic
try
{
allocations::instance().clear();
current->action();
if(!allocations::instance().balanced())
{
unsigned long allocated = allocations::instance().allocated();
unsigned long deallocated = allocations::instance().deallocated();
ostrstream report;
report << "new/delete ("
<< allocated << " allocated, "
<< deallocated << " deallocated)"
<< ends;
const char * text = report.str();
report.freeze(false);
throw failure(text);
}
++passed;
}
catch(const failure & caught)
{
(result = "failed: ") += caught.what();
++failed;
}
catch(const not_implemented &)
{
result = "not implemented";
++unimplemented;
}
catch(const exception & caught)
{
(result = "exception: ") += caught.what();
++failed;
}
catch(...)
{
result = "failed with unknown exception";
++failed;
}
cerr << result << endl;
}
cerr << passed + failed << " tests: "
<< passed << " passed, "
<< failed << " failed";
if(unimplemented)
{
cerr << " (" << unimplemented << " not implemented)";
}
cerr << endl;
return failed == 0;
}
}
#endif
// Copyright Kevlin Henney, 2000. All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives, and that no
// charge may be made for the software and its documentation except to cover
// cost of distribution.
//
// This software is provided "as is" without express or implied warranty.

View File

@@ -1,34 +0,0 @@
# Signals library
# Copyright (C) 2001-2003 Douglas Gregor
# Permission to copy, use, sell and distribute this software is granted
# provided this copyright notice appears in all copies. Permission to modify
# the code and to distribute modified code is granted provided this copyright
# notice appears in all copies, and a notice that the code was modified is
# included with the copyright notice. This software is provided "as is"
# without express or implied warranty, and with no claim as to its suitability
# for any purpose.
# For more information, see http://www.boost.org/
# Testing Jamfile autogenerated from XML source
subproject libs/conversion/test ;
# bring in rules for testing
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
# Make tests run by default.
DEPENDS all : test ;
{
test-suite conversion
: [ run implicit_cast.cpp ]
[ compile-fail implicit_cast_fail.cpp ]
[ run ../cast_test.cpp ]
[ run ../lexical_cast_test.cpp ]
;
}

View File

@@ -1,34 +0,0 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/implicit_cast.hpp>
#include <cassert>
#include <boost/type.hpp>
using boost::implicit_cast;
using boost::type;
template <class T>
type<T> check_return(T) { return type<T>(); }
struct foo
{
foo(char const*) {}
operator long() const { return 0; }
};
typedef type<long> long_type;
typedef type<foo> foo_type;
int main()
{
type<long> x = check_return(boost::implicit_cast<long>(1));
assert(boost::implicit_cast<long>(1) == 1L);
type<foo> f = check_return(boost::implicit_cast<foo>("hello"));
type<long> z = check_return(boost::implicit_cast<long>(foo("hello")));
return 0;
}

View File

@@ -1,23 +0,0 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/implicit_cast.hpp>
#include <boost/type.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
using boost::implicit_cast;
struct foo
{
explicit foo(char const*) {}
};
int test_main(int, char*[])
{
foo x = implicit_cast<foo>("foobar");
}