OpenWalnut  1.4.0
WInterval.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WINTERVAL_H
00026 #define WINTERVAL_H
00027 
00028 #include <utility>
00029 #include <algorithm>
00030 
00031 #include <boost/shared_ptr.hpp>
00032 
00033 #include "../WTypeTraits.h"
00034 
00035 /**
00036  * Basic class for encapsulating a std::pair to be interpreted as interval. This class intentionally does not include a parameter telling whether
00037  * the interval is open or not (mathematically: [],][,[[,]])
00038  *
00039  * \tparam T the type used for this interval
00040  */
00041 template< typename T >
00042 class WInterval
00043 {
00044 public:
00045     /**
00046      * Convenience typedef for a boost::shared_ptr< WInterval >.
00047      */
00048     typedef boost::shared_ptr< WInterval< T > > SPtr;
00049 
00050     /**
00051      * Convenience typedef for a boost::shared_ptr< const WInterval >.
00052      */
00053     typedef boost::shared_ptr< const WInterval< T > > ConstSPtr;
00054 
00055     /**
00056      * Type used to store the information
00057      */
00058     typedef std::pair< T, T > StoreType;
00059 
00060     /**
00061      * My own type.
00062      */
00063     typedef WInterval< T > Type;
00064 
00065     /**
00066      * Copy constructor to create a WInterval using a std::pair
00067      *
00068      * \param c the pair to use
00069      */
00070     explicit WInterval( const StoreType& c );
00071 
00072     /**
00073      * Copy constructor.
00074      *
00075      * \param c the interval to copy
00076      */
00077     WInterval( const Type& c );  // NOLINT
00078 
00079     /**
00080      * Create a new interval instance using the given values.
00081      *
00082      * \param l the lower border
00083      * \param u the upper border
00084      */
00085     WInterval( const T& l, const T& u );
00086 
00087     /**
00088      * Destructor.
00089      */
00090     virtual ~WInterval();
00091 
00092     /**
00093      * Convert the WInterval instance to a std::pair again.
00094      *
00095      * \return the pair
00096      */
00097     operator const StoreType& () const;
00098 
00099     /**
00100      * Get the lower value of the interval.
00101      *
00102      * \return the lower value
00103      */
00104     const T& getLower() const;
00105 
00106     /**
00107      * Return the upper value of the interval
00108      *
00109      * \return the upper value
00110      */
00111     const T& getUpper() const;
00112 
00113     /**
00114      * The length of the interval. This is upper - lower.
00115      *
00116      * \return length
00117      */
00118     T getLength() const;
00119 
00120     /**
00121      * Compare this interval with another one
00122      *
00123      * \param interval the other one
00124      *
00125      * \return true if lower and upper bounds are equal
00126      */
00127     bool operator==( Type interval ) const;
00128 
00129     /**
00130      * Compare this interval with another one
00131      *
00132      * \param interval the other one
00133      *
00134      * \return true if lower and upper bounds are equal
00135      */
00136     bool operator!=( Type interval ) const;
00137 
00138 protected:
00139 private:
00140     /**
00141      * The interval itself.
00142      */
00143     StoreType m_interval;
00144 };
00145 
00146 /**
00147  * Abbreviation for an double interval.
00148  */
00149 typedef WInterval< double > WIntervalDouble;
00150 
00151 /**
00152  * Abbreviation for an integer interval
00153  */
00154 typedef WInterval< int > WIntervalInt;
00155 
00156 /**
00157  * Create an interval instance similar to make_pair.
00158  *
00159  * \tparam T1 the lower bound type
00160  * \tparam T2 the upper bound type
00161  * \param l lower bound
00162  * \param u upper bound
00163  *
00164  * \return the interval
00165  */
00166 template < typename T1, typename T2 >
00167 WInterval< typename WTypeTraits::TypePromotion< T1, T2 >::Result > make_interval( T1 l, T2 u )
00168 {
00169     return WInterval< typename WTypeTraits::TypePromotion< T1, T2 >::Result >( l, u );
00170 }
00171 
00172 /**
00173  * Check whether a value is in the interval or not. This function interprets the interval as closed at both bounds.
00174  *
00175  * \tparam IntervalType type if the interval
00176  * \tparam T type of the value to use for checking
00177  * \param interval the interval to check against
00178  * \param value the value
00179  *
00180  * \return true if inside
00181  */
00182 template < typename IntervalType, typename T >
00183 bool isInClosed( const IntervalType& interval, const T& value )
00184 {
00185     return ( ( interval.getLower() <= value ) && ( interval.getUpper() >= value ) );
00186 }
00187 
00188 /**
00189  * Check whether a value is in the interval or not. This function interprets the interval as open at both bounds.
00190  *
00191  * \tparam IntervalType type if the interval
00192  * \tparam T type of the value to use for checking
00193  * \param interval the interval to check against
00194  * \param value the value
00195  *
00196  * \return true if inside
00197  */
00198 template < typename IntervalType, typename T >
00199 bool isInOpen( const IntervalType& interval, const T& value )
00200 {
00201     return ( ( interval.getLower() < value ) && ( interval.getUpper() > value ) );
00202 }
00203 
00204 /**
00205  * Check whether a value is in the interval or not. This function interprets the interval as open at the lower bound and closed at the upper one.
00206  *
00207  * \tparam IntervalType type if the interval
00208  * \tparam T type of the value to use for checking
00209  * \param interval the interval to check against
00210  * \param value the value
00211  *
00212  * \return true if inside
00213  */
00214 template < typename IntervalType, typename T >
00215 bool isInOpenClosed( const IntervalType& interval, const T& value )
00216 {
00217     return ( ( interval.getLower() < value ) && ( interval.getUpper() >= value ) );
00218 }
00219 
00220 /**
00221  * Check whether a value is in the interval or not. This function interprets the interval as closed at the lower bound and open at the upper one.
00222  *
00223  * \tparam IntervalType type if the interval
00224  * \tparam T type of the value to use for checking
00225  * \param interval the interval to check against
00226  * \param value the value
00227  *
00228  * \return true if inside
00229  */
00230 template < typename IntervalType, typename T >
00231 bool isInClosedOpen( const IntervalType& interval, const T& value )
00232 {
00233     return ( ( interval.getLower() <= value ) && ( interval.getUpper() > value ) );
00234 }
00235 
00236 template < typename T >
00237 WInterval< T >::WInterval( const StoreType& c )
00238 {
00239     // ensure order
00240     m_interval.first = std::min( c.first, c.second );
00241     m_interval.second = std::min( c.first, c.second );
00242 }
00243 
00244 template < typename T >
00245 WInterval< T >::WInterval( const Type& c ):
00246     m_interval( c.m_interval )
00247 {
00248     // nothing else to do
00249 }
00250 
00251 template < typename T >
00252 WInterval< T >::WInterval( const T& l, const T& u ):
00253     m_interval( std::min( l, u ), std::max( l, u ) )
00254 {
00255     // nothing else to do
00256 }
00257 
00258 template < typename T >
00259 WInterval< T >::~WInterval()
00260 {
00261     // nothing else to do
00262 }
00263 
00264 template < typename T >
00265 WInterval< T >::operator const StoreType& () const
00266 {
00267     return m_interval;
00268 }
00269 
00270 template < typename T >
00271 const T& WInterval< T >::getLower() const
00272 {
00273     return m_interval.first;
00274 }
00275 
00276 template < typename T >
00277 const T& WInterval< T >::getUpper() const
00278 {
00279     return m_interval.second;
00280 }
00281 
00282 template < typename T >
00283 T WInterval< T >::getLength() const
00284 {
00285     return getUpper() - getLower();
00286 }
00287 
00288 template < typename T >
00289 bool WInterval< T >::operator==( Type interval ) const
00290 {
00291     return ( ( interval.getLower() == getLower() ) && ( interval.getUpper() == getUpper() ) );
00292 }
00293 
00294 template < typename T >
00295 bool WInterval< T >::operator!=( Type interval ) const
00296 {
00297     return !operator==( interval );
00298 }
00299 
00300 #endif  // WINTERVAL_H
00301