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

    #include "threads_kernel_abstract.h"

    namespace dlib
    {

    // ----------------------------------------------------------------------------------------

        template <
            typename T
            >
        class thread_specific_data
        {
            /*!
                WHAT THIS OBJECT REPRESENTS
                    This object represents a container of thread specific data.  When
                    a thread calls the data() member function it gets a reference to a T object
                    that is specific to its own thread.  Each subsequent call to data() from that
                    thread returns the same instance.  Also note that when a thread ends
                    the instance of its data() object gets destroyed and freed (if the thread
                    was created by the dlib library).  So any pointers or references to the object
                    will be invalid after the thread has ended.
            !*/
        public:

            thread_specific_data (
            );
            /*!
                ensures
                    - #*this is properly initialized
            !*/

            ~thread_specific_data (
            );
            /*!
                ensures
                    - all resources allocated by *this have been freed.  This includes
                      all the thread specific data returned by the data() functions.
            !*/

            T& data (
            );
            /*!
                ensures
                    - if (the calling thread has NOT called this->data() before) then
                        - constructs an instance of T that is specific to the calling
                          thread.
                    - returns a reference to the T instance that was constructed for
                      the calling thread.
                throws
                    - std::bad_alloc or any exception thrown by T's constructor
                      If an exception is thrown then the call to data() will have
                      no effect on *this.
            !*/

            const T& data (
            ) const;
            /*!
                ensures
                    - if (the calling thread has NOT called this->data() before) then
                        - constructs an instance of T that is specific to the calling
                          thread.
                    - returns a const reference to the T instance that was constructed for
                      the calling thread.
                throws
                    - std::bad_alloc or any exception thrown by T's constructor
                      If an exception is thrown then the call to data() will have
                      no effect on *this.
            !*/

        private:
            // restricted functions
            thread_specific_data(thread_specific_data&);        // copy constructor
            thread_specific_data& operator=(thread_specific_data&);    // assignment operator
        };

    // ----------------------------------------------------------------------------------------

    }

    #endif // DLIB_THREAD_SPECIFIC_DATA_EXTENSIOn_ABSTRACT_