19 #ifndef MIR_GEOMETRY_DISPLACEMENT_GENERIC_H_
20 #define MIR_GEOMETRY_DISPLACEMENT_GENERIC_H_
37 template<
template<
typename>
typename T>
40 template<
template<
typename>
typename T>
43 template<
template<
typename>
typename T>
46 template<
typename Tag>
56 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
58 :
dx{T<DeltaXTag>{other.dx}},
59 dy{T<DeltaYTag>{other.dy}}
63 template<
typename DeltaXType,
typename DeltaYType>
70 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
71 inline constexpr
bool operator==(D
const& lhs, D
const& rhs)
73 return lhs.dx == rhs.dx && lhs.dy == rhs.dy;
76 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
77 inline constexpr
bool operator!=(D
const& lhs, D
const& rhs)
79 return lhs.dx != rhs.dx || lhs.dy != rhs.dy;
82 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
83 std::ostream&
operator<<(std::ostream& out, D
const& value)
85 out <<
'(' << value.dx <<
", " << value.dy <<
')';
89 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
90 inline constexpr D
operator+(D
const& lhs, D
const& rhs)
92 return D{lhs.dx + rhs.dx, lhs.dy + rhs.dy};
95 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
96 inline constexpr D
operator-(D
const& lhs, D
const& rhs)
98 return D{lhs.dx - rhs.dx, lhs.dy - rhs.dy};
101 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
104 return D{-rhs.dx, -rhs.dy};
107 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
108 inline constexpr
typename D::PointType
operator+(
typename D::PointType
const& lhs, D
const& rhs)
110 return typename D::PointType{lhs.x + rhs.dx, lhs.y + rhs.dy};
113 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
114 inline constexpr
typename D::PointType
operator+(D
const& lhs,
typename D::PointType
const& rhs)
116 return typename D::PointType{rhs.x + lhs.dx, rhs.y + lhs.dy};
119 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
120 inline constexpr
typename D::PointType
operator-(
typename D::PointType
const& lhs, D
const& rhs)
122 return typename D::PointType{lhs.x - rhs.dx, lhs.y - rhs.dy};
125 template<typename P, typename std::enable_if<std::is_base_of<detail::PointBase, P>::value,
bool>::type =
true>
126 inline constexpr
typename P::DisplacementType
operator-(P
const& lhs, P
const& rhs)
128 return typename P::DisplacementType{lhs.x - rhs.x, lhs.y - rhs.y};
131 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
132 inline constexpr
typename D::PointType&
operator+=(
typename D::PointType& lhs, D
const& rhs)
134 return lhs = lhs + rhs;
137 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
138 inline constexpr
typename D::PointType&
operator-=(
typename D::PointType& lhs, D
const& rhs)
140 return lhs = lhs - rhs;
143 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
146 return lhs.length_squared() < rhs.length_squared();
149 template<typename Scalar, typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
150 inline constexpr D
operator*(Scalar scale, D
const& disp)
152 return D{scale*disp.dx, scale*disp.dy};
155 template<typename Scalar, typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
156 inline constexpr D
operator*(D
const& disp, Scalar scale)
161 template<typename S, typename std::enable_if<std::is_base_of<detail::SizeBase, S>::value,
bool>::type =
true>
164 return typename S::DisplacementType{size.width.as_value(), size.height.as_value()};
167 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
168 inline constexpr
typename D::SizeType
as_size(D
const& disp)
170 return typename D::SizeType{disp.dx.as_value(), disp.dy.as_value()};
173 template<typename P, typename std::enable_if<std::is_base_of<detail::PointBase, P>::value,
bool>::type =
true>
176 return typename P::DisplacementType{point.x.as_value(), point.y.as_value()};
179 template<typename D, typename std::enable_if<std::is_base_of<detail::DisplacementBase, D>::value,
bool>::type =
true>
180 inline constexpr
typename D::PointType
as_point(D
const& disp)
182 return typename D::PointType{disp.dx.as_value(), disp.dy.as_value()};
188 #endif // MIR_GEOMETRY_DISPLACEMENT_GENERIC_H_