Program Listing for File displacement.h¶
↰ Return to documentation for file (/home/docs/checkouts/readthedocs.org/user_builds/canonical-mir-documentation/checkouts/2.30/include/core/mir/geometry/displacement.h)
/*
* Copyright © Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 2 or 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MIR_GEOMETRY_DISPLACEMENT_H_
#define MIR_GEOMETRY_DISPLACEMENT_H_
#include "forward.h"
#include "dimensions.h"
#include "point.h"
#include <ostream>
namespace mir
{
namespace geometry
{
namespace generic
{
template<typename T>
struct Point;
template<typename T>
struct Size;
template<typename T>
struct Displacement
{
using ValueType = T;
constexpr Displacement() {}
constexpr Displacement(Displacement const&) = default;
Displacement& operator=(Displacement const&) = default;
template<typename U>
explicit constexpr Displacement(Displacement<U> const& other) noexcept :
dx{DeltaX<T>{other.dx}},
dy{DeltaY<T>{other.dy}}
{}
template<typename DeltaXType, typename DeltaYType>
constexpr Displacement(DeltaXType&& dx, DeltaYType&& dy) : dx{dx}, dy{dy}
{}
template<typename Q = T>
constexpr std::enable_if_t<std::is_integral_v<Q>, long long> length_squared() const
{
long long x = dx.as_value(), y = dy.as_value();
return x * x + y * y;
}
template<typename Q = T>
constexpr std::enable_if_t<!std::is_integral_v<Q>, T> length_squared() const
{
T x = dx.as_value(), y = dy.as_value();
return x * x + y * y;
}
friend bool operator==(Displacement const& lhs, Displacement const& rhs) = default;
DeltaX<T> dx;
DeltaY<T> dy;
};
template<typename T>
std::ostream& operator<<(std::ostream& out, Displacement<T> const& value)
{
out << '(' << value.dx << ", " << value.dy << ')';
return out;
}
template<typename T>
inline constexpr Displacement<T> operator+(Displacement<T> const& lhs, Displacement<T> const& rhs)
{ return Displacement<T>{lhs.dx + rhs.dx, lhs.dy + rhs.dy}; }
template<typename T>
inline constexpr Displacement<T> operator-(Displacement<T> const& lhs, Displacement<T> const& rhs)
{ return Displacement<T>{lhs.dx - rhs.dx, lhs.dy - rhs.dy}; }
template<typename T>
inline constexpr Displacement<T> operator-(Displacement<T> const& rhs)
{ return Displacement<T>{-rhs.dx, -rhs.dy}; }
template<typename T>
inline constexpr Point<T> operator+(Point<T> const& lhs, Displacement<T> const& rhs)
{ return Point<T>{lhs.x + rhs.dx, lhs.y + rhs.dy}; }
template<typename T>
inline constexpr Point<T> operator+(Displacement<T> const& lhs, Point<T> const& rhs)
{ return Point<T>{rhs.x + lhs.dx, rhs.y + lhs.dy}; }
template<typename T>
inline constexpr Point<T> operator-(Point<T> const& lhs, Displacement<T> const& rhs)
{ return Point<T>{lhs.x - rhs.dx, lhs.y - rhs.dy}; }
template<typename T>
inline constexpr Displacement<T> operator-(Point<T> const& lhs, Point<T> const& rhs)
{ return Displacement<T>{lhs.x - rhs.x, lhs.y - rhs.y}; }
template<typename T>
inline constexpr Point<T>& operator+=(Point<T>& lhs, Displacement<T> const& rhs)
{ return lhs = lhs + rhs; }
template<typename T>
inline constexpr Point<T>& operator-=(Point<T>& lhs, Displacement<T> const& rhs)
{ return lhs = lhs - rhs; }
template<typename T>
inline bool operator<(Displacement<T> const& lhs, Displacement<T> const& rhs)
{ return lhs.length_squared() < rhs.length_squared(); }
template<typename T, typename Scalar>
inline constexpr Displacement<T> operator*(Scalar scale, Displacement<T> const& disp)
{ return Displacement<T>{scale * disp.dx, scale * disp.dy}; }
template<typename T, typename Scalar>
inline constexpr Displacement<T> operator*(Displacement<T> const& disp, Scalar scale)
{ return scale * disp; }
template<typename T>
inline constexpr Displacement<T> as_displacement(Size<T> const& size)
{ return Displacement<T>{size.width.as_value(), size.height.as_value()}; }
template<typename T>
inline constexpr Size<T> as_size(Displacement<T> const& disp)
{ return Size<T>{disp.dx.as_value(), disp.dy.as_value()}; }
template<typename T>
inline constexpr Displacement<T> as_displacement(Point<T> const& point)
{ return Displacement<T>{point.x.as_value(), point.y.as_value()}; }
template<typename T>
inline constexpr Point<T> as_point(Displacement<T> const& disp)
{ return Point<T>{disp.dx.as_value(), disp.dy.as_value()}; }
}
}
}
#endif // MIR_GEOMETRY_DISPLACEMENT_H_