[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

utilities.hxx File Reference VIGRA

#include "config.hxx"
#include "error.hxx"
#include "metaprogramming.hxx"
#include "tuple.hxx"
#include "diff2d.hxx"
#include "mathutil.hxx"
#include <string>
#include <sstream>
#include <cctype>

Go to the source code of this file.

Namespaces

 vigra
 

Macros

#define VIGRA_FINALLY(destructor)   VIGRA_FINALLY_IMPL(destructor, __COUNTER__)
 

Functions

template<class T >
std::string asString (T t)(...)
 
std::string normalizeString (std::string const &s)
 
std::string tolower (std::string s)
 

Macro Definition Documentation

#define VIGRA_FINALLY (   destructor)    VIGRA_FINALLY_IMPL(destructor, __COUNTER__)

Emulate the 'finally' keyword as known from Python and other languages.

This macro improves upon the famous Resource Acquisition Is Initialization idiom, where a resource (e.g. heap memory or a mutex) is automatically free'ed when program execution leaves the current scope. Normally, this is implemented by calling a suitable function in the destructor of a dedicated helper class (e.g. std::unique_ptr or std::lock_guard<std::mutex>).

Traditionally, a separate helper class has to be implemented for each kind of resource to be handled. In contrast, the macro VIGRA_FINALLY creates such a class on the fly by means of an embedded lambda expression.

Usage:

#include <vigra/utilities.hxx>

1 std::mutex my_mutex;
2 ...
3 {
4  // the following two lines are equivalent to
5  // std::unique_ptr<std::string> my_string = new std::string("foo");
6  std::string * my_string = new std::string("foo");
7  VIGRA_FINALLY(delete my_string);
8 
9  // the following two lines are equivalent to
10  // std::lock_guard<std::mutex> lock(my_mutex);
11  my_mutex.lock();
12  VIGRA_FINALLY(my_mutex.unlock());
13 
14  ...
15 }
16 // the string has been deallocated and the mutex is unlocked

You can pass any code to this macro. Multiple statements must be enclosed in braces as usual. Arbitrary many calls to VIGRA_FINALLY can be placed in the same scope. Their actions will be executed in the reversed order of declaration:

1 int i = 0;
2 ...
3 {
4  VIGRA_FINALLY({ // execute multiple statements
5  i = i*i;
6  ++i;
7  });
8 
9  VIGRA_FINALLY( i += 2 ); // this executes first
10 
11  assert(i == 0); // as yet, nothing happend
12 }
13 assert(i == 5); // 'finally' code was executed in reversed order at end-of-scope

This idea was popularized by Marko Tintor in "<a href="http://blog.memsql.com/c-error-handling-with-auto/">The Auto Macro: A Clean Approach to C++ Error Handling</a>".

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.10.0