lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
resource.h
00001 /*****************************************************/
00002 /* lean Smart                   (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_SMART_RESOURCE
00006 #define LEAN_SMART_RESOURCE
00007 
00008 #include "ref_counter.h"
00009 
00013 
00015 #define LEAN_MAKE_RESOURCE \
00016     template <class Resource, bool Critical> \
00017     friend class lean::smart::resource_ptr; \
00018     template <class Resource> \
00019     friend class lean::smart::weak_resource_ptr;
00020 
00023 #define LEAN_RENEW_RESOURCE LEAN_MAKE_RESOURCE \
00024     protected: \
00025         const lean_resource_base::ref_counter_type& ref_counter() const { return lean_resource_base::ref_counter(); } \
00026     public: \
00027         lean_resource_base::ref_counter_type::counter_type ref_count() const { return lean_resource_base::ref_count(); }
00028 
00030 
00031 namespace lean
00032 {
00033 namespace smart
00034 {
00035 
00036 // Prototypes
00037 template <class Resource, bool Critical>
00038 class resource_ptr;
00039 template <class Resource>
00040 class weak_resource_ptr;
00041 
00043 template < class Counter = long, class Allocator = std::allocator<Counter>, bool Lazy = false >
00044 class resource
00045 {
00046     LEAN_MAKE_RESOURCE
00047 
00048 protected:
00050     typedef resource lean_resource_base;
00051 
00053     typedef ref_counter<Counter, Allocator> ref_counter_type;
00054     mutable ref_counter_type m_refCounter;
00055 
00056 private:
00058     LEAN_NOINLINE void create_ref_counter() const
00059     {
00060         LEAN_ASSERT(m_refCounter.is_null());
00061         m_refCounter = ref_counter_type();
00062     }
00063 
00064 protected:
00066     resource()
00067         : m_refCounter( Lazy ? ref_counter_type::null() : ref_counter_type() ) { }
00069     resource(const typename ref_counter_type::allocator_type& allocator)
00070         : m_refCounter(allocator) { }
00072     LEAN_INLINE resource(const resource& right) { }
00074     LEAN_INLINE resource& operator =(const resource& right) { return *this; }
00075 #ifndef LEAN_OPTIMIZE_DEFAULT_DESTRUCTOR
00076 
00077     LEAN_INLINE ~resource() throw() { }
00078 #endif
00079 
00081     const ref_counter_type& ref_counter() const
00082     {
00083         if (Lazy)
00084         {
00085             if (m_refCounter.is_null())
00086                 create_ref_counter();
00087         }
00088         return m_refCounter;
00089     }
00090 
00091 public:
00093     typename ref_counter_type::counter_type ref_count() const { return m_refCounter.count(); }
00094 };
00095 
00097 template < class Counter = long, class Allocator = std::allocator<Counter> >
00098 class resource_interface
00099 {
00100     LEAN_MAKE_RESOURCE
00101 
00102 protected:
00104     LEAN_INLINE resource_interface& operator =(const resource_interface& right) { return *this; }
00105 
00107     typedef ref_counter<Counter, Allocator> ref_counter_type;
00109     virtual const ref_counter_type& ref_counter() const = 0;
00110 
00111 public:
00113     virtual ~resource_interface() throw() { }
00114 
00116     virtual typename ref_counter_type::counter_type ref_count() const = 0;
00117 };
00118 
00119 } // namespace
00120 
00121 using smart::resource;
00122 using smart::resource_interface;
00123 
00124 } // namespace
00125 
00126 #endif