Download | Plain Text | No Line Numbers
- /**
- * @module shared_ptr
- * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
- * @brief Class template shared_ptr
- * @date 13.06.2009
- */
-
- #ifndef SHARED_PTR_H
- #define SHARED_PTR_H
-
- #include <algorithm>
-
- #undef SOLVED_1
- #define SOLVED_1
-
- namespace Ti
- {
- /**
- * @class shared_ptr
- *
- * The templates stores a pointer, usually obtained via new.
- * shared_ptr implements semantics of shared ownership; the last remaining
- * owner of the pointer is responsible for destroying the object, or
- * otherwise releasing the resources associated with the stored pointer.
- * A shared_ptr object is empty if it does not own a pointer.
- */
- template <typename T>
- class shared_ptr
- {
- private:
- /** stored pointer */
- T* m_ptr;
- /** reference counter */
- unsigned long* m_count;
-
- public:
- /**
- * @method shared_ptr
- * @brief Default ctor
- * @param -
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post get() == m_count == NULL
- */
- shared_ptr()
- : m_ptr(NULL), m_count(NULL)
- {}
-
- /**
- * @method get
- * @brief Returns pointer of enclosed object
- * @param -
- * @return returns the stored pointer, null pointer if *this is empty.
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- T* get() const
- {
- return m_ptr;
- }
-
- /**
- * @method shared_ptr
- * @brief Copy ctor. If r is empty, constructs an empty shared_ptr
- * object - otherwise, constructs a shared_ptr object that
- * shares ownership with r.
- * @param other instance to copy from
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post get() == other.get() && m_count == other.m_count
- */
- shared_ptr(const shared_ptr<T>& other)
- : m_ptr(other.m_ptr), m_count(other.m_count)
- {
- add_ref();
- }
-
- /**
- * @method shared_ptr
- * @brief Copy ctor. If other is empty, constructs an empty shared_ptr
- * object - otherwise, constructs a shared_ptr object that
- * shares ownership with other.
- * @param other instance to copy from
- * @return -
- * @globalvars none
- * @exception none
- * @pre The constructor shall not participate in the overload
- * resolution unless O* is implicitly convertible to T*.
- * @post get() == other.get() && m_count == other.m_count
- */
- template <typename O>
- shared_ptr(const shared_ptr<O>& other)
- : m_ptr(other.m_ptr), m_count(other.m_count)
- {
- add_ref();
- }
-
- /**
- * @method shared_ptr
- * @brief Copy ctor. Constructs a shared_ptr instance that stores ptr
- * and shares ownership with other.
- * @param other instance to copy from
- * @param ptr ptr to store
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post get() == p && m_count == other.m_count
- */
- template <typename O>
- shared_ptr(const shared_ptr<O>& other, T* ptr)
- : m_ptr(ptr), m_count(other.m_count)
- {
- add_ref();
- }
-
- /**
- * @method shared_ptr
- * @brief Copy ctor. Constructs a shared_ptr object that owns the pointer p.
- * @param p pointer to store
- * @return -
- * @globalvars none
- * @exception bad_alloc if memory couldn't be optained
- * @pre p shall be convertible to T*. Y shall be a complete type. The
- * expression delete p shall be well formed, shall have well
- * defined behavior, and shall not throw exceptions.
- * @post get() == p && m_count == 1
- */
- template <typename O>
- explicit shared_ptr(O* p)
- : m_ptr(p), m_count(new unsigned long(1))
- {}
-
- /**
- * @method operator=
- * @brief operator =
- * @param other object to compare with
- * @return always *this
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- shared_ptr& operator=(const shared_ptr<T>& other)
- {
- if (*this == other)
- return *this;
- release();
- m_ptr = other.m_ptr;
- m_count = other.m_count;
- add_ref();
- return *this;
- }
-
- /**
- * @method operator=
- * @brief operator =
- * @param other object to compare with
- * @return always *this
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template <typename O>
- shared_ptr& operator=(const shared_ptr<O>& other)
- {
- if (*this == other)
- return *this;
- release();
- m_ptr = other.m_ptr;
- m_count = other.m_count;
- add_ref();
- return *this;
- }
-
- /**
- * @method ~shared_ptr
- * @brief Dtor
- * @param -
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- ~shared_ptr()
- {
- release();
- }
-
- /**
- * @method operator*
- * @brief operator *
- * @param -
- * @return returns *get()
- * @globalvars none
- * @exception none
- * @pre get() != NULL
- * @post none
- */
- T& operator*() const
- {
- return *m_ptr;
- }
-
- /**
- * @method operator->
- * @brief operator ->
- * @param -
- * @return returns get()
- * @globalvars none
- * @exception none
- * @pre get() != NULL
- * @post none
- */
- T* operator->() const
- {
- return m_ptr;
- }
-
- /**
- * @method swap
- * @brief Exchanges the contents of *this and other.
- * @param other instance to swap with
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- void swap(shared_ptr<T>& other)
- {
- std::swap(m_ptr, other.m_ptr);
- std::swap(m_count, other.m_count);
- }
-
- /**
- * @method reset
- * @brief Equivalent to shared_ptr().swap(*this).
- * @param -
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- inline void reset()
- {
- shared_ptr().swap(*this);
- }
-
- private:
- /**
- * @method add_ref
- * @brief Increase reference counter
- * @param -
- * @return -
- * @globalvars none
- * @exception none
- * @pre m_count != NULL
- * @post none
- */
- void add_ref()
- {
- if (m_count != NULL)
- ++(*m_count);
- }
-
- /**
- * @method release
- * @brief Decrease reference counter
- * if m_count == 0 free all resources
- * @param -
- * @return -
- * @globalvars none
- * @exception none
- * @pre m_ptr != NULL && m_count != NULL
- * @post none
- */
- void release()
- {
- if (m_ptr != NULL)
- {
- --(*m_count);
- if (*m_count == 0)
- {
- delete m_ptr;
- delete m_count;
- }
- }
- }
-
- template<class O> friend class shared_ptr;
-
- template <typename R, typename... Args>
- friend shared_ptr<R> make_shared(Args...);
-
- template<typename U1, typename U2>
- friend bool operator==(const shared_ptr<U1>& a, const shared_ptr<U2>& b);
-
- template<typename U1, typename U2>
- friend bool operator==(const shared_ptr<U1>& a, const U2* b);
-
- template<typename U1, typename U2>
- friend bool operator==(const U1* a, const shared_ptr<U2>& b);
-
- template<typename U1, typename U2>
- friend bool operator!=(const shared_ptr<U1>& a, const U2* b);
-
- template<typename U1, typename U2>
- friend bool operator!=(const U1* a, const shared_ptr<U2>& b);
-
- template<typename U1, typename U2>
- friend bool operator!=(const shared_ptr<U1>& a, const shared_ptr<U2>& b);
-
- template <typename R, typename F>
- friend shared_ptr<R> shared_dynamic_cast(const shared_ptr<F>& from);
- };
-
- /**
- * @method make_shared
- * @brief Creates an instance of shared_ptr containing a pointer to the
- * also created instance of T(args...).
- * @param args arguments for ctor of T.
- * @return A shared_ptr instance that stores and owns the address of the
- * newly constructed object of type T.
- * @globalvars none
- * @exception bad_alloc
- * @pre none
- * @post get() != 0 && use_count() == 1
- */
- template <typename T, typename ... Args>
- shared_ptr<T> make_shared(Args ... args)
- {
- return shared_ptr<T>(new T(args ...));
- }
-
- /**
- * @method operator==
- * @brief operator ==
- * @param a object1 to compare
- * @param b object2 to compare
- * @return true if both objects contain the same pointer, false otherwise.
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template<typename U1, typename U2>
- bool operator==(const shared_ptr<U1>& a, const shared_ptr<U2>& b)
- {
- return a.get() == b.get();
- }
-
- /**
- * @method operator==
- * @brief operator ==
- * @param a shared_ptr to compare
- * @param b pointer to compare
- * @return true if a contains pointer b, false otherwise.
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template<typename U1, typename U2>
- bool operator==(const shared_ptr<U1>& a, const U2* b)
- {
- return a.get() == b;
- }
-
- /**
- * @method operator==
- * @brief operator ==
- * @param a pointer to compare
- * @param b shared_ptr to compare
- * @return true if b contains pointer a, false otherwise.
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template<typename U1, typename U2>
- bool operator==(const U1* a, const shared_ptr<U2>& b)
- {
- return a == b.get();
- }
-
- /**
- * @method operator!=
- * @brief operator !=
- * @param a shared_ptr to compare
- * @param b pointer to compare
- * @return true if a contains different pointer than b, false otherwise.
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template<typename U1, typename U2>
- bool operator!=(const shared_ptr<U1>& a, const U2* b)
- {
- return a.get() != b;
- }
-
- /**
- * @method operator!=
- * @brief operator !=
- * @param a pointer to compare
- * @param b shared_ptr to compare
- * @return true if b contains different pointer than a, false otherwise.
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template<typename U1, typename U2>
- bool operator!=(const U1* a, const shared_ptr<U2>& b)
- {
- return a != b.get();
- }
-
- /**
- * @method operator!=
- * @brief operator !=
- * @param a object1 to compare
- * @param b object2 to compare
- * @return true if both objects contain different pointers, false otherwise.
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template<typename U1, typename U2>
- bool operator!=(const shared_ptr<U1>& a, const shared_ptr<U2>& b)
- {
- return a.get() != b.get();
- }
-
- /**
- * @method shared_dynamic_cast
- * @brief Converts pointer from F to T by using dynamic_cast.
- * @param from object to cast
- * @return When dynamic_cast<T*>(from.get()) returns a nonzero value,
- * a shared_ptr<T> object that stores a copy of it and shares
- * ownership with from - otherwise an empty shared_ptr<T> object.
- * @globalvars none
- * @exception none
- * @pre The expression shared_dynamic_cast<T*>(from.get()) shall be well
- * formed and shall have well defined behavior.
- * @post w.get() == dynamic_cast<T*>(from.get()), where w is the return value.
- */
- template <typename T, typename F>
- shared_ptr<T> shared_dynamic_cast(const shared_ptr<F>& from)
- {
- T* castptr = dynamic_cast<T *>(from.get());
- if (castptr != NULL)
- return shared_ptr<T>(from, castptr);
- else
- return shared_ptr<T>();
- }
- } // end namespace ti
-
- namespace std
- {
- using namespace Ti;
-
- /**
- * @method swap
- * @brief Exchanges the contents of t1 and t2.
- * @param t1 instance#1 of shared_ptr
- * @param t2 instance#2 of shared_ptr
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- template <typename T>
- inline void swap(shared_ptr<T>& t1, shared_ptr<T>& t2)
- {
- t1.swap(t2);
- }
- }
-
- #endif
-
- /* vim: set et sw=2 ts=2: */
-