Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ref.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_CORE_REF_H_)
21 #define __MITSUBA_CORE_REF_H_
22 
23 #include "util.h"
24 #include <set>
25 
27 
28 /**
29  * \headerfile mitsuba/core/ref.h mitsuba/mitsuba.h
30  * \brief Reference counting helper
31  *
32  * The \a ref refeference template is a simple wrapper to store a
33  * pointer to an object. It takes care of increasing and decreasing
34  * the reference count of the object. When the last reference goes
35  * out of scope, the associated object will be deallocated.
36  *
37  * \author Wenzel Jakob
38  * \ingroup libcore
39  */
40 template <typename T> class ref {
41 public:
42  /// Create a NULL reference
43  ref() : m_ptr(NULL) { }
44 
45  /// Construct a reference from a pointer
46  ref(T *ptr) : m_ptr(ptr) { if (m_ptr) ((Object *) m_ptr)->incRef(); }
47 
48  /// Copy-constructor
49  ref(const ref &pRef) : m_ptr(pRef.m_ptr) { if (m_ptr) ((Object *) m_ptr)->incRef(); }
50 
51  /// Destroy this reference
52  ~ref() { if (m_ptr) ((Object *) m_ptr)->decRef(); }
53 
54  /// Overwrite this reference with another reference
55  inline ref& operator= (const ref& r) {
56  if (m_ptr == r.m_ptr)
57  return *this;
58  if (m_ptr)
59  ((Object *) m_ptr)->decRef();
60  m_ptr = r.m_ptr;
61  if (m_ptr)
62  ((Object *) m_ptr)->incRef();
63  return *this;
64  }
65 
66  /// Overwrite this reference with a pointer to another object
67  inline ref& operator= (T *ptr) {
68  if (m_ptr == ptr)
69  return *this;
70  if (m_ptr)
71  ((Object *) m_ptr)->decRef();
72  m_ptr = ptr;
73  if (m_ptr)
74  ((Object *) m_ptr)->incRef();
75  return *this;
76  }
77 
78  /// Compare this reference with another reference
79  inline bool operator== (const ref &pref) const { return (m_ptr == pref.m_ptr); }
80 
81  /// Compare this reference with another reference
82  inline bool operator!= (const ref &pref) const { return (m_ptr != pref.m_ptr); }
83 
84  /// Compare this reference with a pointer
85  inline bool operator== (const T* ptr) const { return (m_ptr == ptr); }
86 
87  /// Compare this reference with a pointer
88  inline bool operator!= (const T* ptr) const { return (m_ptr != ptr); }
89 
90  /// Check whether this is a NULL reference
91  inline bool operator!() const { return (m_ptr == NULL); }
92 
93  /// Access the object referenced by this reference
94  inline T* operator-> () { return m_ptr; }
95 
96  /// Access the object referenced by this reference
97  inline const T* operator-> () const { return m_ptr; }
98 
99  /// Return a C++ reference to the referenced object
100  inline T& operator*() { return *m_ptr; }
101 
102  /// Return a C++ reference to the referenced object
103  inline const T& operator*() const { return *m_ptr; }
104 
105  /// Return a pointer to the referenced object
106  inline operator T* () { return m_ptr; }
107 
108  /// Return a pointer to the referenced object
109  inline T* get() { return m_ptr; }
110 
111  /// Return a pointer to the referenced object
112  inline const T* get() const { return m_ptr; }
113 
114  /**
115  * Return a string representation of this reference
116  */
117  inline std::string toString() const {
118  if (m_ptr == NULL)
119  return formatString("ref<%s>[null]",
120  T::m_theClass->getName().c_str());
121  else
122  return formatString("ref<%s>[ref=%i, ptr=%s]",
123  m_ptr->getClass()->getName().c_str(),
124  m_ptr->getRefCount(), m_ptr->toString().c_str());
125  }
126 private:
127  T *m_ptr;
128 };
129 
130 /// \cond
131 
132 /// Comparison operator for references
133 template <typename T> struct ref_comparator {
134  bool operator() (const ref<T>& lhs, const ref<T>& rhs) const {
135  return lhs.get() < rhs.get();
136  }
137 };
138 
139 /// \endcond
140 
141 /**
142  * \brief Simple reference-counted vector container based on \c std::vector and \ref ref
143  */
144 template <typename T> class ref_vector : public std::vector< ref<T> > {
145 public:
146  typedef std::vector< ref<T> > parent_type;
147 
149  ref_vector(size_t size) : parent_type(size) {}
150  ref_vector(const ref_vector &vec) : parent_type(vec) {}
151 
152  /// Remove all duplicates without changing the order
153  inline void ensureUnique() {
154  std::set<T *> seen;
155 
156  typename parent_type::iterator it1 = this->begin(), it2 = this->begin();
157  for (; it1 < this->end(); ++it1) {
158  if (seen.find(it1->get()) != seen.end())
159  continue;
160  seen.insert(it1->get());
161  if (it1 != it2)
162  *it2++ = *it1;
163  else
164  it2++;
165  }
166  this->erase(it2, this->end());
167  }
168 
169  /// Check if a certain pointer is contained in the vector
170  inline bool contains(const T *ptr) const {
171  for (typename parent_type::const_iterator it = this->begin();
172  it != this->end(); ++it)
173  if (it->get() == ptr)
174  return true;
175  return false;
176  }
177 };
178 
180 
181 #endif /* __MITSUBA_CORE_REF_H_ */
MTS_EXPORT_CORE std::string formatString(const char *pFmt,...)
Wrapped snprintf.
void ensureUnique()
Remove all duplicates without changing the order.
Definition: ref.h:153
~ref()
Destroy this reference.
Definition: ref.h:52
ref & operator=(const ref &r)
Overwrite this reference with another reference.
Definition: ref.h:55
std::vector< ref< T > > parent_type
Definition: ref.h:146
ref_vector()
Definition: ref.h:148
Simple reference-counted vector container based on std::vector and ref.
Definition: ref.h:144
ref_vector(size_t size)
Definition: ref.h:149
bool contains(const T *ptr) const
Check if a certain pointer is contained in the vector.
Definition: ref.h:170
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
T & operator*()
Return a C++ reference to the referenced object.
Definition: ref.h:100
T * operator->()
Access the object referenced by this reference.
Definition: ref.h:94
ref()
Create a NULL reference.
Definition: ref.h:43
std::string toString() const
Definition: ref.h:117
ref_vector(const ref_vector &vec)
Definition: ref.h:150
const T & operator*() const
Return a C++ reference to the referenced object.
Definition: ref.h:103
bool operator==(const ref &pref) const
Compare this reference with another reference.
Definition: ref.h:79
Reference counting helper.
Definition: ref.h:40
ref(T *ptr)
Construct a reference from a pointer.
Definition: ref.h:46
T * get()
Return a pointer to the referenced object.
Definition: ref.h:109
bool operator!=(const ref &pref) const
Compare this reference with another reference.
Definition: ref.h:82
Parent of all Mitsuba classes.
Definition: object.h:38
#define MTS_NAMESPACE_END
Definition: platform.h:138
ref(const ref &pRef)
Copy-constructor.
Definition: ref.h:49
bool operator!() const
Check whether this is a NULL reference.
Definition: ref.h:91