00001
00002
00003
00004
00005
00006
00007
00008
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 <cmath>
00019 #include <cstddef>
00020 #include <boost/static_assert.hpp>
00021 #include <boost/type_traits.hpp>
00022 #include <boost/mpl/size.hpp>
00023 #include <boost/mpl/distance.hpp>
00024 #include <boost/mpl/begin.hpp>
00025 #include <boost/mpl/find.hpp>
00026 #include <boost/mpl/range_c.hpp>
00027 #include <boost/iterator/iterator_adaptor.hpp>
00028 #include <boost/iterator/iterator_facade.hpp>
00029
00039
00040 namespace boost { namespace gil {
00041
00054
00055
00062
00063 template <typename T>
00064 class point2 {
00065 public:
00066 typedef T value_type;
00067 template <std::size_t D> struct axis { typedef value_type coord_t; };
00068 static const std::size_t num_dimensions=2;
00069
00070 point2() : x(0), y(0) {}
00071 point2(T newX, T newY) : x(newX), y(newY) {}
00072 point2(const point2& p) : x(p.x), y(p.y) {}
00073 ~point2() {}
00074
00075 point2& operator=(const point2& p) { x=p.x; y=p.y; return *this; }
00076
00077 point2 operator<<(int shift) const { return point2(x<<shift,y<<shift); }
00078 point2 operator>>(int shift) const { return point2(x>>shift,y>>shift); }
00079 point2& operator+=(const point2& p) { x+=p.x; y+=p.y; return *this; }
00080 point2& operator-=(const point2& p) { x-=p.x; y-=p.y; return *this; }
00081 point2& operator/=(double t) { x/=t; y/=t; return *this; }
00082
00083 const T& operator[](std::size_t i) const { return this->*mem_array[i]; }
00084 T& operator[](std::size_t i) { return this->*mem_array[i]; }
00085
00086 T x,y;
00087 private:
00088
00089 static T point2<T>::* const mem_array[num_dimensions];
00090 };
00091
00092 template <typename T>
00093 T point2<T>::* const point2<T>::mem_array[point2<T>::num_dimensions] = { &point2<T>::x, &point2<T>::y };
00094
00096 template <typename T> GIL_FORCEINLINE
00097 bool operator==(const point2<T>& p1, const point2<T>& p2) { return (p1.x==p2.x && p1.y==p2.y); }
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 point2<T> operator+(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x+p2.x,p1.y+p2.y); }
00105 template <typename T> GIL_FORCEINLINE
00106 point2<T> operator-(const point2<T>& p) { return point2<T>(-p.x,-p.y); }
00108 template <typename T> GIL_FORCEINLINE
00109 point2<T> operator-(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x-p2.x,p1.y-p2.y); }
00111 template <typename T> GIL_FORCEINLINE
00112 point2<double> operator/(const point2<T>& p, double t) { return t==0 ? point2<double>(0,0):point2<double>(p.x/t,p.y/t); }
00114 template <typename T> GIL_FORCEINLINE
00115 point2<T> operator*(const point2<T>& p, int t) { return point2<T>(p.x*t,p.y*t); }
00117 template <typename T> GIL_FORCEINLINE
00118 point2<T> operator*(int t, const point2<T>& p) { return point2<T>(p.x*t,p.y*t); }
00119
00121 template <std::size_t K, typename T> GIL_FORCEINLINE
00122 const T& axis_value(const point2<T>& p) { return p[K]; }
00123
00125 template <std::size_t K, typename T> GIL_FORCEINLINE
00126 T& axis_value( point2<T>& p) { return p[K]; }
00127
00133
00134 inline int iround(float x ) { return static_cast<int>(x + (x < 0.0f ? -0.5f : 0.5f)); }
00135 inline int iround(double x) { return static_cast<int>(x + (x < 0.0 ? -0.5 : 0.5)); }
00136 inline int ifloor(float x ) { return static_cast<int>(std::floor(x)); }
00137 inline int ifloor(double x) { return static_cast<int>(std::floor(x)); }
00138 inline int iceil(float x ) { return static_cast<int>(std::ceil(x)); }
00139 inline int iceil(double x) { return static_cast<int>(std::ceil(x)); }
00140
00150
00151 inline point2<int> iround(const point2<float >& p) { return point2<int>(iround(p.x),iround(p.y)); }
00153 inline point2<int> iround(const point2<double>& p) { return point2<int>(iround(p.x),iround(p.y)); }
00155 inline point2<int> ifloor(const point2<float >& p) { return point2<int>(ifloor(p.x),ifloor(p.y)); }
00157 inline point2<int> ifloor(const point2<double>& p) { return point2<int>(ifloor(p.x),ifloor(p.y)); }
00159 inline point2<int> iceil (const point2<float >& p) { return point2<int>(iceil(p.x), iceil(p.y)); }
00161 inline point2<int> iceil (const point2<double>& p) { return point2<int>(iceil(p.x), iceil(p.y)); }
00162
00168
00169 template <typename T>
00170 inline T align(T val, std::size_t alignment) {
00171 return val+(alignment - val%alignment)%alignment;
00172 }
00173
00177 template <typename ConstT, typename Value, typename Reference, typename ConstReference,
00178 typename ArgType, typename ResultType, bool IsMutable>
00179 struct deref_base : public std::unary_function<ArgType, ResultType> {
00180 typedef ConstT const_t;
00181 typedef Value value_type;
00182 typedef Reference reference;
00183 typedef ConstReference const_reference;
00184 BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable);
00185 };
00186
00190 template <typename D1, typename D2>
00191 class deref_compose : public deref_base<
00192 deref_compose<typename D1::const_t, typename D2::const_t>,
00193 typename D1::value_type, typename D1::reference, typename D1::const_reference,
00194 typename D2::argument_type, typename D1::result_type, D1::is_mutable && D2::is_mutable>
00195 {
00196 public:
00197 D1 _fn1;
00198 D2 _fn2;
00199
00200 typedef typename D2::argument_type argument_type;
00201 typedef typename D1::result_type result_type;
00202
00203 deref_compose() {}
00204 deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {}
00205 deref_compose(const deref_compose& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
00206 template <typename _D1, typename _D2> deref_compose(const deref_compose<_D1,_D2>& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
00207
00208 result_type operator()(argument_type x) const { return _fn1(_fn2(x)); }
00209 result_type operator()(argument_type x) { return _fn1(_fn2(x)); }
00210 };
00211
00212
00213 template <typename OutPtr, typename In> GIL_FORCEINLINE
00214 OutPtr gil_reinterpret_cast( In* p) { return static_cast<OutPtr>(static_cast<void*>(p)); }
00215
00216 template <typename OutPtr, typename In> GIL_FORCEINLINE
00217 const OutPtr gil_reinterpret_cast_c(const In* p) { return static_cast<const OutPtr>(static_cast<const void*>(p)); }
00218
00219 namespace detail {
00220
00226
00227 template <class InputIter, class Size, class OutputIter>
00228 std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count,
00229 OutputIter result,
00230 std::input_iterator_tag) {
00231 for ( ; count > 0; --count) {
00232 *result = *first;
00233 ++first;
00234 ++result;
00235 }
00236 return std::pair<InputIter, OutputIter>(first, result);
00237 }
00238
00239 template <class RAIter, class Size, class OutputIter>
00240 inline std::pair<RAIter, OutputIter>
00241 _copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag) {
00242 RAIter last = first + count;
00243 return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result));
00244 }
00245
00246 template <class InputIter, class Size, class OutputIter>
00247 inline std::pair<InputIter, OutputIter>
00248 _copy_n(InputIter first, Size count, OutputIter result) {
00249 return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category());
00250 }
00251
00252 template <class InputIter, class Size, class OutputIter>
00253 inline std::pair<InputIter, OutputIter>
00254 copy_n(InputIter first, Size count, OutputIter result) {
00255 return detail::_copy_n(first, count, result);
00256 }
00257
00259 template <typename T>
00260 struct identity : public std::unary_function<T,T> {
00261 const T& operator()(const T& val) const { return val; }
00262 };
00263
00264
00265
00267 template <typename T1, typename T2>
00268 struct plus_asymmetric : public std::binary_function<T1,T2,T1> {
00269 T1 operator()(T1 f1, T2 f2) const {
00270 return f1+f2;
00271 }
00272 };
00273
00274
00275
00277 template <typename T>
00278 struct inc : public std::unary_function<T,T> {
00279 T operator()(T x) const { return ++x; }
00280 };
00281
00282
00283
00285 template <typename T>
00286 struct dec : public std::unary_function<T,T> {
00287 T operator()(T x) const { return --x; }
00288 };
00289
00291
00292 template <typename Types, typename T>
00293 struct type_to_index
00294 : public mpl::distance<typename mpl::begin<Types>::type,
00295 typename mpl::find<Types,T>::type>::type {};
00296 }
00297
00298
00299
00302 template <typename ColorSpace, typename ChannelMapping = mpl::range_c<int,0,mpl::size<ColorSpace>::value> >
00303 struct layout {
00304 typedef ColorSpace color_space_t;
00305 typedef ChannelMapping channel_mapping_t;
00306 };
00307
00309 template <typename Value, typename T1, typename T2>
00310 void swap_proxy(T1& left, T2& right) {
00311 Value tmp = left;
00312 left = right;
00313 right = tmp;
00314 }
00315
00317 inline bool little_endian() {
00318 short tester = 0x0001;
00319 return *(char*)&tester!=0;
00320 }
00322 inline bool big_endian() {
00323 return !little_endian();
00324 }
00325
00326 } }
00327
00328 #endif