52 #ifndef __PCL_Rectangle_h
53 #define __PCL_Rectangle_h
64 #ifdef __PCL_QT_INTERFACE
65 # include <QtCore/QRect>
66 # ifndef __PCL_QT_NO_RECT_DRAWING_HELPERS
67 # include <QtGui/QPainter>
68 # include <QtGui/QBrush>
123 template <
typename T>
inline
124 bool IsPoint( T x0, T y0, T x1, T y1 ) noexcept
126 return x0 == x1 && y0 == y1;
141 template <
typename T>
inline
142 bool IsLine( T x0, T y0, T x1, T y1 ) noexcept
144 return ((x0 == x1) ^ (y0 == y1)) != 0;
158 template <
typename T>
inline
161 return y0 == y1 && x0 != x1;
175 template <
typename T>
inline
178 return x0 == x1 && y0 != y1;
192 template <
typename T>
inline
195 return x0 == x1 || y0 == y1;
209 template <
typename T>
inline
210 bool IsRect( T x0, T y0, T x1, T y1 ) noexcept
212 return x0 != x1 && y0 != y1;
225 template <
typename T>
inline
228 return x0 < x1 && y0 < y1;
242 template <
typename T>
inline
245 return x0 <= x1 && y0 <= y1;
259 template <
typename T>
inline
278 #define PCL_ASSERT_RECT_SIZE() \
279 static_assert( sizeof( *this ) == 4*sizeof( T ), "Invalid sizeof( GenericRectangle<> )" )
312 template <
typename T>
343 PCL_ASSERT_RECT_SIZE();
356 template <
typename T1>
363 PCL_ASSERT_RECT_SIZE();
391 template <
typename T1>
394 PCL_ASSERT_RECT_SIZE();
424 template <
typename T1>
429 PCL_ASSERT_RECT_SIZE();
443 PCL_ASSERT_RECT_SIZE();
456 PCL_ASSERT_RECT_SIZE();
463 template <
typename T1>
468 PCL_ASSERT_RECT_SIZE();
471 #ifdef __PCL_QT_INTERFACE
474 component( r.right()+1 ), component( r.bottom()+1 ) )
476 PCL_ASSERT_RECT_SIZE();
479 GenericRectangle(
const QPoint& p0,
const QPoint& p1 )
480 : GenericRectangle( component( p0.x() ), component( p0.y() ),
481 component( p1.x() ), component( p1.y() ) )
483 PCL_ASSERT_RECT_SIZE();
588 return RightBottom();
596 return point( (x0 + x1)/2, (y0 + y1)/2 );
667 return Width() + Height();
676 return pcl::Abs( (x1 - x0)*(y1 - y0) );
685 return 0.5*(x0 + x1);
694 return 0.5*(y0 + y1);
705 double w = x1 - x0, h = y1 - y0;
809 template <
typename T1>
816 if ( x < x0 ) clip |= Clip::Left;
817 if ( x > x1 ) clip |= Clip::Right;
821 if ( x < x1 ) clip |= Clip::Left;
822 if ( x > x0 ) clip |= Clip::Right;
827 if ( y < y0 ) clip |= Clip::Top;
828 if ( y > y1 ) clip |= Clip::Bottom;
832 if ( y < y1 ) clip |= Clip::Top;
833 if ( y > y0 ) clip |= Clip::Bottom;
846 template <
typename T1>
849 return ClipCode( p.x, p.y );
856 template <
typename T1>
859 return ((x0 < x1) ? (x >= x0 && x <= x1) : (x >= x1 && x <= x0)) &&
860 ((y0 < y1) ? (y >= y0 && y <= y1) : (y >= y1 && y <= y0));
866 template <
typename T1>
869 return Includes( p.x, p.y );
875 template <
typename T1>
878 return Includes( r.x0, r.y0 ) && Includes( r.x1, r.y1 );
881 #ifdef __PCL_QT_INTERFACE
882 bool Includes(
const QPoint& p )
const noexcept
884 return Includes( p.x(), p.y() );
887 bool Includes(
const QRect& r )
const noexcept
889 return Includes( r.left(), r.top() ) && Includes( r.right()+1, r.bottom()+1 );
901 template <
typename T1>
904 return x >= x0 && y >= y0 && x <= x1 && y <= y1;
914 template <
typename T1>
917 return IncludesFast( p.x, p.y );
930 template <
typename T1>
931 bool Intersects( T1 left, T1 top, T1 right, T1 bottom )
const noexcept
934 return ((x0 < x1) ? (right >= x0 && left <= x1) : (right >= x1 && left <= x0)) &&
935 ((y0 < y1) ? (bottom >= y0 && top <= y1) : (bottom >= y1 && top <= y0));
941 template <
typename T1>
944 return Intersects( r.x0, r.y0, r.x1, r.y1 );
947 #ifdef __PCL_QT_INTERFACE
948 bool Intersects(
const QRect& r )
const noexcept
950 return Intersects( r.left(), r.top(), r.right()+1, r.bottom()+1 );
973 template <
typename T1>
976 return right >= x0 && left <= x1 && bottom >= y0 && top <= y1;
985 template <
typename T1>
988 return IntersectsFast( r.x0, r.y0, r.x1, r.y1 );
995 template <
typename T1>
998 Unite( r.x0, r.y0, r.x1, r.y1 );
1011 template <
typename T1>
1012 void Unite( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1015 Swap( left, right );
1017 Swap( top, bottom );
1049 template <
typename T1>
1052 UniteFast( r.x0, r.y0, r.x1, r.y1 );
1074 template <
typename T1>
1075 void UniteFast( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1086 template <
typename T1>
1100 template <
typename T1>
1112 template <
typename T1>
1119 #ifdef __PCL_QT_INTERFACE
1120 void Unite(
const QRect& r )
1122 Unite( r.left(), r.top(), r.right()+1, r.bottom()+1 );
1125 GenericRectangle Union(
const QRect& r )
const noexcept
1127 GenericRectangle r1 = *
this;
1132 GenericRectangle& operator |=(
const QRect& r ) noexcept
1147 template <
typename T1>
1150 return Intersect( r.x0, r.y0, r.x1, r.y1 );
1167 template <
typename T1>
1168 bool Intersect( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1171 Swap( left, right );
1173 Swap( top, bottom );
1211 template <
typename T1>
1214 return IntersectFast( r.x0, r.y0, r.x1, r.y1 );
1240 template <
typename T1>
1254 template <
typename T1>
1269 template <
typename T1>
1281 template <
typename T1>
1288 #ifdef __PCL_QT_INTERFACE
1289 bool Intersect(
const QRect& r ) noexcept
1291 return Intersect( r.left(), r.top(), r.right()+1, r.bottom()+1 );
1294 GenericRectangle Intersection(
const QRect& r )
const noexcept
1296 GenericRectangle r1 = *
this;
1297 (void)r1.Intersect( r );
1301 GenericRectangle& operator &=(
const QRect& r ) noexcept
1314 template <
typename T1>
1315 void Set( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1330 template <
typename T1>
1343 template <
typename T1>
1353 #ifdef __PCL_QT_INTERFACE
1354 void MoveTo(
const QPoint& p ) noexcept
1356 MoveTo( p.x(), p.y() );
1366 template <
typename T1>
1380 template <
typename T1>
1392 template <
typename T1>
1403 template <
typename T1>
1421 template <
typename T1>
1430 #ifdef __PCL_QT_INTERFACE
1431 void MoveBy(
const QPoint& p ) noexcept
1433 MoveBy( p.x(), p.y() );
1443 template <
typename T1>
1457 template <
typename T1>
1475 template <
typename T1>
1495 template <
typename T1>
1514 template <
typename T1>
1534 template <
typename T1>
1550 template <
typename T1>
1567 template <
typename T1>
1581 template <
typename T1>
1599 template <
typename T1>
1617 template <
typename T1>
1629 template <
typename T1>
1646 InflateBy( kx*Width()/2, ky*Height()/2 );
1657 InflateBy( k*Width()/2, k*Height()/2 );
1689 template <
typename T1>
1707 template <
typename T1>
1725 template <
typename T1>
1737 template <
typename T1>
1751 template <
typename T1>
1765 template <
typename T1>
1778 template <
typename T1,
typename T2>
1779 void Rotate( T1 angle, T2 xc, T2 yc ) noexcept
1790 template <
typename T1,
typename T2>
1793 Rotate( angle, center.x, center.y );
1801 template <
typename T1,
typename T2>
1802 void Rotate( T1 sa, T1 ca, T2 xc, T2 yc ) noexcept
1813 template <
typename T1,
typename T2>
1816 Rotate( sa, ca, center.x, center.y );
1824 template <
typename T1,
typename T2>
1828 r.
Rotate( angle, xc, yc );
1837 template <
typename T1,
typename T2>
1841 r.
Rotate( angle, center );
1851 template <
typename T1,
typename T2>
1855 r.
Rotate( sa, ca, xc, yc );
1865 template <
typename T1,
typename T2>
1869 r.
Rotate( sa, ca, center );
1891 PCL_PRECONDITION( n >= 0 )
1916 PCL_PRECONDITION( n >= 0 )
1972 template <
typename T1>
1989 template <
typename T1>
2005 x0 = y0 = x1 = y1 = d;
2009 #ifdef __PCL_QT_INTERFACE
2012 x0 = component( r.left() );
2013 y0 = component( r.top() );
2014 x1 = component( r.right()+1 );
2015 y1 = component( r.bottom()+1 );
2032 template <
typename T1>
2055 template <
typename T1>
2088 #ifdef __PCL_QT_INTERFACE
2091 component dx = component( p.x() ), dy = component( p.y() );
2112 template <
typename T1>
2135 template <
typename T1>
2168 #ifdef __PCL_QT_INTERFACE
2171 component dx = component( p.x() ), dy = component( p.y() );
2192 template <
typename T1>
2216 template <
typename T1>
2249 #ifdef __PCL_QT_INTERFACE
2252 component dx = component( p.x() ), dy = component( p.y() );
2253 x0 *= dx; y0 *= dy; x1 *= dx; y1 *= dy;
2270 template <
typename T1>
2296 template <
typename T1>
2324 x0 /= d; y0 /= d; x1 /= d; y1 /= d;
2328 #ifdef __PCL_QT_INTERFACE
2331 PCL_PRECONDITION( component( p.x() ) != component( 0 ) && component( p.y() ) != component( 0 ) )
2332 component dx = component( p.x() ), dy = component( p.y() );
2360 #ifdef __PCL_QT_INTERFACE
2361 operator QRect() const noexcept
2363 return QRect(
int( x0 ),
int( y0 ),
int( x1-x0 ),
int( y1-y0 ) );
2367 #ifdef __PCL_QT_INTERFACE
2368 # ifndef __PCL_QT_NO_RECT_DRAWING_HELPERS
2370 void Draw( QPainter& p,
const QBrush* b )
const
2372 int rx0, ry0, rx1, ry1;
2384 if ( rx1 - rx0 <= 1 )
2386 if ( ry1 - ry0 <= 1 )
2387 p.drawPoint( rx0, ry0 );
2389 p.drawLine( rx0, ry0, rx0, ry1-1 );
2391 else if ( ry1 - ry0 <= 1 )
2393 p.drawLine( rx0, ry0, rx1-1, ry0 );
2397 # if ( QT_VERSION >= 0x040000 )
2398 int w = rx1-rx0-1, h = ry1-ry0-1;
2400 int w = rx1-rx0, h = ry1-ry0;
2403 p.fillRect( rx0, ry0, w, h, *b );
2404 p.drawRect( rx0, ry0, w, h );
2408 void Draw( QPainter& p )
const
2413 void Draw( QPainter& p,
const QColor& c )
const
2424 #undef PCL_ASSERT_RECT_SIZE
2437 template <
typename T1,
typename T2>
inline
2440 return r1.x0 == r2.x0 && r1.y0 == r2.y0 && r1.x1 == r2.x1 && r1.y1 == r2.y1;
2448 template <
typename T>
inline
2451 return r1.x0 == d2 && r1.y0 == d2 && r1.x1 == d2 && r1.y1 == d2;
2460 template <
typename T>
inline
2463 return d1 == r2.x0 && d1 == r2.y0 && d1 == r2.x1 && d1 == r2.y1;
2472 template <
typename T1,
typename T2>
inline
2475 T1 x01 =
Min( r1.x0, r1.x1 ); T1 y01 =
Min( r1.y0, r1.y1 );
2476 T1 x11 =
Max( r1.x0, r1.x1 ); T1 y11 =
Max( r1.y0, r1.y1 );
2477 T2 x02 =
Min( r2.x0, r2.x1 ); T2 y02 =
Min( r2.y0, r2.y1 );
2478 T2 x12 =
Max( r2.x0, r2.x1 ); T2 y12 =
Max( r2.y0, r2.y1 );
2503 template <
typename T1,
typename T2>
inline
2507 T1( r1.x1 + r2.x1 ), T1( r1.y1 + r2.y1 ) );
2524 template <
typename T1,
typename T2>
inline
2528 T1( r1.x1 + p2.x ), T1( r1.y1 + p2.y ) );
2540 template <
typename T1,
typename T2>
inline
2544 T2( p1.x + r2.x1 ), T2( p1.y + r2.y1 ) );
2561 template <
typename T>
inline
2576 template <
typename T>
inline
2597 template <
typename T1,
typename T2>
inline
2601 T1( r1.x1 - r2.x1 ), T1( r1.y1 - r2.y1 ) );
2618 template <
typename T1,
typename T2>
inline
2622 T1( r1.x1 - p2.x ), T1( r1.y1 - p2.y ) );
2639 template <
typename T1,
typename T2>
inline
2643 T2( p1.x - r2.x1 ), T2( p1.y - r2.y1 ) );
2660 template <
typename T>
inline
2680 template <
typename T>
inline
2701 template <
typename T1,
typename T2>
inline
2705 T1( r1.x1 * r2.x1 ), T1( r1.y1 * r2.y1 ) );
2722 template <
typename T1,
typename T2>
inline
2726 T1( r1.x1 * p2.x ), T1( r1.y1 * p2.y ) );
2738 template <
typename T1,
typename T2>
inline
2742 T2( p1.x * r2.x1 ), T2( p1.y * r2.y1 ) );
2759 template <
typename T>
inline
2774 template <
typename T>
inline
2795 template <
typename T1,
typename T2>
inline
2798 PCL_PRECONDITION( r2.x0 != T2( 0 ) && r2.y0 != T2( 0 ) &&
2799 r2.x1 != T2( 0 ) && r2.y1 != T2( 0 ) )
2801 T1( r1.x1 / r2.x1 ), T1( r1.y1 / r2.y1 ) );
2818 template <
typename T1,
typename T2>
inline
2821 PCL_PRECONDITION( p2.x != T2( 0 ) && p2.y != T2( 0 ) )
2823 T1( r1.x1 / p2.x ), T1( r1.y1 / p2.y ) );
2840 template <
typename T1,
typename T2>
inline
2843 PCL_PRECONDITION( r2.x0 != T2( 0 ) && r2.y0 != T2( 0 ) &&
2844 r2.x1 != T2( 0 ) && r2.y1 != T2( 0 ) )
2846 T2( p1.x / r2.x1 ), T2( p1.y / r2.y1 ) );
2863 template <
typename T>
inline
2866 PCL_PRECONDITION( d2 != T( 0 ) )
2884 template <
typename T>
inline
2887 PCL_PRECONDITION( r2.x0 != T( 0 ) && r2.y0 != T( 0 ) &&
2888 r2.x1 != T( 0 ) && r2.y1 != T( 0 ) )
2907 template <
typename T,
typename T1,
typename T2>
inline
2930 template <
typename T,
typename T1,
typename T2>
inline
2951 template <
typename T,
typename T1,
typename T2>
inline
2973 template <
typename T,
typename T1,
typename T2>
inline
2990 template <
typename T>
inline
2999 #ifndef __PCL_NO_RECT_INSTANTIATE
3012 using I32Rect = GenericRectangle<int32>;
3031 using F32Rect = GenericRectangle<float>;
3050 using F64Rect = GenericRectangle<double>;
64-bit floating-point rectangle in the R^2 space.
32-bit floating-point rectangle in the R^2 space.
64-bit floating-point rectangle in the R^2 space.
32-bit floating-point rectangle in the R^2 space.
A type-safe collection of enumerated flags.
A generic point in the two-dimensional space.
A generic rectangle in the two-dimensional space.
point BottomRight() const noexcept
GenericRectangle Truncated() const noexcept
GenericRectangle(const pcl::GenericPoint< T1 > &leftTop, const pcl::GenericPoint< T1 > &rightBottom)
bool IsPointOrLine() const noexcept
component Left() const noexcept
constexpr GenericRectangle(component d)
void MoveBy(const pcl::GenericPoint< T1 > &d) noexcept
void SetWidth(T1 w) noexcept
GenericRectangle Rotated(T1 angle, const GenericPoint< T2 > ¢er) const noexcept
component Perimeter() const noexcept
double CenterY() const noexcept
constexpr GenericRectangle(T1 left, T1 top, T1 right, T1 bottom)
GenericRectangle IntersectionFast(const GenericRectangle< T1 > &r) const noexcept
bool IntersectsFast(const pcl::GenericRectangle< T1 > &r) const noexcept
void Round(int n) noexcept
point LeftTop() const noexcept
void UniteFast(T1 left, T1 top, T1 right, T1 bottom) noexcept
component x1
Horizontal coordinate of the lower right corner.
void Unite(T1 left, T1 top, T1 right, T1 bottom) noexcept
GenericRectangle Rounded(int n) const noexcept
void MoveTo(T1 x, T1 y) noexcept
GenericRectangle InflatedByFactors(double kx, double ky) noexcept
point RightTop() const noexcept
bool Intersect(T1 left, T1 top, T1 right, T1 bottom) noexcept
double CenterX() const noexcept
bool IsOrdered() const noexcept
component Area() const noexcept
void MoveBy(T1 dx, T1 dy) noexcept
GenericRectangle InflatedBy(T1 dx, T1 dy) const noexcept
component Bottom() const noexcept
GenericRectangle InflatedBy(T1 d) const noexcept
point CenterLeft() const noexcept
void InflateBy(T1 d) noexcept
constexpr GenericRectangle(component width, component height)
void DeflateBy(T1 d) noexcept
component y1
Vertical coordinate of the lower right corner.
point TopLeft() const noexcept
point Center() const noexcept
point LeftBottom() const noexcept
void InflateBy(T1 dx, T1 dy) noexcept
point CenterBottom() const noexcept
bool IsRect() const noexcept
GenericRectangle InflatedByFactor(double k) noexcept
bool IsVerticalLine() const noexcept
GenericRectangle Rotated(T1 sa, T1 ca, const GenericPoint< T2 > ¢er) const noexcept
void InflateByFactors(double kx, double ky) noexcept
bool IsHorizontalLine() const noexcept
GenericRectangle Rotated(T1 sa, T1 ca, T2 xc, T2 yc) const noexcept
GenericRectangle< int > RoundedToInt() const noexcept
GenericRectangle< int > TruncatedToInt() const noexcept
point RightBottom() const noexcept
void ResizeTo(T1 w, T1 h) noexcept
bool IsNormal() const noexcept
component y0
Vertical coordinate of the upper left corner.
bool IntersectsFast(T1 left, T1 top, T1 right, T1 bottom) const noexcept
bool Includes(T1 x, T1 y) const noexcept
component x0
Horizontal coordinate of the upper left corner.
void Set(T1 left, T1 top, T1 right, T1 bottom) noexcept
GenericRectangle Rotated(T1 angle, T2 xc, T2 yc) const noexcept
GenericRectangle MovedTo(const pcl::GenericPoint< T1 > &p) const noexcept
void DeflateBy(T1 dx, T1 dy) noexcept
point CenterTop() const noexcept
GenericRectangle ResizedBy(T1 dw, T1 dh) const noexcept
void UniteFast(const GenericRectangle< T1 > &r) noexcept
void Rotate(T1 sa, T1 ca, T2 xc, T2 yc) noexcept
void InflateByFactor(double k) noexcept
GenericRectangle UnionFast(const GenericRectangle< T1 > &r) const noexcept
bool Intersects(const pcl::GenericRectangle< T1 > &r) const noexcept
ClipFlags ClipCode(T1 x, T1 y) const noexcept
GenericRectangle HeightSetTo(T1 h) const noexcept
component Right() const noexcept
GenericRectangle MovedBy(T1 dx, T1 dy) const noexcept
bool Includes(const GenericRectangle< T1 > &r) const noexcept
bool Includes(const pcl::GenericPoint< T1 > &p) const noexcept
point CenterRight() const noexcept
GenericRectangle ResizedTo(T1 w, T1 h) const noexcept
bool IntersectFast(const GenericRectangle< T1 > &r) noexcept
void Unite(const GenericRectangle< T1 > &r) noexcept
bool IncludesFast(const pcl::GenericPoint< T1 > &p) const noexcept
bool IntersectFast(T1 left, T1 top, T1 right, T1 bottom) noexcept
void Rotate(T1 angle, T2 xc, T2 yc) noexcept
void ResizeBy(T1 dw, T1 dh) noexcept
double Hypot() const noexcept
bool IsPoint() const noexcept
void Rotate(T1 angle, const GenericPoint< T2 > ¢er) noexcept
void MoveTo(const pcl::GenericPoint< T1 > &p) noexcept
GenericRectangle DeflatedBy(T1 d) const noexcept
bool Intersect(const GenericRectangle< T1 > &r) noexcept
GenericRectangle DeflatedBy(T1 dx, T1 dy) const noexcept
GenericRectangle(std::initializer_list< T1 > l)
point TopRight() const noexcept
point BottomLeft() const noexcept
ClipFlags ClipCode(const pcl::GenericPoint< T1 > &p) const noexcept
component ManhattanDistance() const noexcept
GenericRectangle(const GenericRectangle< T1 > &r)
constexpr GenericRectangle()
GenericRectangle Union(const GenericRectangle< T1 > &r) const noexcept
GenericRectangle Ordered() const noexcept
component Top() const noexcept
component Width() const noexcept
bool IncludesFast(T1 x, T1 y) const noexcept
GenericRectangle MovedBy(const pcl::GenericPoint< T1 > &d) const noexcept
GenericRectangle MovedTo(T1 x, T1 y) const noexcept
component Height() const noexcept
void MoveBy(T1 dxy) noexcept
void SetHeight(T1 h) noexcept
double Diagonal() const noexcept
GenericRectangle Intersection(const GenericRectangle< T1 > &r) const noexcept
GenericRectangle Rounded() const noexcept
GenericRectangle WidthSetTo(T1 w) const noexcept
void Rotate(T1 sa, T1 ca, const GenericPoint< T2 > ¢er) noexcept
bool IsLine() const noexcept
bool Intersects(T1 left, T1 top, T1 right, T1 bottom) const noexcept
32-bit integer rectangle on the plane.
32-bit integer rectangle on the plane.
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Complex< T1 > operator-(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Complex< T1 > operator*(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Complex< T1 > operator+(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Complex< T1 > operator/(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Complex< T > Sqrt(const Complex< T > &c) noexcept
T Abs(const Complex< T > &c) noexcept
Complex< T > Round(const Complex< T > &c) noexcept
void SinCos(T x, T &sx, T &cx) noexcept
void Rotate(T &x, T &y, T1 sa, T1 ca, T2 xc, T2 yc) noexcept
int RoundInt(T x) noexcept
int TruncInt(T x) noexcept
void Swap(GenericPoint< T > &p1, GenericPoint< T > &p2) noexcept
bool IsHorizontalLine(T x0, T y0, T x1, T y1) noexcept
bool IsNormalRect(T x0, T y0, T x1, T y1) noexcept
bool IsRect(T x0, T y0, T x1, T y1) noexcept
bool IsOrderedRect(T x0, T y0, T x1, T y1) noexcept
bool IsLine(T x0, T y0, T x1, T y1) noexcept
bool IsVerticalLine(T x0, T y0, T x1, T y1) noexcept
bool IsPointOrLine(T x0, T y0, T x1, T y1) noexcept
bool IsPoint(T x0, T y0, T x1, T y1) noexcept
void OrderRect(T &x0, T &y0, T &x1, T &y1) noexcept
constexpr const T & Min(const T &a, const T &b) noexcept
constexpr const T & Max(const T &a, const T &b) noexcept