Skip to content
Snippets Groups Projects
Commit a32c5aac authored by Jö Fahlke's avatar Jö Fahlke
Browse files

[!658] [Test][className()] Actually do test the result of className().

Merge branch 'test-classname' into 'master'

ref:core/dune-common Previously it was only printed and the test could
basically never fail.

Addresses: [#158]

See merge request [!658]

  [#158]: gitlab.dune-project.org/NoneNone/issues/158
  [!658]: gitlab.dune-project.org/core/dune-common/merge_requests/658
parents 73a4ff68 b6ecbf12
Branches
Tags
Loading
Pipeline #17970 passed
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <bitset>
#include <complex>
#include <iostream>
#include <regex>
#include <string>
#include <dune/common/classname.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/test/testsuite.hh>
using Dune::FieldVector;
using std::complex;
using CVRef = std::bitset<4>;
constexpr CVRef is_const = 1;
constexpr CVRef is_volatile = 2;
constexpr CVRef is_lvalue_reference = 4;
constexpr CVRef is_rvalue_reference = 8;
constexpr CVRef is_reference = 12;
void checkname(Dune::TestSuite &t, const std::string &name, CVRef cvref,
const std::string &pattern)
{
const auto npos = std::string::npos;
std::cout << name << std::endl;
t.check(std::regex_search(name, std::regex{pattern}))
<< '`' << name << "` does not look like `" << pattern << '`';
static const std::regex const_pattern{ R"(\bconst\b)" };
bool found_const = std::regex_search(name, const_pattern);
if((cvref & is_const) == is_const)
t.check(found_const) << '`' << name << "` contains `const`";
else
t.check(!found_const) << '`' << name << "` does not contain `const`";
static const std::regex volatile_pattern{ R"(\bvolatile\b)" };
bool found_volatile = std::regex_search(name, volatile_pattern);
if((cvref & is_volatile) == is_volatile)
t.check(found_volatile) << '`' << name << "` contains `volatile`";
else
t.check(!found_volatile) << '`' << name << "` does not contain `volatile`";
bool found_reference = name.find('&') != npos;
bool found_rvalue_reference = name.find("&&") != npos;
if((cvref & is_reference) == is_reference)
t.check(found_reference)
<< '`' << name << "` does not contain `&` or `&&`";
else if((cvref & is_lvalue_reference) == is_lvalue_reference)
t.check(found_reference && !found_rvalue_reference)
<< '`' << name << "` contains `&&` or does not contain `&`";
else if((cvref & is_rvalue_reference) == is_rvalue_reference)
t.check(found_rvalue_reference)
<< '`' << name << "` does not contain `&&`";
else
t.check(!found_reference)
<< '`' << name << "` contains `&` or `&&`";
}
int main()
{
try {
std::cout << "First three simple class names extracted from variables:" << std::endl;
FieldVector<int, 3> xi;
std::cout << className(xi) << std::endl;
FieldVector<double, 1> xd;
std::cout << className(xd) << std::endl;
FieldVector<complex<double>, 10> xcd;
std::cout << className(xcd) << std::endl;
std::cout << std::endl;
std::cout << "Adding const:" << std::endl;
const FieldVector<int, 3> cxi;
std::cout << className(cxi) << std::endl;
std::cout << std::endl;
std::cout << "If a variable is a reference can not be extracted (needs decltype as used below): " << std::endl;
FieldVector<double, 1> &rxd = xd;
std::cout << className(rxd) << std::endl;
std::cout << std::endl;
std::cout << "Extracting the class name using a type directly - "
<< "also extractes references correctly: " << std::endl;
std::cout << Dune::className<decltype(rxd)>() << std::endl;
const FieldVector<double, 1> &rcxd = xd;
std::cout << Dune::className<decltype(rcxd)>() << std::endl;
const FieldVector<int, 3> &rcxi = cxi;
std::cout << Dune::className<decltype(rcxi)>() << std::endl;
std::cout << std::endl;
std::cout << "Test some further types:" << std::endl;
std::cout << Dune::className< volatile FieldVector<complex<double>, 10>& >() << std::endl;
std::cout << Dune::className< FieldVector<complex<double>, 10>&& >() << std::endl;
std::cout << std::endl;
} catch (Dune::Exception& e) {
throw;
} catch (...) {
std::cerr << "Generic exception!" << std::endl;
return 2;
}
Dune::TestSuite t("className()");
std::cout << "First three simple class names extracted from variables:"
<< std::endl;
Dune::FieldVector<int, 3> xi;
checkname(t, Dune::className(xi), {},
R"(\bFieldVector\s*<\s*int\s*,\s*3\s*>)");
Dune::FieldVector<double, 1> xd;
checkname(t, Dune::className(xd), {},
R"(\bFieldVector\s*<\s*double\s*,\s*1\s*>)");
Dune::FieldVector<std::complex<double>, 10> xcd;
checkname(t, Dune::className(xcd), {},
R"(\bFieldVector\s*<.*\bcomplex\s*<\s*double\s*>\s*,\s*10\s*>)");
std::cout << std::endl;
std::cout << "Adding const:" << std::endl;
const Dune::FieldVector<int, 3> cxi;
checkname(t, Dune::className(cxi), is_const,
R"(\bFieldVector\s*<\s*int\s*,\s*3\s*>)");
std::cout << std::endl;
std::cout << "If a variable is a reference that can not be extracted (needs "
<< "decltype as used below): " << std::endl;
Dune::FieldVector<double, 1> &rxd = xd;
checkname(t, Dune::className(rxd), {},
R"(\bFieldVector\s*<\s*double\s*,\s*1\s*>)");
std::cout << std::endl;
std::cout << "Extracting the class name using a type directly - "
<< "also extractes references correctly: " << std::endl;
checkname(t, Dune::className<decltype(rxd)>(), is_lvalue_reference,
R"(\bFieldVector\s*<\s*double\s*,\s*1\s*>)");
const Dune::FieldVector<double, 1> &rcxd = xd;
checkname(t, Dune::className<decltype(rcxd)>(), is_const|is_lvalue_reference,
R"(\bFieldVector\s*<\s*double\s*,\s*1\s*>)");
const Dune::FieldVector<int, 3> &rcxi = cxi;
checkname(t, Dune::className<decltype(rcxi)>(), is_const|is_lvalue_reference,
R"(\bFieldVector\s*<\s*int\s*,\s*3\s*>)");
std::cout << std::endl;
std::cout << "Test some further types:" << std::endl;
using RVXCD = volatile Dune::FieldVector<std::complex<double>, 10>&;
checkname(t, Dune::className<RVXCD>(), is_volatile|is_lvalue_reference,
R"(\bFieldVector\s*<.*\bcomplex\s*<\s*double\s*>\s*,\s*10\s*>)");
using RRXCD = Dune::FieldVector<std::complex<double>, 10>&&;
checkname(t, Dune::className<RRXCD>(), is_rvalue_reference,
R"(\bFieldVector\s*<.*\bcomplex\s*<\s*double\s*>\s*,\s*10\s*>)");
std::cout << std::endl;
return t.exit();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment