RAII classes for Brew - brew-framework

Writing code in Brew when local interfaces are being used in it can be repetitive and error prone to make it robust, i.e.:
Foo()
{
ISomeInterface* interface = NULL;
int err = ISHELL_Createnstance(…,...,&interface);
err = somethingThatCanFail();
if (AEE_SUCCESS != err)
ISomeInterface_Release(interface);
err = somethingElseThatCanFail()
if (AEE_SUCCESS != err)
ISomeInterface_Release(interface);
etc....
It would be quick to write an RAII class to automatically release the interface on exit from the function, but it would be specific to a particular interface (it would of course call ISomeInterface_Release in its destructor)
Is there any way of making a generic RAII class that can be used for interfaces of different types? i.e. is there a generic Release function that could be called in the RAII instead of the interface specific release, or some other mechanism?
--- Edit ----
Apologies, I originally added the C++ and RAII tags to this posting which I've now removed.
As the answer requires Brew knowledge not C++ knowledge.
Thanks to the people who took the time to answer, I should have added more info to begin with and not added those additional tags.

shared_ptr does what you ask for:
ISomeInterface* interface = NULL;
int err = ISHELL_Createnstance(…,...,&interface);
std::shared_ptr<ISomeInterface*> pointer(interface, ISomeInterface_Release);
Reference: http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm#constructors
EDIT Here is a sample:
#include <cstdio>
#include <memory>
int main(int ac, char **av) {
std::shared_ptr<FILE> file(fopen("/etc/passwd", "r"), fclose);
int i;
while( (i = fgetc(file.get())) != EOF)
putchar(i);
}

The RAII class that calls a specified function in destructor may look like this:
template<typename T, void (*onRelease)(T)>
class scope_destroyer {
T m_data;
public:
scope_destroyer(T const &data)
: m_data(data)
{}
~scope_destroyer() { onRelease(m_data); }
//...
};
Then you just pass a type T (e.g. a Foo*) and a function that can be called with a single parameter of type T and releases the object.
scope_destroyer<Foo, &ISomeInterface_Release> foo(CreateFoo());

Related

Encounter std::bad_weak_ptr exception after converting a unique_ptr created from a factory method to shared_ptr and using shared_from_this

In summary, I have a class inherited from std::enabled_shared_from_this, and there is a factory method return an std::unique_ptr of it. In another class, I convert the std::unique_ptr of the previous class object to std::shared_ptr, and then I call shared_from_this(), which then throws std::bad_weak_ptr. The code is shown below:
#include <memory>
#include <iostream>
struct Executor;
struct Executor1 {
Executor1(const std::shared_ptr<Executor>& executor,
int x): parent(executor) {
std::cout << x << std::endl;
}
std::shared_ptr<Executor> parent;
};
struct Backend {
virtual ~Backend() {}
virtual void run() = 0;
};
struct Executor: public Backend, public std::enable_shared_from_this<Executor> {
const int data = 10;
virtual void run() override {
Executor1 x(shared_from_this(), data);
}
};
// std::shared_ptr<Backend> createBackend() {
std::unique_ptr<Backend> createBackend() {
return std::make_unique<Executor>();
}
class MainInstance {
private:
std::shared_ptr<Backend> backend;
public:
MainInstance(): backend(createBackend()) {
backend->run();
}
};
int main() {
MainInstance m;
return 0;
}
Indeed changing std::unique_ptr<Backend> createBackend() to std::shared_ptr<Backend> createBackend() can solve the problem, but as I understand, in general, the factory pattern should prefer return a unique_ptr. Considering a good pratice of software engineering, is there a better solution?
[util.smartptr.shared.const]/1 In the constructor definitions below, enables shared_from_this with p, for a pointer p of type Y*, means that if Y has an unambiguous and accessible base class that is a specialization of enable_shared_from_this (23.11.2.5), then [magic happens that makes shared_from_this() work for *p - IT]
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
[util.smartptr.shared.const]/29 Effects: ... equivalent to shared_ptr(r.release(), r.get_deleter())...
template<class Y, class D> shared_ptr(Y* p, D d);
[util.smartptr.shared.const]/10 Effects: ... enable shared_from_this with p
Your example executes std::shared_ptr<Backend>(uptr) where uptr is std::unique_ptr<Backend>, which is equivalent to std::shared_ptr<Backend>(p, d) where p is of type Backend*. This constructor enables shared_from_this with p - but that's a no-op, as Backend doesn't have an unambiguous and accessible base class that is a specialization of enable_shared_from_this
In order for Executor::enable_from_this to work, you need to pass to a shared_ptr constructor a pointer whose static type is Executor* (or some type derived therefrom).
Ok, I find a simple solution, that is, using auto as the return type of the factory function, instead of std::unique_ptr or std::shared_ptr, and keeping std::make_unique inside the factory function. The factory function createBackend should be:
auto createBackend() {
return std::make_unique<Executor>();
}
In this case, the return type can be automatically determined, although I don't know how it works exactly. This code can return either unique_ptr or shared_ptr, which should be better than just using shared_ptr. I tested clang and gcc, and both of them worked, but I am still not sure if this is gauranteed by the type deduction and the implicit conversion.
Update:
Actually, I have found that auto deduces the return type above as std::unique_ptr<Executor> instead of std::unique_ptr<Backend>, which might be the reason why the code works. But using auto has an issue: if you return the smart pointer in an if-else block, where the return type varies depending on some parameters, then auto cannot determine the type. For example:
std::unique_ptr<Backend> createBackend(int k = 0) {
if (k == 0) {
return std::make_unique<Executor>();
}
else {
return std::make_unique<Intepreter>();
}
}
Here, both Executor and Intepreter derive from Backend. I think a correct solution includes:
Inherit Backend instead of its derived classes from std::enable_shared_from_this;
Use dynamic_pointer_cast<Derived class> to cast the shared_ptr to derived class after shared_from_this.
The full code is listed in:
https://gist.github.com/HanatoK/8d91a8ed71271e526d9becac0b20f758

Objective-C++ executable file compilation (with .mm)

Intro. I am facing a strange error with Objective-C++. All my files are of the correct type (.h/.mm instead of .hpp/.cpp). I use clib++ (built into xCode of latest version on macOS Sierra, but it was the same way on El Capitan) instead of libstd++ (that is older and doesn't fully support even C++11).
The problem. I can't compile template classes with both header and executable files. Only in case if entire code is written in header!
However, if I make a non-template class it works just fine even when split into 2 files. Header:
class TempClass {
public:
TempClass(int x);
~TempClass() {};
};
Executable:
TempClass::TempClass(int x) {}
Template class code. Header:
template <typename T> class TempClassTemplate {
public:
TempClassTemplate(T v);
~TempClassTemplate() {};
T val;
};
Executable:
template<typename T> TempClassTemplate<T>::TempClassTemplate(T v) : val(v) {};
Usage example, that causes crash:
int main(int argc, char * argv[]) {
auto obj = new TempClass(5);
printf("temp size is %lu\n", sizeof(obj));
auto objV = new TempClassTemplate<int>(10);
printf("temp size is %lu, val is %i\n", sizeof(objV), objV->val);
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
Results:
The problem isn't with Objective-C or Objective-C++. Its pure C++ known issue, but the compiler gives not enough info.
You can only make a template class - header only. But there are some walkarounds. Read this article for full answer: http://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp
But the short and simple solution is to write all the possible template class usages in the end of .cpp/.mm file like this:
template class TempClassTemplate<int8_t>;
template class TempClassTemplate<int16_t>;
template class TempClassTemplate<int32_t>;

C++11 Observers Pass parameters on Notify

I'm coming from C# and trying to implement a simple Events/EventHandler pattern in c++11 which i believe the common name is Observers and signals, i know there are boost library and others but i dont want to use any external libs.
While searching online I found a simple implementation for what I need, so I took and modified the code and it works ok.
My problem is that the parameters are passed when registering events/observers, and not when raising/signaling/notifying which I find a bit awkward.
class EventManager
{
private:
static std::map<EventType, std::vector<std::function<void()>>> _eventHandlers;
public:
EventManager() = default;
template <typename EventHandler>
static void RegisterEventHandler(EventType&& eventType, EventHandler&& eventHandler)
{
EventManager::_eventHandlers[std::move(eventType)].push_back(std::forward<EventHandler>(eventHandler));
}
static void Raise(const EventType& event)
{
for (const auto& eventHandler : EventManager::_eventHandlers.at(event))
{
eventHandler();
}
}
// disallow copying and assigning
EventManager(const EventManager&) = delete;
EventManager& operator=(const EventManager&) = delete;
};
Can anyone help me to extend the following code by adding the functionality to accept parameters when raising the event as well ?
I believe this solves your question:
// g++ -std=c++11 -o /tmp/events /tmp/events.cpp && /tmp/events
// handler=1 arg=1
// handler=2 arg=1
// handler=1 arg=2
// handler=2 arg=2
#include <functional>
#include <map>
#include <vector>
template<class EventType, class... HandlerArgs>
class EventManager
{
public:
using EventHandler = std::function< void(HandlerArgs...) >;
void register_event(EventType&& event, EventHandler&& handler)
{
_handlers[std::move(event)].push_back(std::forward<EventHandler>(handler));
}
void raise_event(const EventType& event, HandlerArgs&&... args)
{
for (const auto& handler: EventManager::_handlers.at(event)) {
handler(std::forward<HandlerArgs>(args)...);
}
}
private:
std::map<EventType, std::vector<EventHandler>> _handlers;
};
int main(int argc, char **argv)
{
EventManager<int, int> m;
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 1, arg); });
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 2, arg); });
m.raise_event(1, 1);
m.raise_event(1, 2);
}
PS: I removed all the code regarding non-copiability and such, since it is not relevant to this question.
Since i havent got any answers on this, i figured a way to do so but i dont like it since i wanted a better way but well creating a static class that has static variables for each event, before raising the event , the caller will set those variables and the handler will read then reset them . this is dangerous approach especially with multi-threading since one or more threads might change the values while raising same event by mutli threads, so i had to implement some locking features to ensure thread safety.
Yes i know its not the best approach but as i'm not an expert in C++ and this question didnt get any comments nor answers, so this is the approach im following.

an iterator that constructs a new object on dereference

I have a Visual Studio 2013 C++11 project where I'm trying to define an iterator. I want that iterator to dereference to an object, but internally it actually iterates over some internal data the object requires for construction.
class my_obj
{
public:
my_obj(some_internal_initialization_value_ v);
std::wstring friendly_name() const;
// ...
};
class my_iterator
: public boost::iterator_facade<
my_iterator,
my_obj,
boost::forward_traversal_tag>
{
// ...
private:
my_obj& dereference() const
{
// warning C4172: returning address of local variable or temporary
return my_obj(some_internal_initialization_value_);
}
};
int main( int argc, char* argv[])
{
my_container c;
for (auto o = c.begin(); o != c.end(); ++o)
printf( "%s\n", o->friendly_name().c_str() );
}
These internal values are unimportant implementation details to the user and I'd prefer not to expose them. How can I write the iterator that does this correctly? The alternative is that I would have to do something like this:
my_container c;
for (auto i = c.begin(); i != c.end(); ++i)
{
my_obj o(*i);
printf( "%s\n", o.friendly_name().c_str() );
}
From the boost page on iterator_facade, the template arguments are: derived iterator, value_type, category, reference type, difference_type. Ergo, merely tell it that references are not references
class my_iterator
: public boost::iterator_facade<
my_iterator,
my_obj,
boost::forward_traversal_tag,
my_obj> //dereference returns "my_obj" not "my_obj&"
See it working here: http://coliru.stacked-crooked.com/a/4b09ddc37068368b

Why does GCC not find my non-template function? ("no matching function for call to...")

In MSVC 2008, I have the following code:
class Foo {
// Be a little smarter about deriving the vertex type, to save the user some typing.
template<typename Vertex> inline void drawVertices(
Elements vCount, RenPrim primitiveType, PixMaterial *mtl, Vertex const *vertices)
{
this->drawVertices(vCount, primitiveType, mtl, vertices, Vertex::VertexType);
}
virtual void drawVertices(
Elements vCount,
RenPrim primitiveType,
PixMaterial *mtl,
void const *vertices,
uint vertexType) = 0;
};
I use it something like:
struct RenFlexibleVertexPc
{
enum { VertexType = RenVbufVertexComponentsPc };
float x;
float y;
float z;
GraVideoRgba8 c; // Video format, not external!
};
PixMaterial *material;
struct Pc : RenFlexibleVertexPc
{
void set(Triple t, uint cl) { x = (float)t.x_; y = (float)t.y_; z = (float)t.z_; c = cl; }
} vpc[4];
...
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
This works fine in MSVC 2008 SP1. However, GCC (3.4 and 4.1,2) throws a "no matching function for call to function" error, apparently not seeing the template when there is a non-template function with more arguments.
Is GCC broken, or is my code broken, and if so, why?
There is no problem with overloading or inheritance:
#include <iostream>
#include <memory>
namespace {
struct A {
virtual void f()
{
std::cout<<"inside A's f()\n";
}
template <typename T> void f(T t)
{
std::cout<<T::i<<'\t';
this->f();
}
};
struct B : A {
void f()
{
std::cout<<"hello\t";
A::f();
}
};
struct C {
static const unsigned int i = 5;
};
struct D {
enum { i = 6 };
};
}
int main()
{
std::auto_ptr<A> b(new B());
b->f(C());
b->f(D());
}
Works correctly. On the other hand, the smallest example I can find that exhibits your problem does not have inheritance or overloading:
#include <iostream>
namespace {
struct A {
template<class C> void print(C c)
{
c.print();
}
};
}
int main()
{
struct B {
void print()
{
std::cout << "whee!\n";
}
};
A a;
B b;
a.print(b);
}
Note that if struct B is defined in a namespace (whether it's an unnamed namespace, or a completely different namespace, or the global namespace) instead of inside main() that this compiles without error.
I don't know enough of the standard to say if this is a bug, but it appears to be one. I've gone ahead and reported it to the GCC bug database.
And here's your answer from the GCC developers (from the link above): "Local classes cannot be template arguments."
So the code is broken. Not that it's a bad idea. In fact, C++0x removes this restriction.
I noticed the line
Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
And since RenFlexibleVertexPc is not a local class this makes sense. However Pc is a local class/struct, so it is not allowed.
#OP: Specifying the template parameter is a valid approach.
renderer->drawVertices<RenFlexibleVertexPc>(4, RenPrimTriangleFan, material, vpc);
With Pete's additions, you code also compiles on Apple's GCC 4.0.1, so I suspect there's something your posted code is missing that's causing the problem.
#Max: GCC's treatment of your source is standard. Struct B is local to main(), so B (and thus main()::B::print()) is not visible outside main(). As you're probably aware, moving the definition of B outside of main() and it will compile.
The definition of VertexType is already in the code (an enum). Elements is an unsigned long. Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
If it's an enum why pass an object of type array 4 of struct? What is RenFlexibleVertexPc? The last argument to drawVertices should either be a constant pointer to a Vertex object or a const* to an object of a class derived from Vertex.
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
You are calling a function on an uninitialized pointer. I hope this is not the real code. \

Resources