From 15b1fc3b5876f6994848e90ed5fc3e2aed62c4f3 Mon Sep 17 00:00:00 2001 From: nobody Date: Sat, 27 Jan 2001 17:35:01 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'unlabeled-1.1.2'. [SVN r8787] --- cast.htm | 145 -------------- cast_test.cpp | 153 --------------- include/boost/cast.hpp | 342 --------------------------------- include/boost/lexical_cast.hpp | 67 ------- index.htm | 39 ---- lexical_cast_test.cpp | 149 -------------- test.hpp | 312 ------------------------------ 7 files changed, 1207 deletions(-) delete mode 100644 cast.htm delete mode 100644 cast_test.cpp delete mode 100644 include/boost/cast.hpp delete mode 100644 include/boost/lexical_cast.hpp delete mode 100644 index.htm delete mode 100644 lexical_cast_test.cpp delete mode 100644 test.hpp diff --git a/cast.htm b/cast.htm deleted file mode 100644 index d64473b..0000000 --- a/cast.htm +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - -Header boost/cast.hpp Documentation - - - - -

c++boost.gif (8819 bytes)Header -boost/cast.hpp

-

Cast Functions

-

The header boost/cast.hpp -provides polymorphic_cast, polymorphic_downcast, -and numeric_cast function templates designed -to complement the C++ built-in casts.

-

The program cast_test.cpp can be used to -verify these function templates work as expected.

-

Polymorphic casts

-

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

-
-
namespace boost {
-
-template <class Derived, class Base>
-inline Derived polymorphic_cast(Base* x);
-// Throws: std::bad_cast if ( dynamic_cast<Derived>(x) == 0 )
-// Returns: dynamic_cast<Derived>(x)
-
-template <class Derived, class Base>
-inline Derived polymorphic_downcast(Base* x);
-// Effects: assert( dynamic_cast<Derived>(x) == x );
-// Returns: static_cast<Derived>(x)
-
-}
-
-

polymorphic_downcast example

-
-
#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);
-  ...
-
-

numeric_cast

-

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:

-
- -
-

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)
-
-}
-
-

numeric_cast example

-
-
#include <boost/cast.hpp>
-using namespace boost::cast;
-
-void ariane(double vx)
-{
-    ...
-    unsigned short dx = numeric_cast<unsigned short>(vx);
-    ...
-}
-
-

numeric_cast rationale

-

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.

-
-

Revised  06 January, 2001

-

© Copyright boost.org 1999. Permission to copy, use, modify, sell and -distribute this document is granted provided this copyright notice appears in -all copies. This document is provided "as is" without express or -implied warranty, and with no claim as to its suitability for any purpose.

- - - - 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.