00001 #ifndef _IAIREF_H_
00002 #define _IAIREF_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00025 #include "AICountedObject.h"
00026 #include <utility>
00027
00028 #if AI_AUTO_SUITE_AVAILABLE
00029 #ifndef AICOUNTEDOBJECTSUITE_DEFINED
00030 #define AICOUNTEDOBJECTSUITE_DEFINED 1
00031 #endif
00032 #endif
00033
00034
00035 namespace ai {
00036
00037
00038
00041 class RefReplaceParam;
00042
00043 enum IncrementPolicy
00044 {
00045 DoIncrement,
00046 DoNotIncrement
00047 };
00048
00066 extern AICountedObjectSuite *GetAICountedObjectSuitePtr();
00067
00108 template <class X> class Ref {
00109 public:
00111 Ref () AINOEXCEPT : x(nullptr) {}
00112
00115 Ref (const X& x, IncrementPolicy policy = DoIncrement);
00116
00119 Ref (const Ref<X>& ref);
00120
00124 void swap(Ref<X>& other) AINOEXCEPT
00125 {
00126 std::swap(other.x, x);
00127 }
00128
00129 #ifdef AI_HAS_RVALUE_REFERENCES
00130
00133 Ref(Ref<X>&& other) AINOEXCEPT
00134 {
00135 swap(other);
00136 }
00137 #endif
00138
00140 ~Ref ();
00141
00144 operator X () const AINOEXCEPT
00145 {return x;}
00146
00150 void Assign(const X& x, IncrementPolicy policy = DoIncrement);
00151
00156 Ref<X>& operator= (Ref<X> ref) AINOEXCEPT
00157 {
00158 swap(ref);
00159 return *this;
00160 }
00161
00164 bool operator== (const Ref<X>& ref) const AINOEXCEPT
00165 {return x == ref.x;}
00166
00169 bool operator!= (const Ref<X>& ref) const AINOEXCEPT
00170 {return x != ref.x;}
00171
00178 X* operator<< (void (*f)(const RefReplaceParam& p));
00179
00185 Ref<X>& to();
00186
00187 protected:
00188 X x = nullptr;
00189 };
00190
00191
00192 inline void Replace (const RefReplaceParam&)
00193 {
00194 }
00195
00196 template <class X> Ref<X>::Ref (const X& _x, IncrementPolicy policy) : x(_x)
00197 {
00198 if (x)
00199 {
00200 AICountedObjectSuite* theSuite = GetAICountedObjectSuitePtr();
00201 if (policy == DoIncrement)
00202 theSuite->AddRef(x);
00203 }
00204 }
00205
00206 template <class X> Ref<X>::Ref (const Ref<X>& ref) : x(ref.x)
00207 {
00208 if (x)
00209 {
00210 AICountedObjectSuite* theSuite = GetAICountedObjectSuitePtr();
00211 theSuite->AddRef(x);
00212 }
00213 }
00214
00215 template <class X> Ref<X>::~Ref ()
00216 {
00217 if (x)
00218 {
00219 AICountedObjectSuite* theSuite = GetAICountedObjectSuitePtr();
00220 theSuite->Release(x);
00221 }
00222 }
00223
00224 template <class X> void Ref<X>::Assign(const X& _x, IncrementPolicy policy)
00225 {
00226 if (x != _x)
00227 {
00228 AICountedObjectSuite* theSuite = GetAICountedObjectSuitePtr();
00229 if (x)
00230 {
00231 theSuite->Release(x);
00232 }
00233
00234 x = _x;
00235
00236 if (x)
00237 {
00238 if (policy == DoIncrement)
00239 theSuite->AddRef(x);
00240 }
00241 }
00242 }
00243
00244 template <class X> X* Ref<X>::operator<< (void (*)(const RefReplaceParam &p))
00245 {
00246 if (x)
00247 {
00248 AICountedObjectSuite* theSuite = GetAICountedObjectSuitePtr();
00249 theSuite->Release(x);
00250 }
00251
00252 x = nullptr;
00253 return &x;
00254 }
00255
00256 template <class X> Ref<X>& Ref<X>::to()
00257 {
00258 AICountedObjectSuite* theSuite = GetAICountedObjectSuitePtr();
00259 theSuite->AddRef(x);
00260
00261 return *this;
00262 }
00263
00264 template <class X>
00265 inline bool operator==(const Ref<X>& ref, std::nullptr_t) AINOEXCEPT
00266 {
00267 return (ref.operator X() == nullptr);
00268 }
00269
00270 template <class X>
00271 inline bool operator==(std::nullptr_t, const Ref<X>& ref) AINOEXCEPT
00272 {
00273 return (ref == nullptr);
00274 }
00275
00276 template <class X>
00277 inline bool operator!=(const Ref<X>& ref, std::nullptr_t) AINOEXCEPT
00278 {
00279 return !(ref == nullptr);
00280
00281 }
00282
00283 template <class X>
00284 inline bool operator!=(std::nullptr_t, const Ref<X>& ref) AINOEXCEPT
00285 {
00286 return (ref != nullptr);
00287 }
00288
00289
00290 }
00291
00292 #if !AICOUNTEDOBJECTSUITE_DEFINED
00293
00294 extern "C"
00295 {
00296 extern AICountedObjectSuite *sAICountedObject;
00297 }
00298
00303 inline AICountedObjectSuite *ai::GetAICountedObjectSuitePtr()
00304 {
00305 return sAICountedObject;
00306 }
00307
00308 #endif //AICOUNTEDOBJECTSUITE_DEFINED
00309
00310 #endif