utilities.hppGo to the documentation of this file.00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 00004 Use, modification and distribution are subject to the Boost Software License, 00005 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 00006 http://www.boost.org/LICENSE_1_0.txt). 00007 00008 See http://opensource.adobe.com/gil for most recent version including documentation. 00009 */ 00010 00011 /*************************************************************************************************/ 00012 00013 #ifndef GIL_UTILITIES_H 00014 #define GIL_UTILITIES_H 00015 00016 #include "gil_config.hpp" 00017 #include <functional> 00018 #include <boost/config/no_tr1/cmath.hpp> 00019 #include <cstddef> 00020 #include <algorithm> 00021 #include <utility> 00022 #include <iterator> 00023 #include <boost/static_assert.hpp> 00024 #include <boost/type_traits.hpp> 00025 #include <boost/mpl/size.hpp> 00026 #include <boost/mpl/distance.hpp> 00027 #include <boost/mpl/begin.hpp> 00028 #include <boost/mpl/find.hpp> 00029 #include <boost/mpl/range_c.hpp> 00030 #include <boost/iterator/iterator_adaptor.hpp> 00031 #include <boost/iterator/iterator_facade.hpp> 00032 00042 00043 namespace boost { namespace gil { 00044 00057 00058 // CLASS point2 00065 00066 template <typename T> 00067 class point2 { 00068 public: 00069 typedef T value_type; 00070 template <std::size_t D> struct axis { typedef value_type coord_t; }; 00071 static const std::size_t num_dimensions=2; 00072 00073 point2() : x(0), y(0) {} 00074 point2(T newX, T newY) : x(newX), y(newY) {} 00075 point2(const point2& p) : x(p.x), y(p.y) {} 00076 ~point2() {} 00077 00078 point2& operator=(const point2& p) { x=p.x; y=p.y; return *this; } 00079 00080 point2 operator<<(std::ptrdiff_t shift) const { return point2(x<<shift,y<<shift); } 00081 point2 operator>>(std::ptrdiff_t shift) const { return point2(x>>shift,y>>shift); } 00082 point2& operator+=(const point2& p) { x+=p.x; y+=p.y; return *this; } 00083 point2& operator-=(const point2& p) { x-=p.x; y-=p.y; return *this; } 00084 point2& operator/=(double t) { x/=t; y/=t; return *this; } 00085 00086 const T& operator[](std::size_t i) const { return this->*mem_array[i]; } 00087 T& operator[](std::size_t i) { return this->*mem_array[i]; } 00088 00089 T x,y; 00090 private: 00091 // this static array of pointers to member variables makes operator[] safe and doesn't seem to exhibit any performance penalty 00092 static T point2<T>::* const mem_array[num_dimensions]; 00093 }; 00094 00095 template <typename T> 00096 T point2<T>::* const point2<T>::mem_array[point2<T>::num_dimensions] = { &point2<T>::x, &point2<T>::y }; 00097 00099 template <typename T> GIL_FORCEINLINE 00100 bool operator==(const point2<T>& p1, const point2<T>& p2) { return (p1.x==p2.x && p1.y==p2.y); } 00102 template <typename T> GIL_FORCEINLINE 00103 bool operator!=(const point2<T>& p1, const point2<T>& p2) { return p1.x!=p2.x || p1.y!=p2.y; } 00105 template <typename T> GIL_FORCEINLINE 00106 point2<T> operator+(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x+p2.x,p1.y+p2.y); } 00108 template <typename T> GIL_FORCEINLINE 00109 point2<T> operator-(const point2<T>& p) { return point2<T>(-p.x,-p.y); } 00111 template <typename T> GIL_FORCEINLINE 00112 point2<T> operator-(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x-p2.x,p1.y-p2.y); } 00114 template <typename T> GIL_FORCEINLINE 00115 point2<double> operator/(const point2<T>& p, double t) { return t==0 ? point2<double>(0,0):point2<double>(p.x/t,p.y/t); } 00117 template <typename T> GIL_FORCEINLINE 00118 point2<T> operator*(const point2<T>& p, std::ptrdiff_t t) { return point2<T>(p.x*t,p.y*t); } 00120 template <typename T> GIL_FORCEINLINE 00121 point2<T> operator*(std::ptrdiff_t t, const point2<T>& p) { return point2<T>(p.x*t,p.y*t); } 00122 00124 template <std::size_t K, typename T> GIL_FORCEINLINE 00125 const T& axis_value(const point2<T>& p) { return p[K]; } 00126 00128 template <std::size_t K, typename T> GIL_FORCEINLINE 00129 T& axis_value( point2<T>& p) { return p[K]; } 00130 00136 00137 inline std::ptrdiff_t iround(float x ) { return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f)); } 00138 inline std::ptrdiff_t iround(double x) { return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5)); } 00139 inline std::ptrdiff_t ifloor(float x ) { return static_cast<std::ptrdiff_t>(std::floor(x)); } 00140 inline std::ptrdiff_t ifloor(double x) { return static_cast<std::ptrdiff_t>(std::floor(x)); } 00141 inline std::ptrdiff_t iceil(float x ) { return static_cast<std::ptrdiff_t>(std::ceil(x)); } 00142 inline std::ptrdiff_t iceil(double x) { return static_cast<std::ptrdiff_t>(std::ceil(x)); } 00143 00153 00154 inline point2<std::ptrdiff_t> iround(const point2<float >& p) { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); } 00156 inline point2<std::ptrdiff_t> iround(const point2<double>& p) { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); } 00158 inline point2<std::ptrdiff_t> ifloor(const point2<float >& p) { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); } 00160 inline point2<std::ptrdiff_t> ifloor(const point2<double>& p) { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); } 00162 inline point2<std::ptrdiff_t> iceil (const point2<float >& p) { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); } 00164 inline point2<std::ptrdiff_t> iceil (const point2<double>& p) { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); } 00165 00171 00172 template <typename T> 00173 inline T align(T val, std::size_t alignment) { 00174 return val+(alignment - val%alignment)%alignment; 00175 } 00176 00180 template <typename ConstT, typename Value, typename Reference, typename ConstReference, 00181 typename ArgType, typename ResultType, bool IsMutable> 00182 struct deref_base : public std::unary_function<ArgType, ResultType> { 00183 typedef ConstT const_t; 00184 typedef Value value_type; 00185 typedef Reference reference; 00186 typedef ConstReference const_reference; 00187 BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable); 00188 }; 00189 00193 template <typename D1, typename D2> 00194 class deref_compose : public deref_base< 00195 deref_compose<typename D1::const_t, typename D2::const_t>, 00196 typename D1::value_type, typename D1::reference, typename D1::const_reference, 00197 typename D2::argument_type, typename D1::result_type, D1::is_mutable && D2::is_mutable> 00198 { 00199 public: 00200 D1 _fn1; 00201 D2 _fn2; 00202 00203 typedef typename D2::argument_type argument_type; 00204 typedef typename D1::result_type result_type; 00205 00206 deref_compose() {} 00207 deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {} 00208 deref_compose(const deref_compose& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {} 00209 template <typename _D1, typename _D2> deref_compose(const deref_compose<_D1,_D2>& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {} 00210 00211 result_type operator()(argument_type x) const { return _fn1(_fn2(x)); } 00212 result_type operator()(argument_type x) { return _fn1(_fn2(x)); } 00213 }; 00214 00215 // reinterpret_cast is implementation-defined. Static cast is not. 00216 template <typename OutPtr, typename In> GIL_FORCEINLINE 00217 OutPtr gil_reinterpret_cast( In* p) { return static_cast<OutPtr>(static_cast<void*>(p)); } 00218 00219 template <typename OutPtr, typename In> GIL_FORCEINLINE 00220 const OutPtr gil_reinterpret_cast_c(const In* p) { return static_cast<const OutPtr>(static_cast<const void*>(p)); } 00221 00222 namespace detail { 00223 00229 00230 template <class InputIter, class Size, class OutputIter> 00231 std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count, 00232 OutputIter result, 00233 std::input_iterator_tag) { 00234 for ( ; count > 0; --count) { 00235 *result = *first; 00236 ++first; 00237 ++result; 00238 } 00239 return std::pair<InputIter, OutputIter>(first, result); 00240 } 00241 00242 template <class RAIter, class Size, class OutputIter> 00243 inline std::pair<RAIter, OutputIter> 00244 _copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag) { 00245 RAIter last = first + count; 00246 return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result)); 00247 } 00248 00249 template <class InputIter, class Size, class OutputIter> 00250 inline std::pair<InputIter, OutputIter> 00251 _copy_n(InputIter first, Size count, OutputIter result) { 00252 return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category()); 00253 } 00254 00255 template <class InputIter, class Size, class OutputIter> 00256 inline std::pair<InputIter, OutputIter> 00257 copy_n(InputIter first, Size count, OutputIter result) { 00258 return detail::_copy_n(first, count, result); 00259 } 00260 00262 template <typename T> 00263 struct identity : public std::unary_function<T,T> { 00264 const T& operator()(const T& val) const { return val; } 00265 }; 00266 00267 /*************************************************************************************************/ 00268 00270 template <typename T1, typename T2> 00271 struct plus_asymmetric : public std::binary_function<T1,T2,T1> { 00272 T1 operator()(T1 f1, T2 f2) const { 00273 return f1+f2; 00274 } 00275 }; 00276 00277 /*************************************************************************************************/ 00278 00280 template <typename T> 00281 struct inc : public std::unary_function<T,T> { 00282 T operator()(T x) const { return ++x; } 00283 }; 00284 00285 /*************************************************************************************************/ 00286 00288 template <typename T> 00289 struct dec : public std::unary_function<T,T> { 00290 T operator()(T x) const { return --x; } 00291 }; 00292 00294 // a given MPL RandomAccessSequence (or size if the type is not present) 00295 template <typename Types, typename T> 00296 struct type_to_index 00297 : public mpl::distance<typename mpl::begin<Types>::type, 00298 typename mpl::find<Types,T>::type>::type {}; 00299 } // namespace detail 00300 00301 00302 00305 template <typename ColorSpace, typename ChannelMapping = mpl::range_c<int,0,mpl::size<ColorSpace>::value> > 00306 struct layout { 00307 typedef ColorSpace color_space_t; 00308 typedef ChannelMapping channel_mapping_t; 00309 }; 00310 00312 template <typename Value, typename T1, typename T2> // where value_type<T1> == value_type<T2> == Value 00313 void swap_proxy(T1& left, T2& right) { 00314 Value tmp = left; 00315 left = right; 00316 right = tmp; 00317 } 00318 00320 inline bool little_endian() { 00321 short tester = 0x0001; 00322 return *(char*)&tester!=0; 00323 } 00325 inline bool big_endian() { 00326 return !little_endian(); 00327 } 00328 00329 } } // namespace boost::gil 00330 00331 #endif Generated on Sat May 2 13:50:15 2009 for Generic Image Library by 1.5.6 |