These are generic vehicles to verify computation structures. Since they are in no way related to our models, they belong into »Vault« layer Furthermore this reorganisation of test support components is prerequisite to also move further generic facilities down into the Vault
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
|