mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
436 lines
11 KiB
C++
436 lines
11 KiB
C++
/*
|
|
-------------------------------------------------------------------------
|
|
CxxTest: A lightweight C++ unit testing library.
|
|
Copyright (c) 2008 Sandia Corporation.
|
|
This software is distributed under the LGPL License v3
|
|
For more information, see the COPYING file in the top CxxTest directory.
|
|
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
the U.S. Government retains certain rights in this software.
|
|
-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#ifndef __cxxtest__ValueTraits_h__
|
|
#define __cxxtest__ValueTraits_h__
|
|
|
|
//
|
|
// ValueTraits are used by CxxTest to convert arbitrary
|
|
// values used in TS_ASSERT_EQUALS() to a string representation.
|
|
//
|
|
// This header file contains value traits for builtin integral types.
|
|
// To declare value traits for new types you should instantiate the class
|
|
// ValueTraits<YourClass>.
|
|
//
|
|
|
|
#include <cxxtest/Flags.h>
|
|
|
|
#ifdef _CXXTEST_OLD_TEMPLATE_SYNTAX
|
|
# define CXXTEST_TEMPLATE_INSTANTIATION
|
|
#else // !_CXXTEST_OLD_TEMPLATE_SYNTAX
|
|
# define CXXTEST_TEMPLATE_INSTANTIATION template<>
|
|
#endif // _CXXTEST_OLD_TEMPLATE_SYNTAX
|
|
|
|
#ifdef _CXXTEST_HAVE_STD
|
|
#include <cmath>
|
|
#else
|
|
#include <math.h>
|
|
#endif
|
|
|
|
namespace CxxTest
|
|
{
|
|
//
|
|
// This is how we use the value traits
|
|
//
|
|
# define TS_AS_STRING(x) CxxTest::traits(x).asString()
|
|
|
|
//
|
|
// Char representation of a digit
|
|
//
|
|
char digitToChar(unsigned digit);
|
|
|
|
//
|
|
// Convert byte value to hex digits
|
|
// Returns pointer to internal buffer
|
|
//
|
|
const char *byteToHex(unsigned char byte);
|
|
|
|
//
|
|
// Convert byte values to string
|
|
// Returns one past the copied data
|
|
//
|
|
char *bytesToString(const unsigned char *bytes, unsigned numBytes, unsigned maxBytes, char *s);
|
|
|
|
//
|
|
// Copy a string.
|
|
// Returns one past the end of the destination string
|
|
// Remember -- we can't use the standard library!
|
|
//
|
|
char *copyString(char *dst, const char *src);
|
|
|
|
//
|
|
// Compare two strings.
|
|
// Remember -- we can't use the standard library!
|
|
//
|
|
bool stringsEqual(const char *s1, const char *s2);
|
|
|
|
//
|
|
// Represent a character value as a string
|
|
// Returns one past the end of the string
|
|
// This will be the actual char if printable or '\xXXXX' otherwise
|
|
//
|
|
char *charToString(unsigned long c, char *s);
|
|
|
|
//
|
|
// Prevent problems with negative (signed char)s
|
|
//
|
|
char *charToString(char c, char *s);
|
|
|
|
//
|
|
// The default ValueTraits class dumps up to 8 bytes as hex values
|
|
//
|
|
template <class T>
|
|
class ValueTraits
|
|
{
|
|
enum { MAX_BYTES = 8 };
|
|
char _asString[sizeof("{ ") + sizeof("XX ") * MAX_BYTES + sizeof("... }")];
|
|
|
|
public:
|
|
ValueTraits(const T &t) { bytesToString((const unsigned char *)&t, sizeof(T), MAX_BYTES, _asString); }
|
|
const char *asString(void) const { return _asString; }
|
|
};
|
|
|
|
//
|
|
// traits( T t )
|
|
// Creates an object of type ValueTraits<T>
|
|
//
|
|
template <class T>
|
|
inline ValueTraits<T> traits(T t)
|
|
{
|
|
return ValueTraits<T>(t);
|
|
}
|
|
|
|
//
|
|
// You can duplicate the implementation of an existing ValueTraits
|
|
//
|
|
# define CXXTEST_COPY_TRAITS(CXXTEST_NEW_CLASS, CXXTEST_OLD_CLASS) \
|
|
CXXTEST_TEMPLATE_INSTANTIATION \
|
|
class ValueTraits< CXXTEST_NEW_CLASS > \
|
|
{ \
|
|
ValueTraits< CXXTEST_OLD_CLASS > _old; \
|
|
public: \
|
|
ValueTraits( CXXTEST_NEW_CLASS n ) : _old( (CXXTEST_OLD_CLASS)n ) {} \
|
|
const char *asString( void ) const { return _old.asString(); } \
|
|
}
|
|
|
|
//
|
|
// Certain compilers need separate declarations for T and const T
|
|
//
|
|
# ifdef _CXXTEST_NO_COPY_CONST
|
|
# define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS)
|
|
# else // !_CXXTEST_NO_COPY_CONST
|
|
# define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS) CXXTEST_COPY_TRAITS(CXXTEST_CLASS, const CXXTEST_CLASS)
|
|
# endif // _CXXTEST_NO_COPY_CONST
|
|
|
|
//
|
|
// Avoid compiler warnings about unsigned types always >= 0
|
|
//
|
|
template<class N> inline bool negative(N n) { return n < 0; }
|
|
template<class N> inline N abs(N n) { return negative(n) ? -n : n; }
|
|
|
|
# define CXXTEST_NON_NEGATIVE(Type) \
|
|
CXXTEST_TEMPLATE_INSTANTIATION \
|
|
inline bool negative<Type>( Type ) { return false; } \
|
|
CXXTEST_TEMPLATE_INSTANTIATION \
|
|
inline Type abs<Type>( Type value ) { return value; }
|
|
|
|
CXXTEST_NON_NEGATIVE(bool)
|
|
CXXTEST_NON_NEGATIVE(unsigned char)
|
|
CXXTEST_NON_NEGATIVE(unsigned short int)
|
|
CXXTEST_NON_NEGATIVE(unsigned int)
|
|
CXXTEST_NON_NEGATIVE(unsigned long int)
|
|
# ifdef _CXXTEST_LONGLONG
|
|
CXXTEST_NON_NEGATIVE(unsigned _CXXTEST_LONGLONG)
|
|
# endif // _CXXTEST_LONGLONG
|
|
|
|
//
|
|
// Represent (integral) number as a string
|
|
// Returns one past the end of the string
|
|
// Remember -- we can't use the standard library!
|
|
//
|
|
template<class N>
|
|
char *numberToString(N n, char *s,
|
|
N base = 10,
|
|
unsigned skipDigits = 0,
|
|
unsigned maxDigits = (unsigned) - 1)
|
|
{
|
|
if (negative(n))
|
|
{
|
|
*s++ = '-';
|
|
n = abs(n);
|
|
}
|
|
|
|
N digit = 1;
|
|
while (digit <= (n / base))
|
|
{
|
|
digit *= base;
|
|
}
|
|
N digitValue;
|
|
for (; digit >= 1 && skipDigits; n -= digit * digitValue, digit /= base, -- skipDigits)
|
|
{
|
|
digitValue = (unsigned)(n / digit);
|
|
}
|
|
for (; digit >= 1 && maxDigits; n -= digit * digitValue, digit /= base, -- maxDigits)
|
|
{
|
|
*s++ = digitToChar((unsigned)(digitValue = (unsigned)(n / digit)));
|
|
}
|
|
|
|
*s = '\0';
|
|
return s;
|
|
}
|
|
|
|
//
|
|
// All the specific ValueTraits follow.
|
|
// You can #define CXXTEST_USER_VALUE_TRAITS if you don't want them
|
|
//
|
|
|
|
#ifndef CXXTEST_USER_VALUE_TRAITS
|
|
//
|
|
// ValueTraits: const char * const &
|
|
// This is used for printing strings, as in TS_FAIL( "Message" )
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const char * const &>
|
|
{
|
|
ValueTraits &operator=(const ValueTraits &);
|
|
const char *_asString;
|
|
|
|
public:
|
|
ValueTraits(const char * const &value) : _asString(value) {}
|
|
ValueTraits(const ValueTraits &other) : _asString(other._asString) {}
|
|
const char *asString(void) const { return _asString; }
|
|
#if 0
|
|
const char *asString(void) const
|
|
{
|
|
std::string tmp(1, '"');
|
|
for (char const* src = _asString; src && *src; ++src)
|
|
{
|
|
switch (*src)
|
|
{
|
|
case '\\': tmp += "\\\\"; break;
|
|
case '\n': tmp += "\\n"; break;
|
|
case '\r': tmp += "\\r"; break;
|
|
case '\t': tmp += "\\t"; break;
|
|
case '"': tmp += "\\\""; break;
|
|
default: tmp += *src; break;
|
|
}
|
|
}
|
|
tmp += '"';
|
|
|
|
char* res = new char[tmp.size() + 1];
|
|
return strcpy(res, tmp.c_str());
|
|
}
|
|
#endif
|
|
};
|
|
|
|
CXXTEST_COPY_TRAITS(const char *, const char * const &);
|
|
CXXTEST_COPY_TRAITS(char *, const char * const &);
|
|
|
|
//
|
|
// ValueTraits: bool
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const bool>
|
|
{
|
|
bool _value;
|
|
|
|
public:
|
|
ValueTraits(const bool value) : _value(value) {}
|
|
const char *asString(void) const { return _value ? "true" : "false"; }
|
|
};
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(bool);
|
|
|
|
# ifdef _CXXTEST_LONGLONG
|
|
//
|
|
// ValueTraits: signed long long
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const signed _CXXTEST_LONGLONG>
|
|
{
|
|
typedef _CXXTEST_LONGLONG T;
|
|
char _asString[2 + 3 * sizeof(T)];
|
|
public:
|
|
ValueTraits(T t) { numberToString<T>(t, _asString); }
|
|
const char *asString(void) const { return _asString; }
|
|
};
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(signed _CXXTEST_LONGLONG);
|
|
|
|
//
|
|
// ValueTraits: unsigned long long
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const unsigned _CXXTEST_LONGLONG>
|
|
{
|
|
typedef unsigned _CXXTEST_LONGLONG T;
|
|
char _asString[1 + 3 * sizeof(T)];
|
|
public:
|
|
ValueTraits(T t) { numberToString<T>(t, _asString); }
|
|
const char *asString(void) const { return _asString; }
|
|
};
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(unsigned _CXXTEST_LONGLONG);
|
|
# endif // _CXXTEST_LONGLONG
|
|
|
|
//
|
|
// ValueTraits: signed long
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const signed long int>
|
|
{
|
|
typedef signed long int T;
|
|
char _asString[2 + 3 * sizeof(T)];
|
|
public:
|
|
ValueTraits(T t) { numberToString<T>(t, _asString); }
|
|
const char *asString(void) const { return _asString; }
|
|
};
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(signed long int);
|
|
|
|
//
|
|
// ValueTraits: unsigned long
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const unsigned long int>
|
|
{
|
|
typedef unsigned long int T;
|
|
char _asString[1 + 3 * sizeof(T)];
|
|
public:
|
|
ValueTraits(T t) { numberToString<T>(t, _asString); }
|
|
const char *asString(void) const { return _asString; }
|
|
};
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(unsigned long int);
|
|
|
|
//
|
|
// All decimals are the same as the long version
|
|
//
|
|
|
|
CXXTEST_COPY_TRAITS(const signed int, const signed long int);
|
|
CXXTEST_COPY_TRAITS(const unsigned int, const unsigned long int);
|
|
CXXTEST_COPY_TRAITS(const signed short int, const signed long int);
|
|
CXXTEST_COPY_TRAITS(const unsigned short int, const unsigned long int);
|
|
CXXTEST_COPY_TRAITS(const unsigned char, const unsigned long int);
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(signed int);
|
|
CXXTEST_COPY_CONST_TRAITS(unsigned int);
|
|
CXXTEST_COPY_CONST_TRAITS(signed short int);
|
|
CXXTEST_COPY_CONST_TRAITS(unsigned short int);
|
|
CXXTEST_COPY_CONST_TRAITS(unsigned char);
|
|
|
|
//
|
|
// ValueTraits: char
|
|
// Returns 'x' for printable chars, '\x??' for others
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const char>
|
|
{
|
|
char _asString[sizeof("'\\xXX'")];
|
|
public:
|
|
ValueTraits(char c) { copyString(charToString(c, copyString(_asString, "'")), "'"); }
|
|
const char *asString(void) const { return _asString; }
|
|
};
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(char);
|
|
|
|
//
|
|
// ValueTraits: signed char
|
|
// Same as char, some compilers need it
|
|
//
|
|
CXXTEST_COPY_TRAITS(const signed char, const char);
|
|
CXXTEST_COPY_CONST_TRAITS(signed char);
|
|
|
|
//
|
|
// ValueTraits: double
|
|
//
|
|
CXXTEST_TEMPLATE_INSTANTIATION
|
|
class ValueTraits<const double>
|
|
{
|
|
public:
|
|
ValueTraits(double t)
|
|
{
|
|
if ((t != t) || (t >= HUGE_VAL) || (t == -HUGE_VAL))
|
|
{
|
|
nonFiniteNumber(t);
|
|
}
|
|
else if (requiredDigitsOnLeft(t) > MAX_DIGITS_ON_LEFT)
|
|
{
|
|
hugeNumber(t);
|
|
}
|
|
else
|
|
{
|
|
normalNumber(t);
|
|
}
|
|
}
|
|
|
|
const char *asString(void) const { return _asString; }
|
|
|
|
private:
|
|
enum { MAX_DIGITS_ON_LEFT = 24, DIGITS_ON_RIGHT = 4, BASE = 10 };
|
|
char _asString[1 + MAX_DIGITS_ON_LEFT + 1 + DIGITS_ON_RIGHT + 1];
|
|
|
|
static unsigned requiredDigitsOnLeft(double t);
|
|
char *doNegative(double &t);
|
|
void hugeNumber(double t);
|
|
void normalNumber(double t);
|
|
void nonFiniteNumber(double t);
|
|
char *doubleToString(double t, char *s, unsigned skip = 0, unsigned max = (unsigned) - 1);
|
|
};
|
|
|
|
CXXTEST_COPY_CONST_TRAITS(double);
|
|
|
|
//
|
|
// ValueTraits: float
|
|
//
|
|
CXXTEST_COPY_TRAITS(const float, const double);
|
|
CXXTEST_COPY_CONST_TRAITS(float);
|
|
#endif // !CXXTEST_USER_VALUE_TRAITS
|
|
}
|
|
|
|
#ifdef _CXXTEST_HAVE_STD
|
|
# include <cxxtest/StdValueTraits.h>
|
|
#endif // _CXXTEST_HAVE_STD
|
|
|
|
namespace dummy_enum_ns {}
|
|
|
|
//
|
|
// CXXTEST_ENUM_TRAITS
|
|
//
|
|
#define CXXTEST_ENUM_TRAITS( TYPE, VALUES ) \
|
|
namespace CxxTest \
|
|
{ \
|
|
CXXTEST_TEMPLATE_INSTANTIATION \
|
|
class ValueTraits<TYPE> \
|
|
{ \
|
|
TYPE _value; \
|
|
char _fallback[sizeof("(" #TYPE ")") + 3 * sizeof(TYPE)]; \
|
|
public: \
|
|
ValueTraits( TYPE value ) { \
|
|
_value = value; \
|
|
numberToString<unsigned long int>( _value, copyString( _fallback, "(" #TYPE ")" ) ); \
|
|
} \
|
|
const char *asString( void ) const \
|
|
{ \
|
|
switch ( _value ) \
|
|
{ \
|
|
VALUES \
|
|
default: return _fallback; \
|
|
} \
|
|
} \
|
|
}; \
|
|
} using namespace dummy_enum_ns
|
|
|
|
#define CXXTEST_ENUM_MEMBER( MEMBER ) \
|
|
case MEMBER: return #MEMBER;
|
|
|
|
#endif // __cxxtest__ValueTraits_h__
|