//+----------------------------------------------------------------------------+ //| Description: Magic Set Editor - Program to make Magic (tm) cards | //| Copyright: (C) 2001 - 2006 Twan van Laarhoven | //| License: GNU General Public License 2 or later (see file COPYING) | //+----------------------------------------------------------------------------+ #ifndef HEADER_UTIL_DYNAMIC_ARG #define HEADER_UTIL_DYNAMIC_ARG /** @file util/dynamic_arg.hpp * * @brief Support for 'dynamicly scopped' arguments. * This header */ // ----------------------------------------------------------------------------- : Includes #include // ----------------------------------------------------------------------------- : Dynamic argument #ifdef _MSC_VER # define THREAD_LOCAL __declspec(thread) #else # define THREAD_LOCAL __thread #endif /// Declare a dynamic argument. /** The value of the argument can be got with: name() * To change the value use WITH_DYNAMIC_ARG(name, newValue) { ... } * To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file */ #define DECLARE_DYNAMIC_ARG(Type, name) \ extern THREAD_LOCAL Type name##_private; \ inline Type name() { return name##_private; } \ class name##_changer { \ public: \ inline name##_changer(Type const& newValue) \ : oldValue(name##_private) { \ name##_private = newValue; \ } \ inline ~name##_changer() { \ name##_private = oldValue; \ } \ inline operator bool() { return true; } \ private: \ Type oldValue; \ } /// Implementation of a dynamic argument #define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \ THREAD_LOCAL Type name##_private = initial; /// Locally change the value of a dynamic argument /** Usage: * @code * // here name() == old value * WITH_DYNAMIC_ARG(name, newValue) { * // here name() == newValue * } * // here name() == old value * @endcode */ #define WITH_DYNAMIC_ARG(name, value) \ if (name##_changer(value)) // ----------------------------------------------------------------------------- : EOF #endif