mirror of
https://github.com/boostorg/conversion.git
synced 2026-08-06 13:34:14 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c6b836076 |
@@ -1,5 +1,3 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
@@ -11,49 +9,46 @@
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Header
|
||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" 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>
|
||||
<p>The <code>header <a href="../../boost/cast.hpp">boost/cast.hpp</a></code>
|
||||
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
|
||||
<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
|
||||
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
|
||||
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>
|
||||
succeeds. <b> </b></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>,
|
||||
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(
|
||||
preferred. It must also be used for crosscasts. It does an assert(
|
||||
dynamic_cast<Derived>(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>
|
||||
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
|
||||
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>
|
||||
@@ -137,7 +132,7 @@ 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
|
||||
<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>© Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
||||
|
||||
+4
-5
@@ -9,14 +9,13 @@
|
||||
// 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 <limits>
|
||||
#include <boost/cast.hpp>
|
||||
|
||||
# if SCHAR_MAX == LONG_MAX
|
||||
@@ -96,8 +95,8 @@ int main( int argc, char * argv[] )
|
||||
// tests which should succeed
|
||||
long small_value = 1;
|
||||
long small_negative_value = -1;
|
||||
long large_value = LONG_MAX;
|
||||
long large_negative_value = LONG_MIN;
|
||||
long large_value = std::numeric_limits<long>::max();
|
||||
long large_negative_value = std::numeric_limits<long>::min();
|
||||
signed char c = 0;
|
||||
|
||||
c = large_value; // see if compiler generates warning
|
||||
@@ -143,7 +142,7 @@ int main( int argc, char * argv[] )
|
||||
if ( !caught_exception ) ++err_count;
|
||||
|
||||
caught_exception = false;
|
||||
try { numeric_cast<int>( DBL_MAX ); }
|
||||
try { numeric_cast<int>( std::numeric_limits<double>::max() ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
|
||||
+66
-103
@@ -9,17 +9,6 @@
|
||||
// See http://www.boost.org for most recent version including 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
|
||||
// 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
|
||||
// vc-stlport.
|
||||
// 20 Jan 01 Moved BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS to config.hpp.
|
||||
// Removed unused BOOST_EXPLICIT_TARGET macro. Moved
|
||||
// boost::detail::type to boost/type.hpp. Made it compile with
|
||||
// stock gcc again (Dave Abrahams)
|
||||
// 29 Nov 00 Remove nested namespace cast, cleanup spacing before Formal
|
||||
// Review (Beman Dawes)
|
||||
// 19 Oct 00 Fix numeric_cast for floating-point types (Dave Abrahams)
|
||||
@@ -45,10 +34,8 @@
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <cassert>
|
||||
# include <typeinfo>
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/limits.hpp>
|
||||
# include <boost/detail/select_type.hpp>
|
||||
# include <typeinfo>
|
||||
# include <limits>
|
||||
|
||||
// It has been demonstrated numerous times that MSVC 6.0 fails silently at link
|
||||
// time if you use a template function which has template parameters that don't
|
||||
@@ -56,13 +43,20 @@
|
||||
//
|
||||
// TODO: Add this to config.hpp?
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 // 1200 = VC6
|
||||
# define BOOST_EXPLICIT_DEFAULT_TARGET , ::boost::type<Target>* = 0
|
||||
# define BOOST_EXPLICIT_DEFAULT_TARGET , ::boost::detail::type_wrapper<Target>* = 0
|
||||
# define BOOST_EXPLICIT_TARGET ,::boost::detail::type_wrapper<Target>*
|
||||
# else
|
||||
# define BOOST_EXPLICIT_DEFAULT_TARGET
|
||||
# define BOOST_EXPLICIT_TARGET
|
||||
# endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class T> struct type_wrapper {};
|
||||
}
|
||||
|
||||
// See the documentation for descriptions of how to choose between
|
||||
// static_cast<>, dynamic_cast<>, polymorphic_cast<> and polymorphic_downcast<>
|
||||
|
||||
@@ -122,81 +116,69 @@ namespace boost
|
||||
|
||||
// numeric_cast ------------------------------------------------------------//
|
||||
|
||||
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_SGI_CPP_LIMITS)
|
||||
// Move to config.hpp?
|
||||
#if defined(_RWSTD_VER) || (defined(__SGI_STL_PORT) && __SGI_STL_PORT <= 0x400 && __STL_STATIC_CONST_INIT_BUG)
|
||||
// STLPort 4.0 doesn't define the static constants in numeric_limits<> so that they
|
||||
// can be used at compile time if the compiler bug indicated by
|
||||
// __STL_STATIC_CONST_INIT_BUG is present.
|
||||
|
||||
// Rogue wave STL (C++ Builder) also has broken numeric_limits
|
||||
// with default template defining members out of line.
|
||||
# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct signed_numeric_limits : std::numeric_limits<T>
|
||||
{
|
||||
static inline T min()
|
||||
template <bool is_signed> struct numeric_min_select;
|
||||
|
||||
template<>
|
||||
struct numeric_min_select<true>
|
||||
{
|
||||
template <class T>
|
||||
struct limits : std::numeric_limits<T>
|
||||
{
|
||||
return std::numeric_limits<T>::min() >= 0
|
||||
static inline T min()
|
||||
# ifndef __GNUC__ // bug workaround courtesy Jens Maurer
|
||||
{
|
||||
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();
|
||||
};
|
||||
}
|
||||
# else
|
||||
;
|
||||
# endif
|
||||
};
|
||||
};
|
||||
|
||||
# ifdef __GNUC__ // bug workaround courtesy Jens Maurer
|
||||
template<> template<class T>
|
||||
inline T numeric_min_select<true>::limits<T>::min()
|
||||
{
|
||||
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();
|
||||
}
|
||||
# endif
|
||||
|
||||
template<>
|
||||
struct numeric_min_select<false>
|
||||
{
|
||||
template <class T>
|
||||
struct limits : std::numeric_limits<T> {};
|
||||
};
|
||||
|
||||
// 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 >
|
||||
::template then< signed_numeric_limits<T>,
|
||||
std::numeric_limits<T>
|
||||
>::type
|
||||
{};
|
||||
|
||||
// Move to namespace boost in utility.hpp?
|
||||
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<long long, false>
|
||||
: public numeric_min_select<
|
||||
std::numeric_limits<T>::is_signed
|
||||
>::template limits<T>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = true);
|
||||
static long long max()
|
||||
{
|
||||
# ifdef LONGLONG_MAX
|
||||
return LONGLONG_MAX;
|
||||
# else
|
||||
return 9223372036854775807LL; // hope this is portable
|
||||
# endif
|
||||
}
|
||||
|
||||
static long long min()
|
||||
{
|
||||
# ifdef LONGLONG_MIN
|
||||
return LONGLONG_MIN;
|
||||
# else
|
||||
return -9223372036854775808LL; // hope this is portable
|
||||
# endif
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct fixed_numeric_limits_base<unsigned long long, false>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = false);
|
||||
static unsigned long long max()
|
||||
{
|
||||
# ifdef ULONGLONG_MAX
|
||||
return ULONGLONG_MAX;
|
||||
# else
|
||||
return 0xffffffffffffffffULL; // hope this is portable
|
||||
# endif
|
||||
}
|
||||
|
||||
static unsigned long long min() { return 0; }
|
||||
};
|
||||
# endif
|
||||
} // namespace detail
|
||||
|
||||
// less_than_type_min -
|
||||
@@ -260,24 +242,6 @@ namespace boost
|
||||
template <class X, class Y>
|
||||
static inline bool check(X x, Y)
|
||||
{ return x >= 0 && static_cast<X>(static_cast<Y>(x)) != x; }
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 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<>
|
||||
@@ -307,9 +271,8 @@ namespace boost
|
||||
# pragma warning(disable : 4018)
|
||||
# pragma warning(disable : 4146)
|
||||
#elif defined(__BORLANDC__)
|
||||
# pragma option push -w-8041
|
||||
#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>
|
||||
@@ -320,11 +283,10 @@ namespace boost
|
||||
? T(-std::numeric_limits<T>::max()) : std::numeric_limits<T>::min();
|
||||
}
|
||||
};
|
||||
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#elif defined(__BORLANDC__)
|
||||
# pragma option pop
|
||||
#pragma option pop
|
||||
# endif
|
||||
} // namespace detail
|
||||
|
||||
@@ -334,10 +296,10 @@ namespace boost
|
||||
inline Target numeric_cast(Source arg BOOST_EXPLICIT_DEFAULT_TARGET)
|
||||
{
|
||||
// typedefs abbreviating respective trait classes
|
||||
typedef detail::fixed_numeric_limits<Source> arg_traits;
|
||||
typedef std::numeric_limits<Source> arg_traits;
|
||||
typedef detail::fixed_numeric_limits<Target> result_traits;
|
||||
|
||||
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_SGI_CPP_LIMITS)
|
||||
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
// typedefs that act as compile time assertions
|
||||
// (to be replaced by boost compile time assertions
|
||||
// as and when they become available and are stable)
|
||||
@@ -376,6 +338,7 @@ namespace boost
|
||||
} // numeric_cast
|
||||
|
||||
# undef BOOST_EXPLICIT_DEFAULT_TARGET
|
||||
# undef BOOST_EXPLICIT_TARGET
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -13,18 +13,11 @@
|
||||
// where: tested with MSVC 6.0, BCC 5.5, and g++ 2.91
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Some sstream implementations are broken for the purposes of lexical cast.
|
||||
# if defined(BOOST_NO_STRINGSTREAM)
|
||||
# define BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
# ifndef BOOST_NO_STRINGSTREAM
|
||||
# include <sstream>
|
||||
# else
|
||||
# include <strstream>
|
||||
# endif
|
||||
|
||||
#ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
# include <strstream>
|
||||
#else
|
||||
# include <sstream>
|
||||
#endif
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace boost
|
||||
@@ -46,10 +39,10 @@ namespace boost
|
||||
template<typename Target, typename Source>
|
||||
Target lexical_cast(Source arg)
|
||||
{
|
||||
# ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
std::strstream interpreter; // for out-of-the-box g++ 2.95.2
|
||||
# else
|
||||
# ifndef BOOST_NO_STRINGSTREAM
|
||||
std::stringstream interpreter;
|
||||
# else
|
||||
std::strstream interpreter; // for out-of-the-box g++ 2.95.2
|
||||
# endif
|
||||
Target result;
|
||||
|
||||
@@ -61,16 +54,14 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
|
||||
// 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.
|
||||
// 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.
|
||||
|
||||
#ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
# undef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+22
-32
@@ -12,13 +12,13 @@
|
||||
<a href="../../boost/lexical_cast.hpp">boost/lexical_cast.hpp</a></h1>
|
||||
|
||||
<ul>
|
||||
<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="#portability">Portability</a></li>
|
||||
<li><a href="#future">Future directions</a></li>
|
||||
<li><a href="#motivation">Motivation</li>
|
||||
<li></a><a href="#examples">Examples</li>
|
||||
<li></a><a href="#synopsis">Synopsis</li>
|
||||
<li></a><a href="#lexical_cast"><code>lexical_cast</code></li>
|
||||
<li></a><a href="#bad_lexical_cast"><code>bad_lexical_cast</code></li>
|
||||
<li></a><a href="#portability">Portability</li>
|
||||
<li></a><a href="#future">Future directions</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
@@ -79,13 +79,8 @@ 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>.
|
||||
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>
|
||||
|
||||
<hr>
|
||||
@@ -132,7 +127,7 @@ void log_errno(int yoko)
|
||||
<hr>
|
||||
<h2><a name="synopsis">Synopsis</a></h2>
|
||||
|
||||
Library features defined in <a href="../../boost/lexical_cast.hpp"><code>"boost/lexical_cast.hpp"</code></a>:
|
||||
Library features defined in <a href="lexical_cast.hpp"><code>"boost/lexical_cast.hpp"</code></a>:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@@ -159,8 +154,12 @@ template<typename Target, typename Source>
|
||||
</blockquote>
|
||||
|
||||
Returns the result of streaming <code>arg</code> into a <code>std::stringstream</code> and then
|
||||
out as a <code>Target</code> object. If the conversion is unsuccessful, a
|
||||
<a href="#bad_lexical_cast"><code>bad_lexical_cast</code></a> exception is thrown.
|
||||
out as a <code>Target</code> object. The conversion is parameterized by the current
|
||||
<a href="#lexical_context"><code>lexical_context</code></a>, if set. If the conversion is
|
||||
unsuccessful, a <a href="#bad_lexical_cast"><code>bad_lexical_cast</code></a> exception is thrown
|
||||
if the current <a href="#lexical_context"><code>lexical_context</code></a> is set for throwing or
|
||||
if there is no current <a href="#lexical_context"><code>lexical_context</code></a> set, otherwise a
|
||||
<code>Target()</code> is returned.
|
||||
<p>
|
||||
The requirements on the argument and result types are:
|
||||
<ul>
|
||||
@@ -221,32 +220,23 @@ preference to the standard <code><sstream></code> header for out-of-the-bo
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Improved string handling, correctly accommodating wide character strings, incompatible
|
||||
<code>basic_string</code> types, and empty strings.
|
||||
A mechanism for providing quality-of-service control is needed, e.g. formatting and exception
|
||||
behavior. In the name of simplicity (and release), the current version strips out an earlier
|
||||
experimental version.
|
||||
</li>
|
||||
<li>
|
||||
Optimize the use of a stream away for identity conversions.
|
||||
Wide character and incompatible <code>std::basic_string</code> issues need to be catered for.
|
||||
</li>
|
||||
<li>
|
||||
An <code>interpret_cast</code> that performs a <i>do-something-reasonable</i> conversion between
|
||||
types. It would, for instance, select between <code>numeric_cast</code> and <code>lexical_cast</code>
|
||||
based on <code>std::numeric_limits<>::is_specialized</code>. This would be an interesting
|
||||
project, but there are no concrete plans to pursue this at the moment.
|
||||
</li>
|
||||
<li>
|
||||
It is also worth mentioning future <i>non-directions</i>: anything that involves adding extra
|
||||
arguments for a conversion operation is not being considered. A custom keyword cast, such as
|
||||
<code>lexical_cast</code>, is intended to look like a built-in cast operator: built-in cast operators
|
||||
take only a single operand. Where a higher degree of control is required over conversions, the
|
||||
standard <code>stringstream</code> offers a more appropriate path. Where non-stream-based conversions
|
||||
are required, <code>lexical_cast</code> is the wrong tool for the job, and so it won't be special-cased
|
||||
for such scenarios.
|
||||
based on <code>std::numeric_limits<>::is_specialized</code>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div align="right"><small><i>© Copyright Kevlin Henney, 2000, 2002</i></small></div>
|
||||
<div align="right"><small><i>© Copyright Kevlin Henney, 2000</i></small></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
// 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
|
||||
@@ -43,13 +40,6 @@ namespace test // failure exception used to indicate checked test failures
|
||||
{
|
||||
}
|
||||
|
||||
// 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()
|
||||
@@ -114,14 +104,14 @@ namespace test // test utilities
|
||||
check(lhs != rhs, "expected unequal values: " + description);
|
||||
}
|
||||
|
||||
inline void check_null(const void* ptr, const std::string & 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)
|
||||
inline void check_non_null(const void * ptr, const std::string & description)
|
||||
{
|
||||
check(ptr != 0, "expected non-null pointer: " + description);
|
||||
check(ptr, "expected non-null pointer: " + description);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user