This is something I wanted to clean-up since a very long time indeed, but always postponed it, since it requires a lot of nasty clean-up and disentangling.... Several parts had been stashed away into `src/lib/test`, which are not really related: * the testrunner and testsuite builder * generic helper utilities * specialised test-support facilities, e.g. the EventLog This changeset introduces a new top-level test folder and a namespace `::test` Code from this folder is linked into a shared library `libtestsupport.so`, which resides in the linkage hierarchy between »Vessel« and »Vault«, yet is no longer part of the Lumiera application and only linked into the test-suite.
134 lines
3.9 KiB
C++
134 lines
3.9 KiB
C++
/*
|
||
TestHelperVariadic(Test) - verify variadic template diagnostics helper
|
||
|
||
Copyright (C)
|
||
2014, Hermann Vosseler <Ichthyostega@web.de>
|
||
|
||
**Lumiera** is free software; you can redistribute it and/or modify it
|
||
under the terms of the GNU General Public License as published by the
|
||
Free Software Foundation; either version 2 of the License, or (at your
|
||
option) any later version. See the file COPYING for further details.
|
||
|
||
* *****************************************************************/
|
||
|
||
/** @file test-helper-variadic-test.cpp
|
||
** unit test \ref TestHelperVariadic_test
|
||
*/
|
||
|
||
|
||
#include "test/run.hpp"
|
||
#include "test/test-helper.hpp"
|
||
|
||
|
||
#include <iostream>
|
||
#include <utility>
|
||
#include <string>
|
||
#include <cmath>
|
||
|
||
using std::cout;
|
||
using std::string;
|
||
using test::showVariadicTypes;
|
||
|
||
|
||
namespace lib {
|
||
namespace test{
|
||
namespace test{
|
||
|
||
namespace { // test fixture...
|
||
|
||
class Interface
|
||
{
|
||
public:
|
||
Interface(){}
|
||
Interface(Interface const& o) { cout << "COPY.CT from "<<&o<<" !!!\n"; }
|
||
Interface(Interface const&& o) { cout << "MOVE.CT from "<<&o<<" !!!\n"; }
|
||
|
||
Interface& operator= (Interface const& o) { cout << "COPY= from "<<&o<<" !!!\n"; return *this; }
|
||
Interface& operator= (Interface const&& o) { cout << "MOVE= from "<<&o<<" !!!\n"; return *this; }
|
||
|
||
virtual ~Interface() { }
|
||
};
|
||
|
||
class Impl
|
||
: public Interface
|
||
{
|
||
string s_;
|
||
|
||
public:
|
||
Impl(string ss ="ZOMG") : s_(ss) { }
|
||
};
|
||
|
||
|
||
inline double
|
||
makeRvalue()
|
||
{
|
||
return atan2(0,-0.0);
|
||
}
|
||
|
||
|
||
}//(End) test fixture
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/****************************************************************************//**
|
||
* @test document usage of the diagnostics helper for variadic templates.
|
||
* Errors in variadic template instantiations are sometimes hard to spot,
|
||
* due to the intricacies of template argument matching and the
|
||
* reference collapsing rules. Our diagnostics facility is itself a
|
||
* variadic function template, which, when supplied with an argument pack,
|
||
* will build a diagnostic string describing the arguments.
|
||
* @warning care has to be taken to pass the template arguments properly,
|
||
* since template argument matching might mess up the reference kind
|
||
* (rvalue, lvalue) of the passed types. Thus, either use std::forward,
|
||
* or spell out the template argument(s) explicitly on invocation
|
||
*
|
||
* @see showVariadicTypes()
|
||
* @see TestHelper_test
|
||
*/
|
||
class TestHelperVariadic_test : public Test
|
||
{
|
||
|
||
virtual void
|
||
run (Arg)
|
||
{
|
||
double d = makeRvalue();
|
||
double const& cr = d;
|
||
|
||
Impl obj;
|
||
Interface const& ref = obj;
|
||
|
||
cout << "--no-arg--\n" << showVariadicTypes() <<"\n";
|
||
cout << "--reference--\n" << showVariadicTypes(d) <<"\n";
|
||
cout << "--value--\n" << showVariadicTypes(makeRvalue()) <<"\n";
|
||
|
||
forwardFunction("two values", "foo", 42L); // displayed as char [4] const&, long &&
|
||
forwardFunction("references", d,cr,std::move(d)); // displayed as double&, double const&, double &&
|
||
|
||
forwardFunction("baseclass", ref); // displayed as Interface const&
|
||
}
|
||
|
||
|
||
/** this dummy simulates a typical variadic call
|
||
* which takes all arguments as '&&' for the purpose of "perfect forwarding"
|
||
*/
|
||
template<typename... ARGS>
|
||
void
|
||
forwardFunction (string id, ARGS&&... args)
|
||
{
|
||
cout << "--"<<id<<"--\n"
|
||
<< showVariadicTypes (std::forward<ARGS>(args)...)
|
||
<< "\n"
|
||
;
|
||
}
|
||
|
||
};
|
||
|
||
|
||
/** Register this test class... */
|
||
LAUNCHER (TestHelperVariadic_test, "unit common");
|
||
|
||
|
||
}}} // namespace lib::test::test
|