    // Copyright (C) 2007  Davis E. King (davis@dlib.net)
    // License: Boost Software License   See LICENSE.txt for the full license.
    #undef DLIB_WEAK_PTr_ABSTRACT_
    #ifdef DLIB_WEAK_PTr_ABSTRACT_

    #include "shared_ptr_abstract.h"

    namespace dlib {

        template <
            typename T
            >
        class weak_ptr
        {

            /*!
                INITIAL VALUE
                    defined by constructor

                WHAT THIS OBJECT REPRESENTS
                    The weak_ptr class template stores a weak reference to an object that is
                    already managed by a shared_ptr. To access the object, a weak_ptr can
                    be converted to a shared_ptr using the member function lock().

                    This is an implementation of the std::tr1::weak_ptr template from the
                    document ISO/IEC PDTR 19768, Proposed Draft Technical Report on C++
                    Library Extensions.  The only deviation from that document is that this
                    shared_ptr is declared inside the dlib namespace rather than std::tr1.
            !*/

        public:
            typedef T element_type;

            weak_ptr(
            );
            /*!
                ensures
                    - #use_count() == 0
                    - creates an empty weak_ptr
            !*/

            template<typename Y>
            weak_ptr(
                const shared_ptr<Y>& r
            );
            /*!
                requires
                    - Y* must be convertible to T*
                ensures
                    - if (r is empty) then
                        - constructs an empty weak_ptr object
                    - else
                        - constructs a weak_ptr object that shares ownership with r and
                          stores a copy of the pointer stored in r.
                    - #use_count() == #r.use_count()
            !*/

            weak_ptr(
                const weak_ptr& r
            );
            /*!
                ensures
                    - if (r is empty) then
                        - constructs an empty weak_ptr object
                    - else
                        - constructs a weak_ptr object that shares ownership with r and
                          stores a copy of the pointer stored in r.
                    - #use_count() == #r.use_count()
            !*/

            template<typename Y>
            weak_ptr(
                const weak_ptr<Y>& r
            );
            /*!
                requires
                    - Y* must be convertible to T*
                ensures
                    - if (r is empty) then
                        - constructs an empty weak_ptr object
                    - else
                        - constructs a weak_ptr object that shares ownership with r and
                          stores a copy of the pointer stored in r.
                    - #use_count() == #r.use_count()
            !*/

            ~weak_ptr(
            );
            /*!
                ensures
                    - destroys this weak_ptr object but has no effect on the object its
                      stored pointer points to.
            !*/

            weak_ptr& operator= (
                const weak_ptr& r
            );
            /*!
                ensures
                    - equivalent to weak_ptr(r).swap(*this)
            !*/

            template<typename Y>
            weak_ptr& operator= (
                const weak_ptr<Y>& r
            );
            /*!
                requires
                    - Y* must be convertible to T*
                ensures
                    - equivalent to weak_ptr(r).swap(*this)
            !*/

            template<typename Y>
            weak_ptr& operator=(
                const shared_ptr<Y>& r
            );
            /*!
                requires
                    - Y* must be convertible to T*
                ensures
                    - equivalent to weak_ptr(r).swap(*this)
            !*/

            long use_count(
            ) const;
            /*!
                ensures
                    - if (*this is empty) then
                        - returns 0
                    - else
                        - returns the number of shared_ptr instances that share ownership
                          with *this
            !*/

            bool expired(
            ) const;
            /*!
                ensures
                    - returns (use_count() == 0)
            !*/

            shared_ptr<T> lock(
            ) const;
            /*!
                ensures
                    - if (expired()) then
                        - returns shared_ptr<T>()
                    - else
                        - returns shared_ptr<T>(*this)
            !*/

            void reset(
            );
            /*!
                ensures
                    - equivalent to weak_ptr().swap(*this)
            !*/

            void swap(
                weak_ptr<T>& b
            );
            /*!
                ensures
                    - swaps *this and item
            !*/

        };

        template<typename T, typename U>
        bool operator< (
            const weak_ptr<T>& a,
            const weak_ptr<U>& b
        );
        /*!
            ensures
                - Defines an operator< on shared_ptr types appropriate for use in the associative
                  containers.
        !*/

        template<typename T>
        void swap(
            weak_ptr<T>& a,
            weak_ptr<T> & b
        ) { a.swap(b); }
        /*!
            provides a global swap function
        !*/
    }

    #endif // DLIB_WEAK_PTr_ABSTRACT_