8 #ifndef BOOST_GIL_POINT_HPP     9 #define BOOST_GIL_POINT_HPP    11 #include <boost/gil/utilities.hpp>    12 #include <boost/gil/detail/std_common_type.hpp>    14 #include <boost/config.hpp>    17 #include <type_traits>    19 namespace boost { 
namespace gil {
    40     template<std::
size_t D>
    43         using coord_t = value_type;
    46     static constexpr std::size_t num_dimensions = 2;
    49     point(T px, T py) : x(px), y(py) {}
    51     point operator<<(std::ptrdiff_t shift)
 const    53         return point(x << shift, y << shift);
    56     point operator>>(std::ptrdiff_t shift)
 const    58         return point(x >> shift, y >> shift);
    61     point& operator+=(point 
const& p)
    68     point& operator-=(point 
const& p)
    75     point& operator/=(
double d)
    79             x = static_cast<T>(x / d);
    80             y = static_cast<T>(y / d);
    85     point& operator*=(
double d)
    87         x = static_cast<T>(x * d);
    88         y = static_cast<T>(y * d);
    92     T 
const& operator[](std::size_t i)
 const    94         return this->*mem_array[i];
    97     T& operator[](std::size_t i)
    99         return this->*mem_array[i];
   108     static T point<T>::* 
const mem_array[num_dimensions];
   112 template <
typename T>
   113 using point2 = point<T>;
   117 using point_t = point<std::ptrdiff_t>;
   119 template <
typename T>
   120 T point<T>::* 
const point<T>::mem_array[point<T>::num_dimensions] =
   127 template <
typename T>
   129 bool operator==(
const point<T>& p1, 
const point<T>& p2)
   131     return p1.x == p2.x && p1.y == p2.y;
   135 template <
typename T>
   137 bool operator!=(
const point<T>& p1, 
const point<T>& p2)
   139     return p1.x != p2.x || p1.y != p2.y;
   143 template <
typename T>
   145 point<T> operator+(
const point<T>& p1, 
const point<T>& p2)
   147     return { p1.x + p2.x, p1.y + p2.y };
   151 template <
typename T>
   153 point<T> operator-(
const point<T>& p)
   155     return { -p.x, -p.y };
   159 template <
typename T>
   161 point<T> operator-(
const point<T>& p1, 
const point<T>& p2)
   163     return { p1.x - p2.x, p1.y - p2.y };
   167 template <
typename T, 
typename D>
   169 auto operator/(point<T> 
const& p, D d)
   170     -> 
typename std::enable_if
   172         std::is_arithmetic<D>::value,
   173         point<typename detail::std_common_type<T, D>::type>
   176     static_assert(std::is_arithmetic<D>::value, 
"denominator is not arithmetic type");
   177     using result_type = 
typename detail::std_common_type<T, D>::type;
   180         double const x = static_cast<double>(p.x) / static_cast<double>(d);
   181         double const y = static_cast<double>(p.y) / static_cast<double>(d);
   182         return point<result_type>{
   183             static_cast<result_type>(iround(x)),
   184             static_cast<result_type>(iround(y))};
   188         return point<result_type>{0, 0};
   193 template <
typename T, 
typename M>
   195 auto operator*(point<T> 
const& p, M m)
   196     -> 
typename std::enable_if
   198         std::is_arithmetic<M>::value,
   199         point<typename detail::std_common_type<T, M>::type>
   202     static_assert(std::is_arithmetic<M>::value, 
"multiplier is not arithmetic type");
   203     using result_type = 
typename detail::std_common_type<T, M>::type;
   204     return point<result_type>{p.x * m, p.y * m};
   208 template <
typename T, 
typename M>
   210 auto operator*(M m, point<T> 
const& p)
   211     -> 
typename std::enable_if
   213         std::is_arithmetic<M>::value,
   214         point<typename detail::std_common_type<T, M>::type>
   217     static_assert(std::is_arithmetic<M>::value, 
"multiplier is not arithmetic type");
   218     using result_type = 
typename detail::std_common_type<T, M>::type;
   219     return point<result_type>{p.x * m, p.y * m};
   223 template <std::
size_t K, 
typename T>
   225 T 
const& axis_value(point<T> 
const& p)
   227     static_assert(K < point<T>::num_dimensions, 
"axis index out of range");
   232 template <std::
size_t K, 
typename T>
   234 T& axis_value(point<T>& p)
   236     static_assert(K < point<T>::num_dimensions, 
"axis index out of range");
   248 template <
typename T>
   249 inline point<std::ptrdiff_t> iround(point<T> 
const& p)
   251     static_assert(std::is_integral<T>::value, 
"T is not integer");
   252     return { static_cast<std::ptrdiff_t>(p.x), static_cast<std::ptrdiff_t>(p.y) };
   256 inline point<std::ptrdiff_t> iround(point<float> 
const& p)
   258     return { iround(p.x), iround(p.y) };
   262 inline point<std::ptrdiff_t> iround(point<double> 
const& p)
   264     return { iround(p.x), iround(p.y) };
   268 inline point<std::ptrdiff_t> ifloor(point<float> 
const& p)
   270     return { ifloor(p.x), ifloor(p.y) };
   274 inline point<std::ptrdiff_t> ifloor(point<double> 
const& p)
   276     return { ifloor(p.x), ifloor(p.y) };
   280 inline point<std::ptrdiff_t> iceil(point<float> 
const& p)
   282     return { iceil(p.x), iceil(p.y) };
   286 inline point<std::ptrdiff_t> iceil(point<double> 
const& p)
   288     return { iceil(p.x), iceil(p.y) };