[6879] Not apply casting time spell bonuses mods to creature (non-pets) casted spells...
[getmangos.git] / dep / include / zthread / ThreadLocal.h
blobbb83a0fe3ef784e34095b46842a0a844ca6daf26
1 /*
2 * Copyright (c) 2005, Eric Crahen
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is furnished
9 * to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef __ZTTHREADLOCAL_H__
24 #define __ZTTHREADLOCAL_H__
26 #include "zthread/ThreadLocalImpl.h"
28 namespace ZThread {
30 /**
31 * @class ThreadLocal
33 * @author Eric Crahen <http://www.code-foo.com>
34 * @date <2003-07-27T11:18:21-0400>
35 * @version 2.3.0
37 * Provides access to store and retrieve value types to and from a thread local
38 * storage context. A thread local storage context consists of the calling thread
39 * a specific ThreadLocal object. Since this context is specific to each thread
40 * whenever a value is stored in a ThreadLocal that is accessible from multiple
41 * threads, it can only be retrieved by the thread that stored it.
43 * The first time a thread accesses the value associated with a thread local storage
44 * context, a value is created. That value is either an initial value (determined by
45 * InitialValueT) or an inherited value (determined by ChildValueT).
47 * - If a threads parent had no value associated with a ThreadLocal when the thread was created,
48 * then the InitialValueT functor is used to create an initial value.
50 * - If a threads parent did have a value associated with a ThreadLocal when the thread was
51 * created, then the childValueT functor is used to create an initial value.
53 * Not all ThreadLocal's support the inheritance of values from parent threads. The default
54 * behavoir is to create values through the InitialValueT functor for all thread when
55 * they first access a thread local storage context.
57 * - Inheritance is enabled automatically when a user supplies a ChildValueT functor other
58 * than the default one supplied.
60 * - Inheritance can be controlled explicitly by the user through a third functor,
61 * InheritableValueT.
63 * <h2>Examples</h2>
65 * - <a href="#ex1">Default initial value</a>
66 * - <a href="#ex2">User-specified initial value</a>
67 * - <a href="#ex3">User-specified inherited value</a>
69 * <h2><a name="ex1">Default initial value</a></h2>
70 * A ThreadLocal that does not inherit, and uses the default value
71 * for an int as its initial value.
73 * @code
75 * #include "zthread/ThreadLocal.h"
76 * #include "zthread/Thread.h"
77 * #include <iostream>
79 * using namespace ZThread;
81 * class aRunnable : public Runnable {
82 * ThreadLocal<int> localValue;
83 * public:
84 * void run() {
85 * std::cout << localValue.get() << std::endl;
86 * }
87 * };
89 * int main() {
91 * // Create a shared task to display ThreadLocal values
92 * Task task(new aRunnable);
94 * Thread t0(task); t0.wait();
95 * Thread t1(task); t1.wait();
96 * Thread t2(task); t2.wait();
98 * // Output:
100 * // 0
101 * // 0
102 * // 0
104 * return 0;
108 * @endcode
110 * <h2><a name="ex2">User-specified initial value</a></h2>
111 * A ThreadLocal that does not inherit, and uses a custom initial value.
113 * @code
115 * #include "zthread/ThreadLocal.h"
116 * #include "zthread/Thread.h"
117 * #include <iostream>
119 * using namespace ZThread;
121 * struct anInitialValueFn {
122 * int operator()() {
123 * static int next = 100;
124 * int val = next; next += 100;
125 * return val;
127 * };
129 * class aRunnable : public Runnable {
130 * ThreadLocal<int, anInitialValueFn> localValue;
131 * public:
132 * void run() {
133 * std::cout << localValue.get() << std::endl;
135 * };
137 * int main() {
139 * // Create a shared task to display ThreadLocal values
140 * Task task(new aRunnable);
142 * Thread t0(task); t0.wait();
143 * Thread t1(task); t1.wait();
144 * Thread t2(task); t2.wait();
146 * // Output:
148 * // 100
149 * // 200
150 * // 300
152 * return 0;
156 * @endcode
158 * <h2><a name="ex3">User-specified inherited value</a></h2>
159 * A ThreadLocal that does inherit and modify child values.
160 * (The default initial value functor is used)
162 * @code
164 * #include "zthread/ThreadLocal.h"
165 * #include "zthread/Thread.h"
166 * #include <iostream>
168 * using namespace ZThread;
170 * struct anInheritedValueFn {
171 * int operator()(int val) {
172 * return val + 100;
174 * };
176 * // This Runnable associates no ThreadLocal value in the main thread; so
177 * // none of the child threads have anything to inherit.
178 * class aRunnable : public Runnable {
179 * ThreadLocal<int, ThreadLocalImpl::InitialValueFn<int>, anInheritedValueFn> localValue;
180 * public:
181 * void run() {
182 * std::cout << localValue.get() << std::endl;
184 * };
186 * // This Runnable associates a ThreadLocal value in the main thread which
187 * // is inherited when the child threads are created.
188 * class anotherRunnable : public Runnable {
189 * ThreadLocal<int, ThreadLocalImpl::InitialValueFn<int>, anInheritedValueFn> localValue;
190 * public:
191 * anotherRunnable() {
192 * localValue.set(100);
194 * void run() {
195 * std::cout << localValue.get() << std::endl;
197 * };
199 * int main() {
201 * // Create a shared task to display ThreadLocal values
202 * Task task(new aRunnable);
204 * Thread t0(task); t0.wait();
205 * Thread t1(task); t1.wait();
206 * Thread t2(task); t2.wait();
208 * // Output:
210 * // 0
211 * // 0
212 * // 0
214 * task = Task(new anotherRunnable);
216 * Thread t10(task); t10.wait();
217 * Thread t11(task); t11.wait();
218 * Thread t12(task); t12.wait();
220 * // Output:
222 * // 200
223 * // 200
224 * // 200
226 * return 0;
230 * @endcode
232 * <h2>Parameters</h2>
234 * <em>InitialValueT</em>
236 * This template parameter should indicate the functor used to set
237 * the initial value. It should support the following operator:
239 * <code>
240 * // required operator
241 * T operator()
243 * // supported expression
244 * InitialValueT()()
245 * </code>
248 * <em>ChildValueT</em>
250 * This template parameter should indicate the functor used to set
251 * the value that will be inherited by thread whose parent have associated
252 * a value with the ThreadLocal's context at the time they are created.
253 * It should support the following operator:
255 * <code>
256 * // required operator
257 * T operator(const T& parentValue)
259 * // supported expression
260 * ChildValueT()(parentValue)
261 * </code>
264 * <em>InheritableValueT</em>
266 * This template parameter should indicate the functor, used to determine
267 * wheather or not this ThreadLocal will allow values from a parent threads
268 * context to be inherited by child threads when they are created.
269 * It should support the following operator:
271 * <code>
272 * // required operator
273 * bool operator(const T& childValueFunctor)
275 * // supported expression
276 * InheritableValueT()( ChildValueT() )
277 * </code>
280 template <
281 typename T,
282 typename InitialValueT = ThreadLocalImpl::InitialValueFn<T>,
283 typename ChildValueT = ThreadLocalImpl::UniqueChildValueFn,
284 typename InheritableValueT = ThreadLocalImpl::InheritableValueFn
286 class ThreadLocal : private ThreadLocalImpl {
288 typedef ThreadLocalImpl::ValuePtr ValuePtr;
290 class Value : public ThreadLocalImpl::Value {
292 T value;
294 public:
296 Value() : value( InitialValueT()() ) { }
298 Value(const Value& v) : value( ChildValueT()(v.value) ) { }
300 virtual ~Value() { }
302 operator T() { return value; }
304 const Value& operator=(const T& v) { value = v; }
306 virtual bool isInheritable() const {
307 return InheritableValueT()( ChildValueT() );
310 virtual ValuePtr clone() const {
311 return ValuePtr( new Value(*this) );
316 static ValuePtr createValue() {
317 return ValuePtr( new Value );
320 public:
323 * Get the value associated with the context (this ThreadLocal and
324 * the calling thread) of the invoker. If no value is currently
325 * associated, then an intial value is created and associated; that value
326 * is returned.
328 * @return <em>T</em> associated value.
330 * @post If no value has been associated with the invoking context
331 * then an inital value will be associated. That value is
332 * created by the <em>InitialValueT</em> functor.
334 T get() const {
335 return (T)reinterpret_cast<Value&>( *value(&createValue) );
339 * Replace the value associated with the context (this ThreadLocal and
340 * the calling thread) of the invoker. If no value is currently
341 * associated, then an intial value is first created and subsequently
342 * replaced by the new value.
344 * @param v value of type <em>T</em> to associate.
346 * @post If no value has been associated with the invoking context
347 * then an inital value will first be associated. That value is
348 * created by the <em>InitialValueT</em> functor and then
349 * replaced with the new value.
351 void set(T v) const {
352 reinterpret_cast<Value&>( *value(&createValue) ) = v;
356 * Remove any value current associated with this ThreadLocal.
358 * @post Upon thier next invocation the get() and set() functions will behave as
359 * if no value has been associated with this ThreadLocal and an
360 * initial value will be generated.
362 void clear() const {
363 ThreadLocalImpl::clear();
367 * Remove any value current associated with <em>any</em> ThreadLocal.
369 * @post Upon thier next invocation the get() and set() functions will behave as
370 * if no value has been associated with <em>any</em> ThreadLocal and new
371 * initial values will be generated.
373 static void clearAll() {
374 ThreadLocalImpl::clearAll();
380 } // namespace ZThread
382 #endif // __ZTTHREADLOCAL_H__