/*
 [auto_generated]
 libs/numeric/odeint/test/trivial_state.cpp

 [begin_description]
 This file defines a vector_space 1d class with the appropriate operators.
 [end_description]

 Copyright 2009-2012 Karsten Ahnert
 Copyright 2009-2012 Mario Mulansky

 Distributed under the Boost Software License, Version 1.0.
 (See accompanying file LICENSE_1_0.txt or
 copy at http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef VECTOR_SPACE_1D_HPP_INCLUDED
#define VECTOR_SPACE_1D_HPP_INCLUDED

#include <boost/config.hpp>
#include <boost/operators.hpp>

template< class T >
struct vector_space_1d :
    boost::additive1< vector_space_1d< T > ,
    boost::additive2< vector_space_1d< T > , T ,
    boost::multiplicative1< vector_space_1d< T > ,
    boost::multiplicative2< vector_space_1d< T > , T
    > > > >
{
    typedef T value_type;

    value_type m_x;

    vector_space_1d( void ) : m_x( 0.0 ) {}

    vector_space_1d& operator+=( const vector_space_1d& p )
    {
        m_x += p.m_x;
        return *this;
    }

    vector_space_1d& operator-=( const vector_space_1d& p )
    {
        m_x -= p.m_x;
        return *this;
    }

    vector_space_1d& operator*=( const vector_space_1d& p )
    {
        m_x *= p.m_x;
        return *this;
    }

    vector_space_1d& operator/=( const vector_space_1d& p )
    {
        m_x /= p.m_x;
        return *this;
    }

    vector_space_1d& operator+=( const value_type& val )
    {
        m_x += val;
        return *this;
    }

    vector_space_1d& operator-=( const value_type& val )
    {
        m_x -= val;
        return *this;
    }

    vector_space_1d& operator*=( const value_type &val )
    {
        m_x *= val;
        return *this;
    }

    vector_space_1d& operator/=( const value_type &val )
    {
        m_x /= val;
        return *this;
    }
};


template< class T >
vector_space_1d< T > abs( const vector_space_1d< T > &v)
{
    vector_space_1d< T > tmp;
    tmp.m_x = std::abs( v.m_x );
    return tmp;
}


template< class T >
T max BOOST_PREVENT_MACRO_SUBSTITUTION ( const vector_space_1d< T > &v )
{
    return v.m_x;
}

namespace boost {
    namespace numeric {
        namespace odeint {

            template< class T >
            struct vector_space_reduce< vector_space_1d< T > >
            {
                template< class Op >
                T operator()( const vector_space_1d< T > &v , Op op , T value )
                {
                    return v.m_x;
                }
            };

} // odeint
} // numeric
} // boost

#endif // VECTOR_SPACE_1D_HPP_INCLUDED
