f



Checking at compile time if type can be output to a stream

I am writing my unit test class, trying to make it similar to Java's JUnit.
I want to use templates to cut down on the amount of code I write.  So far
I have

template <typename T>
bool Test::assertEquals<T>(const std::string& msg, const T& expected, const
T& actual)
{
	if (! registerAssertion( expected == actual ) )
	{
		std::cout << "Failure: " << msg << " expected " << expected <<
" but got " << actual << std::endl;
		return false;
	}
	else
	{
		return true;
	}
}

template <typename T>
bool Test::assertEquals<T>(const T& expected, const T& actual)
{
	return assertEquals<T>("", expected, actual);
}

However, this is clearly insufficient for many reasons (lack of tolerance
for floating-point numbers, for instance). In this case, I cannot assume
that << will always be available to print the compared values to the
stream. How can I check for this at compile time?

Regards,
Roman Werpachowski

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Roman
7/11/2009 9:35:54 AM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

5 Replies
561 Views

Similar Articles

[PageSpeed] 46

On 11 juil, 18:35, Roman Werpachowski
<roman_dot_werpachowski@gmail_dot_com.org> wrote:
> In this case, I cannot assume
> that << will always be available to print the compared values to the
> stream. How can I check for this at compile time?

I think you cannot without support for SFINAE for expressions or C++0x
concepts.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Mathias
7/12/2009 4:44:50 AM
On Jul 11, 11:35 am, Roman Werpachowski
<roman_dot_werpachowski@gmail_dot_com.org> wrote:
> I am writing my unit test class, trying to make it similar to Java's JUnit.
> I want to use templates to cut down on the amount of code I write.  So far
> I have
>
> template <typename T>
> bool Test::assertEquals<T>(const std::string& msg, const T& expected, const
> T& actual)
> {
>         if (! registerAssertion( expected == actual ) )
>         {
>                 std::cout << "Failure: " << msg << " expected " << expected <<
> " but got " << actual << std::endl;
>                 return false;
>         }
>         else
>         {
>                 return true;
>         }
>
> }
>
> template <typename T>
> bool Test::assertEquals<T>(const T& expected, const T& actual)
> {
>         return assertEquals<T>("", expected, actual);
>
> }
>
> However, this is clearly insufficient for many reasons (lack of tolerance
> for floating-point numbers, for instance). In this case, I cannot assume
> that << will always be available to print the compared values to the
> stream. How can I check for this at compile time?
>
> Regards,
> Roman Werpachowski
>

There are several ways of doing it. First thing that comes to mind is
relying on sizeof's ability to deduce the type of a function call at
compile time. Something like this:

template <typename T>
bool Test::assertEquals<T>(const std::string& msg,
    const T& expected,
    const T& actual,
    size_t nDummy = sizeof( cout << T()) )


SFINAE will make sure that this template is only instantiated for
types that can be output to a standard stream.

This is not fool-proof as the user can shoot herself in the foot
by supplying the default parameter.

If you want to be fool-proof, I guess you need to use enable_if.

tempalte <typename T>
typename enable_if<sizeof(cout << T()), bool>::type
bool Test::assertEquals<T>(const std::string& msg,
    const T& expected,
    const T& actual)



HTH,
   Andy.



-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Andrew
7/12/2009 4:49:10 AM
On 11 July, 17:35, Roman Werpachowski
> However, this is clearly insufficient for many reasons (lack of tolerance
> for floating-point numbers, for instance).

Take a look at my C++ unit testing framework. It is called FRUCTOSE
and can be found at http://fructose.sourceforge.net. It contains
macros for asserting with floating point variables. It might be just
what you need.

> In this case, I cannot assume
> that << will always be available to print the compared values to the
> stream. How can I check for this at compile time?

I am not sure you can, due to implicit type conversion. If only there
was a standard way to make a class printable, like the toString method
in java. Still, there may be some template experts in this group who
can devise a clever way to do it.

Regards,

Andrew Marlow


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Andrew
7/12/2009 4:51:13 AM
> I am writing my unit test class, trying to make it similar to Java's
JUnit.

I realize this is not what you were asking for; but there are a number
of libraries that provide unit testing similar to JUnit:

CppUnit:
    http://sourceforge.net/projects/cppunit/

Cpp Unit Lite:
    http://c2.com/cgi/wiki?CppUnitLite

UnitTest++:
    http://unittest-cpp.sourceforge.net/

as well as C++ specific unit test frameworks:

TUT:
    http://tut-framework.sourceforge.net/

Boost's Unit Test Framework:
    http://www.boost.org/doc/libs/1_39_0/libs/test/doc/html/utf.html

Does neither meet your expectations?

Regards,
&rzej

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
restor
7/13/2009 10:46:53 AM
restor <akrzemi1@gmail.com> wrote in news:a98c6f71-84cb-4781-a5be-
3eff3808fa3a@d4g2000vbm.googlegroups.com:

> Does neither meet your expectations?

I wanted to try writing my own.

Regards,
Roman Werpachowski

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Roman
7/14/2009 7:21:57 AM
Reply: