(Compile-time) unit testing which of several overloads is called - c++

Consider the following piece of code:
struct A {};
struct B : A {};
bool f(A,A) { /* ... */ }
bool f(B,B) { /* ... */ }
Now suppose I have somewhere something like
// ...
b = f(x,y);
// ...
I would like to ensure by a (probably compile-time, or alternatively run-time) unit test that a particular overload of f is called by this sequence of code. Let's say f(B,B) is some specialized, optimized version of f(A,A), so that it is functionally equivalent, yet faster. I cannot determine which function has been called by just looking at the result.
One possibility, of course, is letting f set some global flag.
Another possibility is something like
template <class X, class Res> struct Distinguish {
using Tag = X;
Res m_res;
explicit Distinguish (Res res) : m_res (res) { }
operator Res () const { return m_res; }
};
Distinguish<char[1], bool> f (A, A) { /* ... */ }
Distinguish<char[2], bool> f (B, B) { /* ... */ }
and then examine decltype(f (x,y))::Tag. Yet that is ugly, since I have to change the signatures of f.
Is there any better way?

Step thru it in a debugger. You might have to put a carriage return before the curly brace in your function definitions.

Related

C++ conditional type at run time with templates

I have a template function that is specialized with two types, as:
class A () { /* ... */ };
class B () { /* ... */ };
template<class T>
void foo (T &out);
template<>
void foo<A> (A &out) { /* ... */ }
template<>
void foo<B> (B &out) { /* different code ... */ }
I either call foo with A or B depending on a run-time condition and I need to allocate either A or B before calling foo. After calling foo there needs to be other code that is the same with both A or B, resulting in something like this:
if (condition) {
A obj;
foo (obj);
/* code using obj */
} else {
B obj;
foo (obj);
/* same code using obj */
}
Since the only difference is in the declaration of obj, I would like to avoid repeating the same code, ideally like auto obj = condition ? A() : B(); which of course is not allowed run time. Is there any other way to obtain this in a clean way?
The common code could be a function template, or a generic lambda (depending on how much code there is and how readable the result:
if (condition) {
A obj;
foo (obj);
/* code using obj */
} else {
B obj;
foo (obj);
/* same code using obj */
}
Could transform into something like:
auto common_code = [](auto && obj) {
foo(obj);
/* code using obj */
};
if (condition) {
common_code(A{});
} else {
common_code(B{});
}
Another thing worth noting, foo does not need to be a template, and generally speaking, function template specializations are discouraged (as the specializations don't participate in overload resolution, and can be surprising).
You can just write two non-template foo functions, one that takes A& and the other that takes a B&. This is simpler and more obvious code.
If you're passing either an A or B object as an (in-)out argument for mostly common code with some select specialized behavior, simply add a function template that delegates the non-common work to foo and contains the common work by itself.
template <typename T, typename = std::enable_if_t<std::is_same_v<T, A> ||
std::is_same_v<T, B>>>
void do_non_const_things_with_a_or_b(T &obj) {
foo(obj); // specialized for A or B
// common code for A and B
}
void f(bool condition) {
if (condition) {
A obj;
do_non_const_things_with_a_or_b(obj);
} else {
B obj;
do_non_const_things_with_a_or_b(obj);
}
}

Runtime type resolution on a non-default constructible class without polymorphysm

I have a bit of a puzzle. I have a template class graph with a template parameter - a class vertex, that can be either symmetric or asymmetric, compressed or raw, and I only know which at runtime.
So if I wanted to get the graph of appropriate type from disk, run Bellman Ford on it and then free the memory, I would need to repeat the template instantiation in all four branches of conditionals, like so:
#include "graph.h"
int main(){
// parse cmd-line args, to get `compressed` `symmetric`
// TODO get rid of conditionals.
if (compressed) {
if (symmetric) {
graph<compressedSymmetricVertex> G =
readCompressedGraph<compressedSymmetricVertex>(iFile, symmetric,mmap);
bellman_ford(G,P);
} else {
graph<compressedAsymmetricVertex> G =
readCompressedGraph<compressedAsymmetricVertex>(iFile,symmetric,mmap);
bellman_ford(G,P);
if(G.transposed) G.transpose();
G.del();
}
} else {
if (symmetric) {
graph<symmetricVertex> G =
readGraph<symmetricVertex>(iFile,compressed,symmetric,binary,mmap);
bellman_ford(G,P);
G.del();
} else {
graph<asymmetricVertex> G =
readGraph<asymmetricVertex>(iFile,compressed,symmetric,binary,mmap);
bellman_ford(G,P);
if(G.transposed) G.transpose();
G.del();
}
}
return 0;
}
QUESTION: How can I extract everything except the call to the readGraph functions outside the conditionals with the following restrictions.
I cannot modify the graph template. Otherwise I would have simply moved the Vertex type into a union.
I cannot use std::variant because graph<T> cannot be default constructible.
Call overhead is an issue. If there are subtyping polymoprhism based solutions that don't involve making compressedAsymmetricVertex a subtype of vertex, I'm all ears.
Edit: Here is a sample header graph.h:
#pragma once
template <typename T>
struct graph{ T Data; graph(int a): Data(a) {} };
template <typename T>
graph<T> readGraph<T>(char*, bool, bool, bool) {}
template <typename T>
graph<T> readCompressedGraph<T> (char*, bool, bool) {}
class compressedAsymmetricVertex {};
class compressedSymmetricVertex {};
class symmetricVertex{};
class asymmetricVertex {};
Since you did not spell out all the types, and did not explain what is going on with the binary parameter, I can only give an approximate solution. Refine it according to your exact needs. This should be in line with:
class GraphWorker
{
public:
GraphWorker(bool compressed, bool symmetric)
: m_compressed(compressed), m_symmetric(symmetric)
{}
virtual void work(const PType & P, const char * iFile, bool binary, bool mmap ) const = 0;
protected:
const bool m_compressed;
const bool m_symmetric;
};
template <class GraphType>
class ConcreteGraphWorker : public GraphWorker
{
public:
ConcreteGraphWorker(bool compressed, bool symmetric)
: GraphWorker(compressed, symmetric)
{}
void work(const PType & P, const char * iFile, bool binary, bool mmap) const override
{
graph<GraphType> G =
readGraph<GraphType>(iFile, m_compressed, m_symmetric,
binary, mmap);
bellman_ford(G,P);
G.del();
}
};
static const std::unique_ptr<GraphWorker> workers[2][2] = {
{
std::make_unique<ConcreteGraphWorker<asymmetricVertex>>(false, false),
std::make_unique<ConcreteGraphWorker<symmetricVertex>>(false, true),
},
{
std::make_unique<ConcreteGraphWorker<compressedAsymmetricVertex>>(true, false),
std::make_unique<ConcreteGraphWorker<compressedSymmetricVertex>>(true, true),
}
};
int main()
{
workers[compressed][symmetric]->work(P, iFile, binary, mmap);
}
Some comments: It is better to avoid bool altogether, and use specific enumeration types. This means that instead of my two-dimensional array, you should use something like:
std::map<std::pair<Compression, Symmetry>, std::unique_ptr<GraphWorker>> workers;
But since there could be other unknown dependencies, I have decided to stick with the confusing bool variables. Also, having workers as a static variable has its drawbacks, and since I don't know your other requirements I did not know what to do with it. Another issue is the protected Boolean variables in the base class. Usually, I'd go with accessors instead.
I'm not sure if all this jumping-through-hoops, just to avoid a couple of conditionals, is worth it. This is much longer and trickier than the original code, and unless there are more than 4 options, or the code in work() is much longer, I'd recommend to stick with the conditionals.
edit: I have just realized that using lambda functions is arguably clearer (it is up to debate). Here it is:
int main()
{
using workerType = std::function<void(PType & P, const char *, bool, bool)>;
auto makeWorker = [](bool compressed, bool symmetric, auto *nullGrpah)
{
auto worker = [=](PType & P, const char *iFile, bool binary, bool mmap)
{
// decltype(*nullGraph) is a reference, std::decay_t fixes that.
using GraphType = std::decay_t<decltype(*nullGrpah)>;
auto G = readGraph<GraphType>(iFile, compressed, symmetric,
binary, mmap);
bellman_ford(G,P);
G.del();
};
return workerType(worker);
};
workerType workers[2][2] {
{
makeWorker(false, false, (asymmetricVertex*)nullptr),
makeWorker(false, true, (symmetricVertex*)nullptr)
},
{
makeWorker(true, false, (compressedAsymmetricVertex*)nullptr),
makeWorker(true, true, (compressedSymmetricVertex*)nullptr)
}
};
workers[compressed][symmetric](P, iFile, binary, mmap);
}
The simple baseline is that whenever you want to cross from "type only known at runtime" to "type must be known at compile-time" (i.e. templates), you will need a series of such conditionals. If you cannot modify graph at all, then you will be stuck with needing four different G variables (and branches) whenever you want to handle a G object in a non-templated function, as all the graph template variants are unrelated types and cannot be treated uniformly (std::variant aside).
One solution would be to do this transition exactly once, right after reading in compressed and symmetric, and stay fully templated from there:
template<class VertexT>
graph<VertexT> readTypedGraph()
{
if constexpr (isCompressed<VertexT>::value)
return readCompressedGraph<VertexT>(/*...*/);
else
return readGraph<VertexT>(/*...*/);
}
template<class VertexT>
void main_T()
{
// From now on you are fully compile-time type-informed.
graph<VertexT> G = readTypedGraph<VertexT>();
bellman_ford(G);
transposeGraphIfTransposed(G);
G.del();
}
// non-template main
int main()
{
// Read parameters.
bool compressed = true;
bool symmetric = false;
// Switch to fully-templated code.
if (compressed)
if (symmetric)
main_T<compressedSymmetricVertex>();
else
main_T<compressedAsymmetricVertex>();
// else
// etc.
return 0;
}
Demo
You will probably have to write a lot of meta-functions (such as isCompressed) but can otherwise code as normal (albeit your IDE won't help you as much). You're not locked down in any way.

C++ runtime type switching (avoiding switch)

I've been into C++ for some years but I have not found yet the solution to a problem I constantly have. Know how to solve it would be awesome.
What I have at the moment is:
// Client code:
switch(currentEnumValue)
{
case MyEnum::kValue01:
processData<MyEnum::kValue01>(data);
break;
case MyEnum::kValue02:
processData<MyEnum::kValue02>(data);
break;
default:
LOG("Invalid command");
break;
}
// Declarations
enum class MyEnum {kValue01, kValue02};
class MyClass
{
// code
template <MyEnum> void processData(char*); /* Implemented somewhere else */
}
template <> void MyClass::processData<MyEnum::kValue01>(char* data); /* Implemented somewhere else */
MyClass <> void MyClass::processData<MyEnum::kValue02>(char* data); /* Implemented somewhere else */
I would like to remove the switch because of many reasons. Instead of it I would need something like: processData<runtime-decltype(currentEnumValue)>(data);
I know about typeid and about not mixing compile time and runtime together... but despite this, I would like to find some solution anyway, preferably excluding macros.
This class makes a jump table for a given Enum up to a certain count size based off constructing some template and invoking it with the supplied args. It assumes the enum values start at 0, and go to Count-1.
template<class Enum, Enum Count, template<Enum>class Z>
struct magic_switch {
// return value of a call to magic_switch(Args...)
template<class...Args>
using R = std::result_of_t<Z<Enum(0)>(Args...)>;
// A function pointer for a jump table:
template<class...Args>
using F = R<Args...>(*)(Args&&...);
// Produces a single function pointer for index I and args Args...
template<size_t I, class...Args>
F<Args...> f() const {
using ret = R<Args...>;
return +[](Args&&...args)->ret{
using Invoke=Z<Enum(I)>;
return Invoke{}(std::forward<Args>(args)...);
};
}
// builds a jump table:
template<class...Args, size_t...Is>
std::array<F<Args...>,size_t(Count)>
table( std::index_sequence<Is...> ) const {
return {{
f<Is, Args...>()...
}};
}
template<class...Args>
R<Args...> operator()(Enum n, Args&&...args) {
// a static jump table for this case of Args...:
static auto jump=table<Args...>(std::make_index_sequence<size_t(Count)>{});
// Look up the nth entry in the jump table, and invoke it:
return jump[size_t(n)](std::forward<Args>(args)...);
}
};
then if you have an enum:
enum class abc_enum { a, b, c, count };
and a function object template:
template<abc_enum e>
struct stuff {
void operator()() const {
std::cout << (int)e << '\n';
}
};
you can dispatch:
magic_switch<abc_enum, abc_enum::count, stuff>{}(abc_enum::b);
in any case, within the template stuff, you get the enum value as a compile time constant. You call it with a run time constant.
Overhead should be similar to a switch statement, or a vtable call, depending on what the compiler does optimization wise.
live example.
Note that setting Enum to std::size_t is valid.
In C++11 you need make_index_sequence and index_sequence:
template<size_t...>
struct index_sequence {};
namespace details {
template<size_t Count, size_t...szs>
struct sequence_maker : sequence_maker<Count-1, Count-1, szs...> {};
template<size_t...szs>
struct sequence_maker<0,szs...> {
using type = index_sequence<szs...>;
};
}
template<size_t Count>
using make_index_sequence=typename details::sequence_maker<Count>::type;
template<class...Ts>
using index_sequence_for=make_index_sequence<sizeof...(Ts)>;
and this alias:
template<class Sig>
using result_of_t=typename std::result_of<Sig>::type;
then strip std:: off their use in the above code.
live example.
Boost variant does something like what you are doing. It lets you replace switch statements with a template based contruct that can check that all cases are defined at compile-time, but then select one at run-time.
e.g.,
using namespace boost;
using Data = variant<int, double>;
struct ProcessDataFn: static_visitor<void>
{
char* data;
void operator()(int& i)
{
// do something with data
}
void operator()(double& d)
{
// do something else
}
};
void processData(char* data, Data& dataOut)
{
apply_visitor(ProcessDataFn{data}, dataOut);
}
void example(char * data)
{
Data d = 0;
processData(data, d); // calls first overload of operator()
Data d = 0.0;
processData(data, d); // calls second overload
}
To expand on my comment, ideally we'd have compile-time reflection and be able to write a generic dispatch function. In its absence, one option is to unfortunately use macros to do that for you using the X Macro pattern:
#define LIST_OF_CASES \
X_ENUM(kValue0) \
X_ENUM(kValue1) \
X_ENUM(kValue2)
enum MyEnum
{
# define X_ENUM(a) a,
LIST_OF_CASES
# undef X_ENUM
};
void dispatch(MyEnum val)
{
switch (val)
{
# define X_ENUM(a) case a: processData<a>(); break;
LIST_OF_CASES
# undef X_ENUM
default:
// something's really wrong here - can't miss cases using this pattern
}
}
One benefit of this approach is that it scales to large numbers of enumerations, it gets really hard to omit a case, and that you can attach extra information by using a multi-argument X_ENUM macro.
I know you said you'd like to avoid macros, but the alternative without virtual functions then is to have some sort of a static table of function pointers indexed by the enum, and that is just a virtual function in disguise (with admittedly lower overhead, but still suffering the cost of an indirect function call).

How to implement a lambda function for a sort algorithm involving object members, indirection, and casting?

I'm working on some code and I have a section where I do a one off sort function. To implement it I decided it was easiest to overload the operator< function. What I would prefer to do is move the implementation of the sort closer to the actual call by using some sort of boost::bind, boost::phoenix, lambda or some other type of implementation. Unfortunately I don't have access to new C++11 functionality. Below is some example code.
// In a header
struct foo
{
char * a;
char * c_str() { return a; }
}
// In a header
struct bar
{
foo * X;
bar(foo * _X) : X(_X) {}
bool operator < (const bar& rhs) const
{
return std::string(X->c_str()) < std::string(rhs.X->c_str());
}
};
struct bars : public std::vector<bar> { ... some stuff };
// Some other header
bars Bs;
// A cpp file
... other stuff happens that fills the Xs vector with objects
...::Function()
{
// Current use and it works fine
std::sort(Bs.begin(), Bs.end())
// Would like something that accomplishes this:
// std::sort(Bs.begin(), Bs.end(),
// std::string(lhs.X->c_str()) < std::string(rhs.X->c_str()))
// A non-working example of what I'm trying to do
// std::sort(Xs.begin(), Xs.end(),
// std::string((bind(bar::X->c_str(), _1)) <
// std::string((bind(bar::X->c_str(), _2)) )
}
I get lost when trying to figure out how to access the member pointers, member function and then cast the result all within a boost::bind function.
Thank you for your help.
I'm sure you can twist your way out of this using ample helpings of
Boost Phoenix bind and lambda
Boost Bind protect
However, I've learned to avoid these situations. Edit In fact, see below for one such contraption. I find this very very error prone and hard to reason about.
What you're seeing is, in essence, a violation of the Law Of Demeter. If you "just" wrote the code (not in a lambda), already it would be handling too many tasks.
So the first thing I'd do is rethink the class design.
The second thing I'd do is /extract/ different responsibilities from your comparator. Notice, that the comparator does three things:
access the c_str() of the X in lhs
access the c_str() of the X in rhs
compare the two
The first two steps are clear candidates for extraction. Let's write the generic comparer that remains first:
template <typename F>
struct compare_by_impl {
compare_by_impl(F f = F{}) : _f(std::move(f)) {}
template <typename T, typename U>
bool operator()(T const& a, U const& b) const {
return _f(a) < _f(b);
}
private:
F _f;
};
As always, it's nice to have factory function that will deduce the accessor type (in case you can get away with just using Phoenix there, it will save you specifying the (arcane) typenames involved in the expression templates):
template <typename Accessor>
compare_by_impl<Accessor> comparer_by(Accessor&& f) {
return compare_by_impl<Accessor>(std::forward<Accessor>(f));
}
Now you could already move the implementation with your sort call:
void Function()
{
struct accessX_c_str {
std::string operator()(bar const& b) const {
return b.X->c_str();
}
};
std::sort(Bs.begin(), Bs.end(), comparer_by(accessX_c_str()));
}
I'd personally leave it there.
Here's some more twisted contraptions:
// to avoid `comparer_by`
std::sort(Bs.begin(), Bs.end(), phx::bind(accessX_c_str(), arg1) < phx::bind(accessX_c_str(), arg2));
// to avoid any helper types (!?!?!? untested!)
std::sort(Bs.begin(), Bs.end(),
phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg1)))
< phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg2)))
);

C++: Is it possible to use dynamic binding with a template parameter?

I have a template function which accepts a function-object ('functor') as a template parameter:
template <typename Func> int f (void) {
Func func;
return func ();
};
struct Functor {
virtual int operator () (void) = 0;
};
struct Functor0 : Functor {
int operator () (void) {
return 0;
}
};
struct Functor1 : Functor {
int operator () (void) {
return 1;
}
};
I want to avoid an if-else block like:
int a;
if (someCondition) {
a = f<Functor0> ();
}
else {
a = f<Functor1> ();
}
Is there a way to use something similar to dynamic binding, i.e something like:
a = f<Functor> (); // I know this line won't compile, it is just an example of what I need
and decide in runtime what (derived) type is passed as the template parameter?
Is there a way to use something similar to dynamic binding
No. This is fundamentally impossible. At some point in your code you need to have the case distinction. Of course, that doesn’t have to be written manually; you can use macros (or again templates) to generate the necessary code. But it needs to be there.
One way to avoid the check (if that is REALLY what you want to do), is to use an array - ..
Functor* fp[] = { new Functor0(), new Functor1() };
now - use someCondition as an index.
a = (*fp[someCondition])();
this relies simply on run-time polymorphism rather than the redundant template mechanism you are using... (btw. don't forget to cleanup!)
Of course, this is nasty and frankly redundant, the overhead of the if will be insignificant, but the clarity it adds to the code is significant...