I am tying to write a simple generic smart pointer template that allows a programmer to apply an arbitrary number of wraps before and after calling some function FUNC() e.g. If a requirement was to start timer, lock, log_start, FUNC(), log_end, unlock , stop timer
Then I would like to be able to write something simple where the programmer supplied 3 types and a function to a template and let the compiler do the rest. I get the feeling it can be done using variadic templates in a manner similar to how typelists worked combined with overloading operator ->
i.e.
class timer {}; // ctor start timer, dtor stop timer
class locker{}; // ctor lock, dtor unlock
class logger{}; // ctor lock, dtor unlock
Then some code such as
template <typename ...base_class_list>
class aggregate : public base_class_list... {};
using pre_conditions = aggregate<logger, locker, trans>;
class gadget
{
auto do_something() -> void;
}; // gadget
Finally (the part I would like to write but don’t know how to glue it together
SMART_PTR<pre_conditions, gadget> g;
g->do_something();
I can get it working easily enough using the approach described by Bjarne Stroustrup in “Wrapping C++ Member Function Calls”, but was wondering if there was a more generic and elegant solution.
The easy way is to wrapping only all operator()
:
template <typename T, typename ... Ts>
struct magic
{
T obj;
template <typename ... Us>
decltype(auto) operator ()(Us...args)
{
ordered_tuple<Ts...> t; // tuple doesn't guaranty order
obj(std::forward<Us>(args)...);
}
};
To wrap operator ->
, it is more tricky:
template <typename T, typename ... Ts>
class wrapper
{
ordered_tuple<Ts...> t; // tuple doesn't guaranty order
T* obj;
public:
wrapper(T* obj) : obj(obj) {}
T* operator ->()
{
return obj;
}
};
template <typename T, typename ... Ts>
class magic
{
T obj;
public:
wrapper<T, Ts...> operator ->()
{
return {&obj};
}
};
Handling const
and non-default constructor should also be done. (and finding better name).