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
-Y diagram hierarchy.
-
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.
-
The C++ built-in static_cast 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 polymorphic_downcast
-template retains the efficiency of static_cast for non-debug
-compilations, but for debug compilations adds safety via an assert() that a dynamic_cast
-succeeds.
-
The C++ built-in dynamic_cast 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 polymorphic_cast template performs a dynamic_cast,
-and throws an exception if the dynamic_cast returns 0.
-
A polymorphic_downcast 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, polymorphic_cast is
-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. Warning:: Because polymorphic_downcast
-uses assert(), it violates the one definition rule (ODR) if NDEBUG is inconsistently
-defined across translation units. [See ISO Std 3.2]
-
The C++ built-in dynamic_cast 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.
-
polymorphic_cast and polymorphic_downcast synopsis
#include <boost/cast.hpp>
-...
-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<Banana*>(fruit);
- ...
A static_cast or implicit conversion will not
-detect failure to preserve range for numeric casts. The numeric_cast function
-templates are similar to static_cast 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.
-
The requirements on the argument and result types are:
-
-
-
Both argument and result types are CopyConstructible [ISO Std 20.1.3].
-
Both argument and result types are Numeric, defined by std::numeric_limits<>::is_specialized
- being true.
-
The argument can be converted to the result type using static_cast.
-
-
-
numeric_cast synopsis
-
-
namespace boost {
-
-class bad_numeric_cast : public std::bad_cast {...};
-
-template<typename Target, typename Source>
- 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<Target>(arg)
-
-}
The form of the throws condition is specified so that != is not a required
-operation.
-
History
-
polymorphic_cast was suggested by Bjarne Stroustrup in "The C++
-Programming Language".
-polymorphic_downcast was contributed by Dave
-Abrahams.
-numeric_cast was contributed by Kevlin
-Henney.
-
-
-
-
diff --git a/cast_test.cpp b/cast_test.cpp
deleted file mode 100644
index e3ca7ea..0000000
--- a/cast_test.cpp
+++ /dev/null
@@ -1,153 +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 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
-#include
-#include
-
-# 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( base ); // downcast
- assert( derived->kind() == 'D' );
-
- derived = 0;
- derived = polymorphic_cast( base ); // downcast, throw on error
- assert( derived->kind() == 'D' );
-
- base2 = polymorphic_cast( 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( base ); } // #1 assert failure
-
- bool caught_exception = false;
- try { derived = polymorphic_cast( 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( small_value );
- assert( c == 1 );
- c = 0;
- c = numeric_cast( small_value );
- assert( c == 1 );
- c = 0;
- c = numeric_cast( small_negative_value );
- assert( c == -1 );
-
- // These tests courtesy of Joe R NWP Swatosh
- assert( 0.0f == numeric_cast( 0.0 ) );
- assert( 0.0 == numeric_cast( 0.0 ) );
-
- // tests which should result in errors being detected
-
- caught_exception = false;
- try { c = numeric_cast( 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( 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( 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( 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( 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
diff --git a/include/boost/cast.hpp b/include/boost/cast.hpp
deleted file mode 100644
index 031cc5d..0000000
--- a/include/boost/cast.hpp
+++ /dev/null
@@ -1,342 +0,0 @@
-// boost cast.hpp header file ----------------------------------------------//
-
-// (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
-// 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)
-// 15 Jul 00 Suppress numeric_cast warnings for GCC, Borland and MSVC
-// (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
-// 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.
-// 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.
-// 3 Aug 99 Initial version
-
-#ifndef BOOST_CAST_HPP
-#define BOOST_CAST_HPP
-
-# include
-# include
-# include
-# include
-# ifndef BOOST_NO_LIMITS
-# include
-# endif
-
-// It has been demonstrated numerous times that MSVC 6.0 fails silently at link
-// time if you use a template function which has template parameters that don't
-// appear in the function's argument list.
-//
-// TODO: Add this to config.hpp?
-# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 // 1200 = VC6
-# define BOOST_EXPLICIT_DEFAULT_TARGET , ::boost::type* = 0
-# else
-# define BOOST_EXPLICIT_DEFAULT_TARGET
-# endif
-
-namespace boost
-{
-// See the documentation for descriptions of how to choose between
-// static_cast<>, dynamic_cast<>, polymorphic_cast<> and polymorphic_downcast<>
-
-// polymorphic_cast --------------------------------------------------------//
-
- // Runtime checked polymorphic downcasts and crosscasts.
- // Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup,
- // section 15.8 exercise 1, page 425.
-
- template
- inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
- {
- Target tmp = dynamic_cast(x);
- if ( tmp == 0 ) throw std::bad_cast();
- return tmp;
- }
-
-// polymorphic_downcast ----------------------------------------------------//
-
- // 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.
-
- // Contributed by Dave Abrahams
-
- template
- inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
- {
- assert( dynamic_cast(x) == x ); // detect logic error
- return static_cast(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 ------------------------------------------------------------//
-
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
-
- namespace detail
- {
- template struct numeric_min_select;
-
- template<>
- struct numeric_min_select
- {
- template
- struct limits : std::numeric_limits
- {
- static inline T min()
-# ifndef __GNUC__ // bug workaround courtesy Jens Maurer
- {
- return std::numeric_limits::min() >= 0
- // unary minus causes integral promotion, thus the static_cast<>
- ? static_cast(-std::numeric_limits::max())
- : std::numeric_limits::min();
- }
-# else
- ;
-# endif
- };
- };
-
-# ifdef __GNUC__ // bug workaround courtesy Jens Maurer
- template<> template
- inline T numeric_min_select::limits::min()
- {
- return std::numeric_limits::min() >= 0
- // unary minus causes integral promotion, thus the static_cast<>
- ? static_cast(-std::numeric_limits::max())
- : std::numeric_limits::min();
- }
-# endif
-
- template<>
- struct numeric_min_select
- {
- template
- struct limits : std::numeric_limits {};
- };
-
- // Move to namespace boost in utility.hpp?
- template
- struct fixed_numeric_limits
- : public numeric_min_select<
- std::numeric_limits::is_signed
- >::template limits
- {
- };
- } // namespace detail
-
-// less_than_type_min -
- // x_is_signed should be numeric_limits::is_signed
- // y_is_signed should be numeric_limits::is_signed
- // y_min should be numeric_limits::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
- struct less_than_type_min
- {
- template
- static bool check(X x, Y y_min)
- { return x < y_min; }
- };
-
- template <>
- struct less_than_type_min
- {
- template
- static bool check(X, Y)
- { return false; }
- };
-
- template <>
- struct less_than_type_min
- {
- template
- static bool check(X x, Y)
- { return x < 0; }
- };
-
- // greater_than_type_max -
- // same_sign should be:
- // numeric_limits::is_signed == numeric_limits::is_signed
- // y_max should be numeric_limits::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
- struct greater_than_type_max;
-
- template<>
- struct greater_than_type_max
- {
- template
- static inline bool check(X x, Y y_max)
- { return x > y_max; }
- };
-
- template <>
- struct greater_than_type_max
- {
- // What does the standard say about this? I think it's right, and it
- // will work with every compiler I know of.
- template
- static inline bool check(X x, Y)
- { return x >= 0 && static_cast(static_cast(x)) != x; }
- };
-
- template<>
- struct greater_than_type_max
- {
- template
- static inline bool check(X x, Y y_max)
- { return x > y_max; }
- };
-
- template <>
- struct greater_than_type_max
- {
- // What does the standard say about this? I think it's right, and it
- // will work with every compiler I know of.
- template
- static inline bool check(X x, Y)
- { return static_cast(static_cast(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
-
-# ifndef BOOST_NO_LIMITS
- // Move to namespace boost in utility.hpp?
- template
- struct fixed_numeric_limits : public std::numeric_limits
- {
- static inline T min()
- {
- return std::numeric_limits::is_signed && std::numeric_limits::min() >= 0
- ? T(-std::numeric_limits::max()) : std::numeric_limits::min();
- }
- };
-# endif // BOOST_NO_LIMITS
-
-# if BOOST_MSVC
-# pragma warning(pop)
-#elif defined(__BORLANDC__)
-# pragma option pop
-# endif
- } // namespace detail
-
-#endif
-
- template
- inline Target numeric_cast(Source arg BOOST_EXPLICIT_DEFAULT_TARGET)
- {
-#ifndef BOOST_NO_LIMITS
- // typedefs abbreviating respective trait classes
- typedef std::numeric_limits arg_traits;
- typedef detail::fixed_numeric_limits result_traits;
-#endif
-
-#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)
- 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::check(arg, result_traits::min())
- || greater_than_type_max::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(arg);
- } // numeric_cast
-
-# undef BOOST_EXPLICIT_DEFAULT_TARGET
-
-} // namespace boost
-
-#endif // BOOST_CAST_HPP
diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp
deleted file mode 100644
index 5096e1b..0000000
--- a/include/boost/lexical_cast.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// boost lexical_cast.hpp header -------------------------------------------//
-
-// See http://www.boost.org for most recent version including documentation.
-
-#ifndef BOOST_LEXICAL_CAST_INCLUDED
-#define BOOST_LEXICAL_CAST_INCLUDED
-
-// what: lexical_cast custom keyword cast
-// who: contributed by Kevlin Henney, with alternative naming, behaviors
-// and fixes contributed by Dave Abrahams, Daryle Walker and other
-// Boosters on the list
-// when: November 2000
-// where: tested with MSVC 6.0, BCC 5.5, and g++ 2.91
-
-#include
-# ifndef BOOST_NO_STRINGSTREAM
-# include
-# else
-# include
-# endif
-#include
-
-namespace boost
-{
- // exception used to indicate runtime lexical_cast failure
- class bad_lexical_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 lexical cast: "
- "source type value could not be interpreted as target";
- }
- };
-
- template
- Target lexical_cast(Source arg)
- {
-# ifndef BOOST_NO_STRINGSTREAM
- std::stringstream interpreter;
-# else
- std::strstream interpreter; // for out-of-the-box g++ 2.95.2
-# endif
- Target result;
-
- if(!(interpreter << arg) || !(interpreter >> result) ||
- !(interpreter >> std::ws).eof())
- throw bad_lexical_cast();
-
- return result;
- }
-}
-
-// 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.
-
-#endif
diff --git a/index.htm b/index.htm
deleted file mode 100644
index 079576c..0000000
--- a/index.htm
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-Boost Conversion Library
-
-
-
-
-
Boost
-Conversion Library
-
-
The Conversion Library improves program safety and clarity by performing
-otherwise messy conversions. It includes cast-style function templates designed to complement the C++
-Standard's built-in casts.
-
To reduce coupling, particularly to standard library IOStreams, the Boost
-Conversion Library is
-supplied by several headers:
-
-
The boost/cast header provides polymorphic_cast<>
- and polymorphic_downcast<> to perform safe casting between
- polymorphic types, and numeric_cast<> to perform safe casting
- between numeric types.
-
-
The boost/lexical_cast header provides lexical_cast<>
- general literal text conversions, such as an int represented as
- a string, or vice-versa.
-
-
-
Revised 06 January, 2001
-
-
-
-
-
diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp
deleted file mode 100644
index c19cf08..0000000
--- a/lexical_cast_test.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-// boost lexical_cast_test.cpp program -------------------------------------//
-
-// See http://www.boost.org for most recent version including documentation.
-
-// what: lexical_cast custom keyword cast tests
-// who: contributed by Kevlin Henney
-// when: October 2000
-// where: tested with MSVC 6.0 and BCC 5.5
-
-#include
-#include "test.hpp"
-#include
-#include
-#include
-
-using namespace boost;
-using namespace std;
-
-typedef test::test test_case;
-typedef const test_case * test_case_iterator;
-
-extern const test_case_iterator begin, end;
-
-int main()
-{
- test::tester test_suite(begin, end);
- return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE;
-}
-
-void test_to_string()
-{
- test::check_equal(
- lexical_cast(2001), "2001",
- "2001 -> \"2001\"");
- test::check_equal(
- lexical_cast(2001.0), "2001",
- "2001.0 ->\"2001\"");
- test::check_equal(
- lexical_cast(complex(2000,1)), "(2000,1)",
- "complex(2000,1) -> \"(2000,1)\"");
-}
-
-void test_to_int()
-{
- test::check_equal(
- lexical_cast("2001"), 2001,
- "\"2001\" -> 2001");
- test::check_equal(
- lexical_cast(" 2001"), 2001,
- "\" 2001\" -> 2001");
- test::check_equal(
- lexical_cast("2001 "), 2001,
- "\"2001 \" -> 2001");
- TEST_CHECK_THROW(
- lexical_cast("Two thousand and one"),
- bad_lexical_cast,
- "\"Two thousand and one\"");
- TEST_CHECK_THROW(
- lexical_cast("2001: A Space Odyssey"),
- bad_lexical_cast,
- "\"2001: A Space Odyssey\"");
- TEST_CHECK_THROW(
- lexical_cast(200.1),
- bad_lexical_cast,
- "200.1");
- TEST_CHECK_THROW(
- lexical_cast("200e1"),
- bad_lexical_cast,
- "\"200e1\"");
-}
-
-void test_to_char()
-{
- test::check_equal(
- lexical_cast("2"), '2',
- "\"2\" -> '2'");
- test::check_equal(
- lexical_cast(" 2"), '2',
- "\" 2\" -> '2'");
- test::check_equal(
- lexical_cast("2 "), '2',
- "\"2 \" -> '2'");
- test::check_equal(
- lexical_cast(2), '2',
- "2 -> '2'");
- TEST_CHECK_THROW(
- lexical_cast("2001"),
- bad_lexical_cast,
- "\"2001\"");
- TEST_CHECK_THROW(
- lexical_cast(2001),
- bad_lexical_cast,
- "2001");
-}
-
-void test_to_double()
-{
- test::check_equal(
- lexical_cast("1e6"), 1e6,
- "\"1e6\" -> 1e6");
- test::check_equal(
- lexical_cast("1e-2"), 1e-2,
- "\"1e-2\" -> 1e-2");
-}
-
-void test_to_bool()
-{
- test::check_equal(
- lexical_cast(1), true,
- "1 -> true");
- test::check_equal(
- lexical_cast('0'), false,
- "'0' -> false");
- TEST_CHECK_THROW(
- lexical_cast(2001),
- bad_lexical_cast,
- "2001");
- TEST_CHECK_THROW(
- lexical_cast(2),
- bad_lexical_cast,
- "2");
- TEST_CHECK_THROW(
- lexical_cast("true thousand and one"),
- bad_lexical_cast,
- "\"true thousand and one\"");
-}
-
-const test_case test_cases[] =
-{
- { "lexical_cast", test_to_string },
- { "lexical_cast", test_to_int },
- { "lexical_cast", test_to_char },
- { "lexical_cast", test_to_double },
- { "lexical_cast", test_to_bool }
-};
-
-const test_case_iterator begin = test_cases;
-const test_case_iterator end =
- test_cases + (sizeof test_cases / sizeof *test_cases);
-
-// 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.
diff --git a/test.hpp b/test.hpp
deleted file mode 100644
index d286b8c..0000000
--- a/test.hpp
+++ /dev/null
@@ -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
-#include
-#include // for out-of-the-box g++
-#include
-
-namespace test // test tuple comprises name and nullary function (object)
-{
- template
- 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
- void check_equal(
- const lhs_type & lhs, const rhs_type & rhs,
- const std::string & description)
- {
- check(lhs == rhs, "expected equal values: " + description);
- }
-
- template
- 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
- 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
- bool tester::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.