dlib C++ Library - vector_abstract.h

    // Copyright (C) 2003  Davis E. King (davisking@users.sourceforge.net)
    // License: Boost Software License   See LICENSE.txt for the full license.
    #undef DLIB_VECTOR_ABSTRACT_
    #ifdef DLIB_VECTOR_ABSTRACT_

    #include "../serialize.h"
    #include <functional>
    #include <iostream>
    #include "../matrix/matrix_abstract.h"

    namespace dlib
    {
        class point;

        template <
            typename T
            >
        class vector
        {
            /*!
                REQUIREMENTS ON T
                    T should be some object that provides an interface that is
                    compatible with double, float and the like.

                INITIAL VALUE
                    x() == 0
                    y() == 0
                    z() == 0

                WHAT THIS OBJECT REPRESENTS
                    This object represents a three dimensional vector.

                THREAD SAFETY
                    Note that the vector object is not allowed to be reference counted.
                    This is to ensure a minimum amount of thread safety.
            !*/

        public:

            typedef T type;

            vector (
            );
            /*!
                ensures
                   - #*this has been properly initialized
            !*/

            vector (
                const T _x,
                const T _y,
                const T _z
            );
            /*!
                ensures
                    - #*this properly initialized
                    - #x() == _x
                    - #y() == _y
                    - #z() == _z
            !*/

            vector (
                const point& p
            );
            /*!
                ensures
                    - #*this properly initialized
                    - #x() == p.x()
                    - #y() == p.y()
                    - #z() == 0
            !*/

            vector (
                const vector& v
            );
            /*!
                ensures
                    - #*this properly initialized
                    - #x() == v.x()
                    - #y() == v.y()
                    - #z() == v.z()
            !*/

            template <typename EXP>
            vector (
                const matrix_exp<EXP>& m
            );
            /*!
                requires
                    - m.size() == 3
                    - m.nr() == 1 || m.nc() == 1 (i.e. m must be a row or column matrix)
                ensures
                    - #x() == m(0)
                    - #y() == m(1)
                    - #z() == m(2)
            !*/

            template <long NR, long NC, typename MM>
            operator matrix<T,NR, NC, MM> (
            ) const;
            /*!
                ensures
                    - provides automatic conversions from a vector object to a column
                      matrix
                    - returns a matrix object m such that:
                        - m.nr() == 3
                        - m.nc() == 1
                        - m(0) == x()
                        - m(1) == y()
                        - m(2) == z()
            !*/

            ~vector (
            );
            /*!
                ensures
                    - all resources associated with *this have been released
            !*/

            T length(
            ) const;
            /*!
                ensures
                    - returns the length of the vector
            !*/

            T& x (
            );
            /*!
                ensures
                    - returns a reference to the x component of the vector
            !*/

            T& y (
            );
            /*!
                ensures
                    - returns a reference to the y component of the vector
            !*/

            T& z (
            );
            /*!
                ensures
                    - returns a reference to the z component of the vector
            !*/

            const T& x (
            ) const;
            /*!
                ensures
                    - returns a const reference to the x component of the vector
            !*/

            const T& y (
            ) const;
            /*!
                ensures
                    - returns a const reference to the y component of the vector
            !*/

            const T& z (
            ) const;
            /*!
                ensures
                    - returns a const reference to the z component of the vector
            !*/

            T dot (
                const vector& rhs
            ) const;
            /*!
                ensures
                    - returns the result of the dot product between *this and rhs
            !*/

            vector cross (
                const vector& rhs
            ) const;
            /*!
                ensures
                    - returns the result of the cross product between *this and rhs
            !*/

            vector normalize (
            ) const;
            /*!
                ensures
                    - returns a vector with length() == 1 and in the same direction as *this
            !*/

            vector operator+ (
                const vector& rhs
            ) const;
            /*!
                ensures
                    - returns the result of adding *this to rhs
            !*/

            vector operator- (
                const vector& rhs
            ) const;
            /*!
                ensures
                    - returns the result of subtracting rhs from *this
            !*/

            vector operator/ (
                const T rhs
            ) const;
            /*!
                ensures
                    - returns the result of dividing *this by rhs
            !*/

            vector& operator= (
                const vector& rhs
            );
            /*!
                ensures
                    - #x() == rhs.x()
                    - #y() == rhs.y()
                    - #z() == rhs.z()
                    - returns #*this
            !*/

            vector& operator += (
                const vector& rhs
            );
            /*!
                ensures
                    - #*this == *this + rhs
                    - returns #*this
            !*/

            vector& operator -= (
                const vector& rhs
            );
            /*!
                ensures
                    - #*this == *this - rhs
                    - returns #*this
            !*/

            vector& operator *= (
                const T rhs
            );
            /*!
                ensures
                    - #*this == *this * rhs
                    - returns #*this
            !*/

            vector& operator /= (
                const T rhs
            );
            /*!
                ensures
                    - #*this == *this / rhs
                    - returns #*this
            !*/

            bool operator== (
                const vector& rhs
            ) const;
            /*!
                ensures
                    - if (x() == rhs.x() && y() == rhs.y() && z() == rhs.z()) then
                        - returns true
                    - else
                        - returns false
            !*/

            bool operator!= (
                const vector& rhs
            ) const;
            /*!
                ensures
                    - returns !((*this) == rhs)
            !*/

            void swap (
                vector& item
            );
            /*!
                ensures
                    - swaps *this and item
            !*/

        };

        template<typename T, typename U>
        vector<T>  operator* (
            const vector<T> & lhs,
            const U rhs
        );
        /*!
            ensures
                - returns the result of multiplying the scalar rhs by lhs
        !*/

        template<typename T, typename U>
        vector<T>  operator* (
            const U lhs,
            const vector<T> & rhs
        );
        /*!
            ensures
                - returns the result of multiplying the scalar lhs by rhs
        !*/

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

        template<typename T>
        void serialize (
            const vector<T> & item,
            std::ostream& out
        );
        /*!
            provides serialization support
        !*/

        template<typename T>
        void deserialize (
            vector<T> & item,
            std::istream& in
        );
        /*!
            provides deserialization support
        !*/

        template<typename T>
        std::ostream& operator<< (
            std::ostream& out,
            const vector<T>& item
        );
        /*!
            ensures
                - writes item to out in the form "(x, y, z)"
        !*/

        template<typename T>
        std::istream& operator>>(
            std::istream& in,
            vector<T>& item
        );
        /*!
            ensures
                - reads a vector from the input stream in and stores it in #item.
                  The data in the input stream should be of the form (x, y, z)
        !*/

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

        class point
        {
            /*!
                INITIAL VALUE
                    The initial value of this object is defined by its constructor.

                WHAT THIS OBJECT REPRESENTS
                    This object represents a point inside a Cartesian coordinate system.
            !*/

        public:

            point (
            );
            /*!
                ensures
                    - #x() == 0
                    - #y() == 0
            !*/

            point (
                long x_
                long y_
            );
            /*!
                ensures
                    - #x() == x_
                    - #y() == y_
            !*/

            point (
                const point& p
            );
            /*!
                ensures
                    - #x() == p.x()
                    - #y() == p.y()
            !*/

            template <typename T>
            point (
                const vector<T>& v
            );
            /*!
                ensures
                    - #x() == floor(v.x()+0.5)
                    - #y() == floor(v.y()+0.5)
            !*/

            long x (
            ) const;
            /*!
                ensures
                    - returns the x coordinate of this point
            !*/

            long y (
            ) const;
            /*!
                ensures
                    - returns the y coordinate of this point
            !*/

            long& x (
            );
            /*!
                ensures
                    - returns a non-const reference to the x coordinate of
                      this point
            !*/

            long& y (
            );
            /*!
                ensures
                    - returns a non-const reference to the y coordinate of
                      this point
            !*/

            const point operator+ (
                const point& rhs
            ) const;
            /*!
                ensures
                    - returns point(x()+rhs.x(), y()+rhs.y())
            !*/

            const point operator- (
                const point& rhs
            ) const;
            /*!
                ensures
                    - returns point(x()-rhs.x(), y()-rhs.y())
            !*/

            point& operator= (
                const point& p
            );
            /*!
                ensures
                    - #x() == p.x()
                    - #y() == p.y()
                    - returns #*this
            !*/

            point& operator+= (
                const point& rhs
            );
            /*!
                ensures
                    - #*this = *this + rhs
                    - returns #*this
            !*/

            point& operator-= (
                const point& rhs
            );
            /*!
                ensures
                    - #*this = *this - rhs
                    - returns #*this
            !*/

            bool operator== (
                const point& p
            ) const;
            /*!
                ensures
                    - if (x() == p.x() && y() == p.y()) then
                        - returns true
                    - else
                        - returns false
            !*/

            bool operator!= (
                const point& p
            ) const;
            /*!
                ensures
                    - returns !(*this == p)
            !*/
        };

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

        void serialize (
            const point& item,
            std::ostream& out
        );
        /*!
            provides serialization support
        !*/

        void deserialize (
            point& item,
            std::istream& in
        );
        /*!
            provides deserialization support
        !*/

        std::ostream& operator<< (
            std::ostream& out,
            const point& item
        );
        /*!
            ensures
                - writes item to out in the form "(x, y)"
        !*/

        std::istream& operator>>(
            std::istream& in,
            point& item
        );
        /*!
            ensures
                - reads a point from the input stream in and stores it in #item.
                  The data in the input stream should be of the form (x, y)
        !*/

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

    }

    namespace std
    {
        /*!
            Define std::less<vector<T> > so that you can use vectors in the associative containers.
        !*/
        template<typename T>
        struct less<dlib::vector<T> > : public binary_function<dlib::vector<T> ,dlib::vector<T> ,bool>
        {
            inline bool operator() (const dlib::vector<T> & a, const dlib::vector<T> & b) const
            {
                if      (a.x() < b.x()) return true;
                else if (a.x() > b.x()) return false;
                else if (a.y() < b.y()) return true;
                else if (a.y() > b.y()) return false;
                else if (a.z() < b.z()) return true;
                else if (a.z() > b.z()) return false;
                else                    return false;
            }
        };

        /*!
            Define std::less<point> so that you can use points in the associative containers.
        !*/
        template<>
        struct less<dlib::point> : public binary_function<dlib::point,dlib::point,bool>
        {
            inline bool operator() (const dlib::point& a, const dlib::point& b) const
            {
                if      (a.x() < b.x()) return true;
                else if (a.x() > b.x()) return false;
                else if (a.y() < b.y()) return true;
                else if (a.y() > b.y()) return false;
                else                    return false;
            }
        };
    }

    #endif // DLIB_VECTOR_ABSTRACT_