    // Copyright (C) 2003  Davis E. King (davis@dlib.net)
    // License: Boost Software License   See LICENSE.txt for the full license.
    #ifndef DLIB_SEQUENCE_KERNEl_C_
    #define DLIB_SEQUENCE_KERNEl_C_

    #include "sequence_kernel_abstract.h"
    #include "../algs.h"
    #include "../assert.h"

    namespace dlib
    {

        template <
            typename seq_base
            >
        class sequence_kernel_c : public seq_base
        {
            typedef typename seq_base::type T;
        public:

            void add (
                unsigned long pos,
                T& item
            );

            void remove (
                unsigned long pos,
                T& item
            );

            const T& operator[] (
                unsigned long pos
            ) const;

            T& operator[] (
                unsigned long pos
            );

            void cat (
                sequence_kernel_c& item
            );

            const T& element (
            ) const;

            T& element (
            );

            void remove_any (
                T& item
            );

        };

        template <
            typename seq_base
            >
        inline void swap (
            sequence_kernel_c<seq_base>& a,
            sequence_kernel_c<seq_base>& b
        ) { a.swap(b); }

    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------
    // member function definitions
    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------

        template <
            typename seq_base
            >
        void sequence_kernel_c<seq_base>::
        add(
            unsigned long pos,
            T& item
        )
        {

            // make sure requires clause is not broken
            DLIB_CASSERT(( pos <= this->size() ),
                    "\tvoid sequence::add"
                    << "\n\tpos must be >= 0 and <= size()"
                    << "\n\tpos: " << pos
                    << "\n\tsize(): " << this->size()
                    << "\n\tthis: " << this
            );

            // call the real function
            seq_base::add(pos,item);
        }

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

        template <
            typename seq_base
            >
        void sequence_kernel_c<seq_base>::
        cat (
            sequence_kernel_c<seq_base>& item
        )
        {
            // make sure requires clause is not broken
            DLIB_CASSERT(&item != this,
                    "\tvoid sequence::cat"
                    << "\n\tyou can't concatenate a sequence onto itself"
                    << "\n\t&item: " << &item
                    << "\n\tthis:  " << this
            );

            // call the real function
            seq_base::cat(item);

        }

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

        template <
            typename seq_base
            >
        void sequence_kernel_c<seq_base>::
        remove (
            unsigned long pos,
            T& item
        )
        {
            // make sure requires clause is not broken
            DLIB_CASSERT(( pos < this->size() ),
                    "\tvoid sequence::remove"
                    << "\n\tpos must be >= 0 and < size()"
                    << "\n\tpos: " << pos
                    << "\n\tsize(): " << this->size()
                    << "\n\tthis: " << this
            );

            // call the real function
            seq_base::remove(pos,item);

        }

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

        template <
            typename seq_base
            >
        const typename seq_base::type& sequence_kernel_c<seq_base>::
        operator[] (
            unsigned long pos
        ) const
        {

            // make sure requires clause is not broken
            DLIB_CASSERT(( pos < this->size() ),
                    "\tconst T& sequence::operator[]"
                    << "\n\tpos must be >= 0 and < size()"
                    << "\n\tpos: " << pos
                    << "\n\tsize(): " << this->size()
                    << "\n\tthis: " << this
            );

            // call the real function
            return seq_base::operator[](pos);
        }

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

        template <
            typename seq_base
            >
        typename seq_base::type& sequence_kernel_c<seq_base>::
        operator[] (
            unsigned long pos
        )
        {

            // make sure requires clause is not broken
            DLIB_CASSERT(( pos < this->size() ),
                    "\tT& sequence::operator[]"
                    << "\n\tpos must be >= 0 and < size()"
                    << "\n\tpos: " << pos
                    << "\n\tsize(): " << this->size()
                    << "\n\tthis: " << this
            );

            // call the real function
            return seq_base::operator[](pos);
        }

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

        template <
            typename seq_base
            >
        const typename seq_base::type& sequence_kernel_c<seq_base>::
        element (
        ) const
        {
            DLIB_CASSERT(this->current_element_valid() == true,
                    "\tconst T& sequence::element() const"
                    << "\n\tyou can't access the current element if it doesn't exist"
                    << "\n\tthis: " << this
            );

            return seq_base::element();
        }

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

        template <
            typename seq_base
            >
        typename seq_base::type& sequence_kernel_c<seq_base>::
        element (
        )
        {
            DLIB_CASSERT(this->current_element_valid() == true,
                    "\tT& sequence::element()"
                    << "\n\tyou can't access the current element if it doesn't exist"
                    << "\n\tthis: " << this
            );

            return seq_base::element();
        }

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

        template <
            typename seq_base
            >
        void sequence_kernel_c<seq_base>::
        remove_any (
            T& item
        )
        {
            // make sure requires clause is not broken
            DLIB_CASSERT( (this->size() > 0),
                     "\tvoid sequence::remove_any"
                     << "\n\tsize() must be greater than zero if something is going to be removed"
                     << "\n\tsize(): " << this->size()
                     << "\n\tthis:   " << this
            );

            // call the real function
            seq_base::remove_any(item);
        }

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

    }

    #endif // DLIB_SEQUENCE_KERNEl_C_