Compare commits

...

27 Commits

Author SHA1 Message Date
nobody ddcd4f4764 This commit was manufactured by cvs2svn to create tag
'Version_1_34_0'.

[SVN r37679]
2007-05-12 21:59:40 +00:00
Vladimir Prus 37d07617d1 Fix
[SVN r35993]
2006-11-10 21:03:16 +00:00
Vladimir Prus bfeb60c400 Merge from HEAD.
Allow building of shared versions of some Boost.Test libraries.
Adjust tests to use always use static linking to Boost.Test, since
linking to the shared version requires test changes.

Patch from Juergen Hunold.


[SVN r35990]
2006-11-10 19:59:52 +00:00
Rene Rivera 78f1acc5ff Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Gennaro Prota abf3aa23de removed erroneous macro version
[SVN r34578]
2006-07-17 04:17:11 +00:00
Gennaro Prota 06e7d986d2 fixed library name, copyright notice, removed a tab char and a space-only line; NOTE: is the copyright notice autogenerated?
[SVN r34573]
2006-07-17 03:08:48 +00:00
nobody 74fc01da7e This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
Dave Abrahams 80e9edcb29 Stop using assert() in tests
[SVN r33181]
2006-02-28 22:56:33 +00:00
Beman Dawes 17ca3a4493 show arg as pased by const ref
[SVN r32840]
2006-02-12 01:17:17 +00:00
Vladimir Prus e5a0aec661 Revert (supposedly mistaken) removal of 'numeric_cast_test.cpp' from the
list of tests.


[SVN r32701]
2006-02-07 11:36:24 +00:00
Vladimir Prus 8cec2cc291 Update Jamfile.v2
[SVN r32700]
2006-02-07 11:35:31 +00:00
Stefan Slapeta 027a566e09 Small fix for new init_unit_test_suite signature
[SVN r32293]
2006-01-12 11:59:09 +00:00
Markus Schöpflin 9a29a753e8 Fixed lexical_cast_test which was no longer working after the last test
framework update.


[SVN r32176]
2005-12-28 11:05:31 +00:00
John Maddock cb2bd8076d Reconfigure lexical_cast to work wide character strings and VC++ when not using /Zc:wchar_t.
[SVN r30724]
2005-08-29 12:44:09 +00:00
John Maddock 1637edf8ca Large patch from Ulrich Eckhardt to fix support for EVC++ 4.
[SVN r30670]
2005-08-25 16:27:28 +00:00
Douglas Gregor 72d69ef6ad Merged from 1.33.0 release
[SVN r30540]
2005-08-12 13:02:37 +00:00
Fernando Cacciola 1470210523 fixed: "bcc5.6.4 added to the old cast redirection list"
[SVN r29814]
2005-06-27 15:05:13 +00:00
Douglas Gregor 0b19a0ae27 Fix line endings
[SVN r29773]
2005-06-24 14:24:02 +00:00
Dave Abrahams 3ab685475c Move #include outside namespace.
[SVN r29772]
2005-06-24 14:20:41 +00:00
Fernando Cacciola e66d58e6de Old numeric_cast<> completely replaced by new code (except that the old code is retained as a fallback mechanism for old broken compilers that can't deal with the new code)
[SVN r29761]
2005-06-23 23:33:01 +00:00
Joaquín M. López Muñoz e331fc2a21 workaround for GCC 2.9x lacking std::char_traits<>::eof()
[SVN r29703]
2005-06-20 10:54:07 +00:00
Joaquín M. López Muñoz 2a65633517 fixed trivial bug
[SVN r29654]
2005-06-17 12:34:38 +00:00
Terje Slettebø 7a388cb1a6 Fixed so it doesn't trim any whitespace when converting, fixed reversed bad_lexical_cast constructor parameters, changed to pass-by-const reference
[SVN r29630]
2005-06-16 18:37:51 +00:00
Terje Slettebø 461dce3851 Fixed so it doesn't trim any whitespace when converting, fixed reversed bad_lexical_cast constructor parameters, changed to pass-by-const reference
[SVN r29629]
2005-06-16 18:27:22 +00:00
Terje Slettebø cfe358b570 Fixed so it doesn't trim any whitespace when converting, fixed reversed bad_lexical_cast constructor parameters, changed to pass-by-const reference
[SVN r29627]
2005-06-16 18:16:58 +00:00
Vladimir Prus caa875505e Update
[SVN r28239]
2005-04-14 11:20:26 +00:00
Dave Abrahams 462025d8e6 Fix docs
[SVN r27509]
2005-02-26 14:58:12 +00:00
10 changed files with 284 additions and 572 deletions
+43 -105
View File
@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
"Microsoft FrontPage 5.0">
<meta http-equiv="Content-Type" content=
"text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
@@ -19,10 +19,9 @@
<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
<p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a> provides <code>
<a href="#Polymorphic_cast">polymorphic_cast</a> and</code> <a href=
"#Polymorphic_cast"><code>polymorphic_downcast</code></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
@@ -34,43 +33,50 @@
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>
as from one base to the other in a <code>Y</code> 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
<p>The C++ built-in <code>static_cast</code> 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>
the wrong derived class. The <code>polymorphic_downcast</code> template retains
the efficiency of <code>static_cast</code> for non-debug compilations, but for
debug compilations adds safety via an assert() that a <code>dynamic_cast</code>
succeeds.</p>
<p>The C++ built-in <b>dynamic_cast</b> can be used for downcasts and
<p>The C++ built-in <code>dynamic_cast</code> 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 throwing form of <b>dynamic_cast</b>, which
easy to forget to test. The throwing form of <code>dynamic_cast</code>, which
works on references, can be used on pointers through the ugly expression
&amp;<code>dynamic_cast&lt;T&amp;&gt;(*p)</code>, which causes undefined
behavior if <code>p</code> is <code>0</code>. The <b>polymorphic_cast</b>
template performs a <b>dynamic_cast</b> on a pointer, and throws an
exception if the <b>dynamic_cast</b> returns 0.</p>
behavior if <code>p</code> is <code>0</code>. The <code>polymorphic_cast</code>
template performs a <code>dynamic_cast</code> on a pointer, and throws an
exception if the <code>dynamic_cast</code> 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>A <code>polymorphic_downcast</code> should be used for
downcasts that you are certain should succeed. Error checking is
only performed in translation units where <code>NDEBUG</code> is
not defined, via
<pre> assert( dynamic_cast&lt;Derived&gt;(x) == x )
</pre> where <code>x</code> is the source pointer. This approach
ensures that not only is a non-zero pointer returned, but also
that it is correct in the presence of multiple inheritance.
Attempts to crosscast using <code>polymorphic_downcast</code> will
fail to compile.
<b>Warning:</b> Because <code>polymorphic_downcast</code> uses assert(), it
violates the One Definition Rule (ODR) if NDEBUG is inconsistently
defined across translation units. [See ISO Std 3.2]
</p><p>
For crosscasts, or when the success of a cast can only be known at
runtime, or when efficiency is not important,
<code>polymorphic_cast</code> is preferred. </p>
<p>The C++ built-in <b>dynamic_cast</b> must be used to cast references
<p>The C++ built-in <code>dynamic_cast</code> 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>
@@ -78,8 +84,7 @@
<h3>polymorphic_cast and polymorphic_downcast synopsis</h3>
<blockquote>
<pre>
namespace boost {
<pre>namespace boost {
template &lt;class Derived, class Base&gt;
inline Derived polymorphic_cast(Base* x);
@@ -98,8 +103,7 @@ inline Derived polymorphic_downcast(Base* x);
<h3>polymorphic_downcast example</h3>
<blockquote>
<pre>
#include &lt;boost/cast.hpp&gt;
<pre>#include &lt;boost/cast.hpp&gt;
...
class Fruit { public: virtual ~Fruit(){}; ... };
class Banana : public Fruit { ... };
@@ -111,85 +115,20 @@ void f( Fruit * 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 "The C++
<p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++
Programming Language".<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>
<code>polymorphic_downcast</code> was contributed by <a href=
"../../people/dave_abrahams.htm">Dave Abrahams</a>.<code><br>
An old
numeric_cast</code> that was contributed by <a href=
"../../people/kevlin_henney.htm">Kevlin Henney</a> is now superseeded by the <a href="../numeric/conversion/doc/index.html">Boost Numeric Conversion Library</a></p>
<hr>
<p>Revised
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
-->06 January, 2001
<!--webbot bot="Timestamp" endspan i-checksum="38320"
-->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348"
--></p>
<p>&copy; Copyright boost.org 1999. Permission to copy, use, modify, sell
@@ -198,5 +137,4 @@ void ariane(double vx)
or implied warranty, and with no claim as to its suitability for any
purpose.</p>
</body>
</html>
</html>
+18 -295
View File
@@ -1,6 +1,6 @@
// boost cast.hpp header file ----------------------------------------------//
// (C) Copyright Kevlin Henney and Dave Abrahams 1999.
// (C) Copyright Kevlin Henney and 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)
@@ -8,9 +8,10 @@
// See http://www.boost.org/libs/conversion for Documentation.
// Revision History
// 02 Apr 01 Removed BOOST_NO_LIMITS workarounds and included
// <boost/limits.hpp> instead (the workaround did not
// actually compile when BOOST_NO_LIMITS was defined in
// 23 JUn 05 numeric_cast removed and redirected to the new verion (Fernando Cacciola)
// 02 Apr 01 Removed BOOST_NO_LIMITS workarounds and included
// <boost/limits.hpp> instead (the workaround did not
// actually compile when BOOST_NO_LIMITS was defined in
// any case, so we loose nothing). (John Maddock)
// 21 Jan 01 Undid a bug I introduced yesterday. numeric_cast<> never
// worked with stock GCC; trying to get it to do that broke
@@ -26,14 +27,14 @@
// (Dave Abrahams)
// 30 Jun 00 More MSVC6 wordarounds. See comments below. (Dave Abrahams)
// 28 Jun 00 Removed implicit_cast<>. See comment below. (Beman Dawes)
// 27 Jun 00 More MSVC6 workarounds
// 27 Jun 00 More MSVC6 workarounds
// 15 Jun 00 Add workarounds for MSVC6
// 2 Feb 00 Remove bad_numeric_cast ";" syntax error (Doncho Angelov)
// 26 Jan 00 Add missing throw() to bad_numeric_cast::what(0 (Adam Levar)
// 29 Dec 99 Change using declarations so usages in other namespaces work
// correctly (Dave Abrahams)
// 23 Sep 99 Change polymorphic_downcast assert to also detect M.I. errors
// as suggested Darin Adler and improved by Valentin Bonnard.
// as suggested Darin Adler and improved by Valentin Bonnard.
// 2 Sep 99 Remove controversial asserts, simplify, rename.
// 30 Aug 99 Move to cast.hpp, replace value_cast with numeric_cast,
// place in nested namespace.
@@ -43,7 +44,7 @@
#define BOOST_CAST_HPP
# include <boost/config.hpp>
# include <cassert>
# include <boost/assert.hpp>
# include <typeinfo>
# include <boost/type.hpp>
# include <boost/limits.hpp>
@@ -54,7 +55,7 @@
// appear in the function's argument list.
//
// TODO: Add this to config.hpp?
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 // 1200 = VC6
# if defined(BOOST_MSVC) && BOOST_MSVC < 1300
# define BOOST_EXPLICIT_DEFAULT_TARGET , ::boost::type<Target>* = 0
# else
# define BOOST_EXPLICIT_DEFAULT_TARGET
@@ -68,7 +69,7 @@ namespace boost
// polymorphic_cast --------------------------------------------------------//
// Runtime checked polymorphic downcasts and crosscasts.
// Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup,
// Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup,
// section 15.8 exercise 1, page 425.
template <class Target, class Source>
@@ -81,304 +82,26 @@ namespace boost
// polymorphic_downcast ----------------------------------------------------//
// assert() checked polymorphic downcast. Crosscasts prohibited.
// BOOST_ASSERT() checked polymorphic downcast. Crosscasts prohibited.
// WARNING: Because this cast uses assert(), it violates the One Definition
// Rule if NDEBUG is inconsistently defined across translation units.
// WARNING: Because this cast uses BOOST_ASSERT(), it violates
// the One Definition Rule if used in multiple translation units
// where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER
// NDEBUG are defined inconsistently.
// Contributed by Dave Abrahams
template <class Target, class Source>
inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
{
assert( dynamic_cast<Target>(x) == x ); // detect logic error
BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error
return static_cast<Target>(x);
}
// implicit_cast -----------------------------------------------------------//
//
// Removed due to uncertain purpose. Use either numeric_cast (see below)
// or static_cast according to the need.
// numeric_cast and related exception --------------------------------------//
// Contributed by Kevlin Henney
// bad_numeric_cast --------------------------------------------------------//
// exception used to indicate runtime numeric_cast failure
class bad_numeric_cast : public std::bad_cast
{
public:
// constructors, destructors and assignment operator defaulted
// function inlined for brevity and consistency with rest of library
virtual const char *what() const throw()
{
return "bad numeric cast: loss of range in numeric_cast";
}
};
// numeric_cast ------------------------------------------------------------//
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_SGI_CPP_LIMITS)
namespace detail
{
template <class T>
struct signed_numeric_limits : std::numeric_limits<T>
{
static inline T min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return (std::numeric_limits<T>::min)() >= 0
// unary minus causes integral promotion, thus the static_cast<>
? static_cast<T>(-(std::numeric_limits<T>::max)())
: (std::numeric_limits<T>::min)();
};
};
// Move to namespace boost in utility.hpp?
template <class T, bool specialized>
struct fixed_numeric_limits_base
: public if_true< std::numeric_limits<T>::is_signed >
::BOOST_NESTED_TEMPLATE then< signed_numeric_limits<T>,
std::numeric_limits<T>
>::type
{};
template <class T>
struct fixed_numeric_limits
: fixed_numeric_limits_base<T,(std::numeric_limits<T>::is_specialized)>
{};
# ifdef BOOST_HAS_LONG_LONG
// cover implementations which supply no specialization for long
// long / unsigned long long. Not intended to be full
// numeric_limits replacements, but good enough for numeric_cast<>
template <>
struct fixed_numeric_limits_base< ::boost::long_long_type, false>
{
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
BOOST_STATIC_CONSTANT(bool, is_signed = true);
static ::boost::long_long_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
# ifdef LONGLONG_MAX
return LONGLONG_MAX;
# else
return 9223372036854775807LL; // hope this is portable
# endif
}
static ::boost::long_long_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
# ifdef LONGLONG_MIN
return LONGLONG_MIN;
# else
return -( 9223372036854775807LL )-1; // hope this is portable
# endif
}
};
template <>
struct fixed_numeric_limits_base< ::boost::ulong_long_type, false>
{
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
BOOST_STATIC_CONSTANT(bool, is_signed = false);
static ::boost::ulong_long_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
# ifdef ULONGLONG_MAX
return ULONGLONG_MAX;
# else
return 0xffffffffffffffffULL; // hope this is portable
# endif
}
static ::boost::ulong_long_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
};
# endif
} // namespace detail
// less_than_type_min -
// x_is_signed should be numeric_limits<X>::is_signed
// y_is_signed should be numeric_limits<Y>::is_signed
// y_min should be numeric_limits<Y>::min()
//
// check(x, y_min) returns true iff x < y_min without invoking comparisons
// between signed and unsigned values.
//
// "poor man's partial specialization" is in use here.
template <bool x_is_signed, bool y_is_signed>
struct less_than_type_min
{
template <class X, class Y>
static bool check(X x, Y y_min)
{ return x < y_min; }
};
template <>
struct less_than_type_min<false, true>
{
template <class X, class Y>
static bool check(X, Y)
{ return false; }
};
template <>
struct less_than_type_min<true, false>
{
template <class X, class Y>
static bool check(X x, Y)
{ return x < 0; }
};
// greater_than_type_max -
// same_sign should be:
// numeric_limits<X>::is_signed == numeric_limits<Y>::is_signed
// y_max should be numeric_limits<Y>::max()
//
// check(x, y_max) returns true iff x > y_max without invoking comparisons
// between signed and unsigned values.
//
// "poor man's partial specialization" is in use here.
template <bool same_sign, bool x_is_signed>
struct greater_than_type_max;
template<>
struct greater_than_type_max<true, true>
{
template <class X, class Y>
static inline bool check(X x, Y y_max)
{ return x > y_max; }
};
template <>
struct greater_than_type_max<false, true>
{
// What does the standard say about this? I think it's right, and it
// will work with every compiler I know of.
template <class X, class Y>
static inline bool check(X x, Y)
{ return x >= 0 && static_cast<X>(static_cast<Y>(x)) != x; }
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
// MSVC6 can't static_cast unsigned __int64 -> floating types
# define BOOST_UINT64_CAST(src_type) \
static inline bool check(src_type x, unsigned __int64) \
{ \
if (x < 0) return false; \
unsigned __int64 y = static_cast<unsigned __int64>(x); \
bool odd = y & 0x1; \
__int64 div2 = static_cast<__int64>(y >> 1); \
return ((static_cast<src_type>(div2) * 2.0) + odd) != x; \
}
BOOST_UINT64_CAST(long double);
BOOST_UINT64_CAST(double);
BOOST_UINT64_CAST(float);
# undef BOOST_UINT64_CAST
# endif
};
template<>
struct greater_than_type_max<true, false>
{
template <class X, class Y>
static inline bool check(X x, Y y_max)
{ return x > y_max; }
};
template <>
struct greater_than_type_max<false, false>
{
// What does the standard say about this? I think it's right, and it
// will work with every compiler I know of.
template <class X, class Y>
static inline bool check(X x, Y)
{ return static_cast<X>(static_cast<Y>(x)) != x; }
};
#else // use #pragma hacks if available
namespace detail
{
# if BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4018)
# pragma warning(disable : 4146)
#elif defined(__BORLANDC__)
# pragma option push -w-8041
# endif
// Move to namespace boost in utility.hpp?
template <class T>
struct fixed_numeric_limits : public std::numeric_limits<T>
{
static inline T min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return std::numeric_limits<T>::is_signed && (std::numeric_limits<T>::min)() >= 0
? T(-(std::numeric_limits<T>::max)()) : (std::numeric_limits<T>::min)();
}
};
# if BOOST_MSVC
# pragma warning(pop)
#elif defined(__BORLANDC__)
# pragma option pop
# endif
} // namespace detail
#endif
template<typename Target, typename Source>
inline Target numeric_cast(Source arg BOOST_EXPLICIT_DEFAULT_TARGET)
{
// typedefs abbreviating respective trait classes
typedef detail::fixed_numeric_limits<Source> arg_traits;
typedef detail::fixed_numeric_limits<Target> result_traits;
#if defined(BOOST_STRICT_CONFIG) \
|| (!defined(__HP_aCC) || __HP_aCC > 33900) \
&& (!defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) \
|| defined(BOOST_SGI_CPP_LIMITS))
// typedefs that act as compile time assertions
// (to be replaced by boost compile time assertions
// as and when they become available and are stable)
typedef bool argument_must_be_numeric[arg_traits::is_specialized];
typedef bool result_must_be_numeric[result_traits::is_specialized];
const bool arg_is_signed = arg_traits::is_signed;
const bool result_is_signed = result_traits::is_signed;
const bool same_sign = arg_is_signed == result_is_signed;
if (less_than_type_min<arg_is_signed, result_is_signed>::check(arg, (result_traits::min)())
|| greater_than_type_max<same_sign, arg_is_signed>::check(arg, (result_traits::max)())
)
#else // We need to use #pragma hacks if available
# if BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4018)
#elif defined(__BORLANDC__)
#pragma option push -w-8012
# endif
if ((arg < 0 && !result_traits::is_signed) // loss of negative range
|| (arg_traits::is_signed && arg < (result_traits::min)()) // underflow
|| arg > (result_traits::max)()) // overflow
# if BOOST_MSVC
# pragma warning(pop)
#elif defined(__BORLANDC__)
#pragma option pop
# endif
#endif
{
throw bad_numeric_cast();
}
return static_cast<Target>(arg);
} // numeric_cast
# undef BOOST_EXPLICIT_DEFAULT_TARGET
} // namespace boost
# include <boost/numeric/conversion/cast.hpp>
#endif // BOOST_CAST_HPP
-6
View File
@@ -23,12 +23,6 @@ inline T implicit_cast (typename mpl::identity<T>::type x) {
//template <typename T>
//void implicit_cast (...);
// Macro for when you need a constant expression (Gennaro Prota)
#define BOOST_IMPLICIT_CAST(dst_type, expr) \
( sizeof( implicit_cast<dst_type>(expr) ) \
, \
static_cast<dst_type>(expr) \
)
} // namespace boost
+63 -14
View File
@@ -12,8 +12,9 @@
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// and other Boosters
// when: November 2000, March 2003
// when: November 2000, March 2003, June 2005
#include <cstddef>
#include <string>
#include <typeinfo>
#include <boost/config.hpp>
@@ -29,8 +30,7 @@
#if defined(BOOST_NO_STRINGSTREAM) || \
defined(BOOST_NO_STD_WSTRING) || \
defined(BOOST_NO_STD_LOCALE) || \
defined(BOOST_NO_INTRINSIC_WCHAR_T)
defined(BOOST_NO_STD_LOCALE)
#define DISABLE_WIDE_CHAR_SUPPORT
#endif
@@ -45,9 +45,9 @@ namespace boost
{
}
bad_lexical_cast(
const std::type_info &s,
const std::type_info &t) :
source(&s), target(&t)
const std::type_info &source_type,
const std::type_info &target_type) :
source(&source_type), target(&target_type)
{
}
const std::type_info &source_type() const
@@ -80,11 +80,13 @@ namespace boost
};
#ifndef DISABLE_WIDE_CHAR_SUPPORT
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template<>
struct stream_char<wchar_t>
{
typedef wchar_t type;
};
#endif
template<>
struct stream_char<wchar_t *>
@@ -123,6 +125,11 @@ namespace boost
template<typename Target, typename Source>
class lexical_stream
{
private:
typedef typename widest_char<
typename stream_char<Target>::type,
typename stream_char<Source>::type>::type char_type;
public:
lexical_stream()
{
@@ -148,7 +155,16 @@ namespace boost
{
return !is_pointer<InputStreamable>::value &&
stream >> output &&
(stream >> std::ws).eof();
stream.get() ==
#if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
// GCC 2.9x lacks std::char_traits<>::eof().
// We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
// configurations, which do provide std::char_traits<>::eof().
EOF;
#else
std::char_traits<char_type>::eof();
#endif
}
bool operator>>(std::string &output)
{
@@ -166,10 +182,6 @@ namespace boost
}
#endif
private:
typedef typename widest_char<
typename stream_char<Target>::type,
typename stream_char<Source>::type>::type char_type;
#if defined(BOOST_NO_STRINGSTREAM)
std::strstream stream;
#elif defined(BOOST_NO_STD_LOCALE)
@@ -180,6 +192,42 @@ namespace boost
};
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// call-by-const reference version
namespace detail
{
template<class T>
struct array_to_pointer_decay
{
typedef T type;
};
template<class T, std::size_t N>
struct array_to_pointer_decay<T[N]>
{
typedef const T * type;
};
}
template<typename Target, typename Source>
Target lexical_cast(const Source &arg)
{
typedef typename detail::array_to_pointer_decay<Source>::type NewSource;
detail::lexical_stream<Target, NewSource> interpreter;
Target result;
if(!(interpreter << arg && interpreter >> result))
throw_exception(bad_lexical_cast(typeid(NewSource), typeid(Target)));
return result;
}
#else
// call-by-value fallback version (deprecated)
template<typename Target, typename Source>
Target lexical_cast(Source arg)
{
@@ -187,12 +235,14 @@ namespace boost
Target result;
if(!(interpreter << arg && interpreter >> result))
throw_exception(bad_lexical_cast(typeid(Target), typeid(Source)));
throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
return result;
}
#endif
}
// Copyright Kevlin Henney, 2000-2003. All rights reserved.
// Copyright Kevlin Henney, 2000-2005. All rights reserved.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -200,4 +250,3 @@ namespace boost
#undef DISABLE_WIDE_CHAR_SUPPORT
#endif
+4 -5
View File
@@ -3,7 +3,7 @@
<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="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost Conversion Library</title>
</head>
@@ -22,8 +22,7 @@ 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>
polymorphic 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
@@ -31,9 +30,9 @@ supplied by several headers:</p>
</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" -->
S-Format="%d %B, %Y" startspan -->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348" -->
</p>
</body>
</html>
</html>
+47 -36
View File
@@ -4,7 +4,7 @@
<head>
<title>lexical_cast</title>
<meta name="author" content="Kevlin Henney, mailto:kevlin@curbralan.com">
<meta name="generator" content="Microsoft FrontPage 4.0">
<meta name="generator" content="Microsoft FrontPage 5.0">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" width="277" height="86">Header
@@ -77,7 +77,7 @@
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>
numeric to numeric, <code><a href="../numeric/conversion/doc/numeric_cast.html">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
@@ -89,8 +89,7 @@
<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[])
<pre>int main(int argc, char * argv[])
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
@@ -112,8 +111,7 @@ int main(int argc, char * argv[])
}
</pre>
</blockquote>The following example uses numeric data in a string expression: <blockquote>
<pre>
void log_message(const std::string &amp;);
<pre>void log_message(const std::string &amp;);
void log_errno(int yoko)
{
@@ -125,12 +123,11 @@ void log_errno(int yoko)
<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
<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);
Target <a href="#lexical_cast">lexical_cast</a>(const Source&amp; arg);
}
</pre>
</blockquote>Unit test defined in <a href="lexical_cast_test.cpp"><code>&quot;lexical_cast_test.cpp&quot;</code></a>.
@@ -138,9 +135,8 @@ namespace boost
<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>template&lt;typename Target, typename Source&gt;
Target lexical_cast(const Source&amp; 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.
@@ -186,8 +182,7 @@ template&lt;typename Target, typename Source&gt;
<hr>
<h2><a name="bad_lexical_cast"><code>bad_lexical_cast</code></a></h2>
<blockquote>
<pre>
class bad_lexical_cast : public std::bad_cast
<pre>class bad_lexical_cast : public std::bad_cast
{
public:
... // <i>same member function interface as</i> std::exception
@@ -196,28 +191,44 @@ public:
</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>
<h2><a name="changes">Changes</a></h2>
<h3>June 2005:</h3>
<ul type="square">
<li>Call-by-const reference for the parameters. This requires partial specialization
of class templates, so it doesn't work for MSVC 6, and it uses the original
pass by value there.<br>
</li>
<li>The MSVC 6 support is deprecated, and will be removed in a future Boost
version. </li>
</ul>
<h3>Earlier:</h3>
<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. <br>
<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>. <br>
<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. <br>
<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>
<div align="right"><small><i>&copy; Copyright Kevlin Henney, 2000&#150;2005</i></small></div>
</body>
</html>
</html>
+103 -71
View File
@@ -2,11 +2,13 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Terje Slettebø and Kevlin Henney, 2003.
// Copyright Terje Slettebø and Kevlin Henney, 2005.
//
// 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: The unit test no longer compile on MSVC 6, but lexical_cast itself works for it.
#include <boost/config.hpp>
@@ -17,13 +19,13 @@
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.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)
defined(BOOST_NO_STD_LOCALE)
#define DISABLE_WIDE_CHAR_SUPPORT
#endif
@@ -40,8 +42,10 @@ void test_conversion_from_wchar_t();
void test_conversion_to_wchar_t();
void test_conversion_from_wstring();
void test_conversion_to_wstring();
void test_bad_lexical_cast();
void test_no_whitespace_stripping();
unit_test_framework::test_suite *init_unit_test_suite(int, char **)
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test_framework::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast unit test");
@@ -58,6 +62,8 @@ unit_test_framework::test_suite *init_unit_test_suite(int, char **)
suite->add(BOOST_TEST_CASE(test_conversion_from_wstring));
suite->add(BOOST_TEST_CASE(test_conversion_to_wstring));
#endif
suite->add(BOOST_TEST_CASE(test_bad_lexical_cast));
suite->add(BOOST_TEST_CASE(test_no_whitespace_stripping));
return suite;
}
@@ -67,99 +73,96 @@ void test_conversion_to_char()
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_THROW(lexical_cast<char>(123), 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_THROW(lexical_cast<char>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<char>("Test"), 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);
lexical_cast<char>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<char>(std::string("Test")), boost::bad_lexical_cast);
lexical_cast<char>(std::string("Test")), 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(1, lexical_cast<int>('1'));
BOOST_CHECK_EQUAL(0, lexical_cast<int>('0'));
BOOST_CHECK_THROW(lexical_cast<int>('A'), 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_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>(1.23), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(1e20), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(1e20), 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);
lexical_cast<int>(" 123"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>("Test"), bad_lexical_cast);
BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
BOOST_CHECK_EQUAL(123,lexical_cast<int>(std::string("123")));
BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::string("123")));
BOOST_CHECK_THROW(
lexical_cast<int>(std::string(" 123")), boost::bad_lexical_cast);
lexical_cast<int>(std::string(" 123")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::string("")), boost::bad_lexical_cast);
lexical_cast<int>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::string("Test")), boost::bad_lexical_cast);
lexical_cast<int>(std::string("Test")), 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_CLOSE(1.0, lexical_cast<double>('1'), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_THROW(lexical_cast<double>('A'), bad_lexical_cast);
BOOST_CHECK_CLOSE(1.0, lexical_cast<double>(1), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE(1.23, lexical_cast<double>(1.23), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE(1.234567890, 1.234567890, std::numeric_limits<double>::epsilon());
BOOST_CHECK_CLOSE(1.0, lexical_cast<double>(true), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE(0.0, lexical_cast<double>(false), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE(1.23, lexical_cast<double>("1.23"), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_THROW(lexical_cast<double>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<double>("Test"), bad_lexical_cast);
BOOST_CHECK_CLOSE(1.23, lexical_cast<double>(std::string("1.23")), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_THROW(
lexical_cast<double>(std::string("")), boost::bad_lexical_cast);
lexical_cast<double>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<double>(std::string("Test")), boost::bad_lexical_cast);
lexical_cast<double>(std::string("Test")), 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_THROW(lexical_cast<bool>('A'), 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_THROW(lexical_cast<bool>(123), 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_THROW(lexical_cast<bool>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("Test"), 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);
lexical_cast<bool>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("Test")), boost::bad_lexical_cast);
lexical_cast<bool>(std::string("Test")), bad_lexical_cast);
}
void test_conversion_to_string()
@@ -169,8 +172,8 @@ void test_conversion_to_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("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>(""));
@@ -192,45 +195,51 @@ void test_conversion_from_to_wchar_t_alias()
void test_conversion_to_pointer()
{
BOOST_CHECK_THROW(lexical_cast<char *>("Test"), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<char *>("Test"), bad_lexical_cast);
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), bad_lexical_cast);
#endif
}
void test_conversion_from_wchar_t()
{
#ifndef DISABLE_WIDE_CHAR_SUPPORT
#ifndef DISABLE_WIDE_CHAR_SUPPORT
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK_EQUAL(1, lexical_cast<int>(L'1'));
BOOST_CHECK_THROW(lexical_cast<int>(L'A'), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(L'A'), bad_lexical_cast);
#endif
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_THROW(lexical_cast<int>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(L"Test"), bad_lexical_cast);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(L'1'));
BOOST_CHECK_THROW(lexical_cast<double>(L'A'), boost::bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<double>(L'A'), bad_lexical_cast);
#endif
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_THROW(lexical_cast<double>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<double>(L"Test"), bad_lexical_cast);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
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_THROW(lexical_cast<bool>(L'A'), bad_lexical_cast);
#endif
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
BOOST_CHECK_THROW(lexical_cast<bool>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(L"Test"), bad_lexical_cast);
#endif
}
void test_conversion_to_wchar_t()
{
#ifndef DISABLE_WIDE_CHAR_SUPPORT
#if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
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_THROW(lexical_cast<wchar_t>(123), 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));
@@ -239,14 +248,14 @@ void test_conversion_to_wchar_t()
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_THROW(lexical_cast<wchar_t>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<wchar_t>(L"Test"), 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);
lexical_cast<wchar_t>(std::wstring(L"")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<wchar_t>(std::wstring(L"Test")), boost::bad_lexical_cast);
lexical_cast<wchar_t>(std::wstring(L"Test")), bad_lexical_cast);
#endif
}
@@ -255,16 +264,16 @@ 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);
lexical_cast<int>(std::wstring(L"")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::wstring(L"Test")), boost::bad_lexical_cast);
lexical_cast<int>(std::wstring(L"Test")), 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);
lexical_cast<bool>(std::wstring(L"")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::wstring(L"Test")), boost::bad_lexical_cast);
lexical_cast<bool>(std::wstring(L"Test")), bad_lexical_cast);
#endif
}
@@ -276,8 +285,10 @@ void test_conversion_to_wstring()
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));
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK(L"A" == lexical_cast<std::wstring>(L'A'));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L' '));
#endif
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""));
@@ -286,3 +297,24 @@ void test_conversion_to_wstring()
BOOST_CHECK(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
#endif
}
void test_bad_lexical_cast()
{
try
{
lexical_cast<int>(std::string("Test"));
BOOST_CHECK(false); // Exception expected
}
catch(const bad_lexical_cast &e)
{
BOOST_CHECK(e.source_type() == typeid(std::string));
BOOST_CHECK(e.target_type() == typeid(int));
}
}
void test_no_whitespace_stripping()
{
BOOST_CHECK_THROW(lexical_cast<int>(" 123"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>("123 "), bad_lexical_cast);
}
-34
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
import testing ;
# 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 ../numeric_cast_test.cpp ]
[ run ../lexical_cast_test.cpp ]
;
}
+3 -2
View File
@@ -19,7 +19,8 @@ test-suite conversion
: [ run implicit_cast.cpp ]
[ compile-fail implicit_cast_fail.cpp ]
[ run ../cast_test.cpp ]
[ run ../lexical_cast_test.cpp ]
[ run ../numeric_cast_test.cpp ]
[ run ../lexical_cast_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
;
+3 -4
View File
@@ -4,9 +4,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/implicit_cast.hpp>
#include <cassert>
#include <boost/detail/lightweight_test.hpp>
#include <boost/type.hpp>
using boost::implicit_cast;
using boost::type;
@@ -25,9 +24,9 @@ typedef type<foo> foo_type;
int main()
{
type<long> x = check_return(boost::implicit_cast<long>(1));
assert(boost::implicit_cast<long>(1) == 1L);
BOOST_TEST(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;
return boost::report_errors();
}