GCC Code Coverage Report


Directory: ./
File: include/2geom/int-point.h
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 0 3 0.0%
Functions: 0 1 0.0%
Branches: 0 0 -%

Line Branch Exec Source
1 /**
2 * \file
3 * \brief Cartesian point / 2D vector with integer coordinates
4 *//*
5 * Copyright 2011 Krzysztof KosiƄski <tweenk.pl@gmail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
14 *
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
20 *
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
25 *
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
29 */
30
31 #ifndef LIB2GEOM_SEEN_INT_POINT_H
32 #define LIB2GEOM_SEEN_INT_POINT_H
33
34 #include <cassert>
35 #include <tuple>
36 #include <boost/functional/hash.hpp>
37 #include <boost/operators.hpp>
38 #include <2geom/coord.h>
39
40 namespace Geom {
41
42 /**
43 * @brief Two-dimensional point with integer coordinates.
44 *
45 * This class is an exact equivalent of Point, except it stores integer coordinates.
46 * Integer points are useful in contexts related to rasterized graphics, for example
47 * for bounding boxes when rendering SVG.
48 *
49 * @see Point
50 * @ingroup Primitives */
51 class IntPoint
52 : boost::additive< IntPoint
53 , boost::totally_ordered< IntPoint
54 , boost::multiplicative< IntPoint, IntCoord
55 , boost::multiplicative< IntPoint
56 >>>> // base class chaining, see documentation for Boost.Operator
57 {
58 IntCoord _pt[2] = { 0, 0 };
59 public:
60 /// @name Create integer points
61 /// @{
62 /** Construct a point at the origin. */
63 constexpr IntPoint() = default;
64 /** Construct a point from its coordinates. */
65 constexpr IntPoint(IntCoord x, IntCoord y)
66 : _pt{ x, y }
67 {}
68 /// @}
69
70 /// @name Access the coordinates of a point
71 /// @{
72 IntCoord operator[](unsigned i) const { assert(i < 2); return _pt[i]; }
73 IntCoord &operator[](unsigned i) { assert(i < 2); return _pt[i]; }
74 constexpr IntCoord operator[](Dim2 d) const { return _pt[d]; }
75 constexpr IntCoord &operator[](Dim2 d) { return _pt[d]; }
76
77 constexpr IntCoord x() const noexcept { return _pt[X]; }
78 constexpr IntCoord &x() noexcept { return _pt[X]; }
79 constexpr IntCoord y() const noexcept { return _pt[Y]; }
80 constexpr IntCoord &y() noexcept { return _pt[Y]; }
81
82 // Structured binding support
83 template <size_t I> constexpr IntCoord get() const { static_assert(I < 2); return _pt[I]; }
84 template <size_t I> constexpr IntCoord &get() { static_assert(I < 2); return _pt[I]; }
85 /// @}
86
87 /// @name Vector-like operations
88 /// @{
89 constexpr IntCoord lengthSq() const { return _pt[X] * _pt[X] + _pt[Y] * _pt[Y]; }
90 /** @brief Return a point like this point but rotated -90 degrees.
91 * If the y axis grows downwards and the x axis grows to the
92 * right, then this is 90 degrees counter-clockwise. */
93 constexpr IntPoint ccw() const {
94 return IntPoint(_pt[Y], -_pt[X]);
95 }
96 /** @brief Return a point like this point but rotated +90 degrees.
97 * If the y axis grows downwards and the x axis grows to the
98 * right, then this is 90 degrees clockwise. */
99 constexpr IntPoint cw() const {
100 return IntPoint(-_pt[Y], _pt[X]);
101 }
102 /// @}
103
104 /// @name Vector-like arithmetic operations
105 /// @{
106 constexpr IntPoint operator-() const {
107 return IntPoint(-_pt[X], -_pt[Y]);
108 }
109 constexpr IntPoint &operator+=(IntPoint const &o) {
110 _pt[X] += o._pt[X];
111 _pt[Y] += o._pt[Y];
112 return *this;
113 }
114 constexpr IntPoint &operator-=(IntPoint const &o) {
115 _pt[X] -= o._pt[X];
116 _pt[Y] -= o._pt[Y];
117 return *this;
118 }
119 constexpr IntPoint &operator*=(IntPoint const &o) {
120 _pt[X] *= o._pt[X];
121 _pt[Y] *= o._pt[Y];
122 return *this;
123 }
124 constexpr IntPoint &operator*=(IntCoord o) {
125 _pt[X] *= o;
126 _pt[Y] *= o;
127 return *this;
128 }
129 constexpr IntPoint &operator/=(IntPoint const &o) {
130 _pt[X] /= o._pt[X];
131 _pt[Y] /= o._pt[Y];
132 return *this;
133 }
134 constexpr IntPoint &operator/=(IntCoord o) {
135 _pt[X] /= o;
136 _pt[Y] /= o;
137 return *this;
138 }
139 /// @}
140
141 /// @name Various utilities
142 /// @{
143 /** @brief Equality operator. */
144 constexpr bool operator==(IntPoint const &p) const {
145 return _pt[X] == p[X] && _pt[Y] == p[Y];
146 }
147 /** @brief Lexicographical ordering for points.
148 * Y coordinate is regarded as more significant. When sorting according to this
149 * ordering, the points will be sorted according to the Y coordinate, and within
150 * points with the same Y coordinate according to the X coordinate. */
151 constexpr bool operator<(IntPoint const &p) const {
152 return _pt[Y] < p[Y] || (_pt[Y] == p[Y] && _pt[X] < p[X]);
153 }
154 /// @}
155
156 /** @brief Lexicographical ordering functor.
157 * @param d The more significant dimension */
158 template <Dim2 d> struct LexLess;
159 /** @brief Lexicographical ordering functor.
160 * @param d The more significant dimension */
161 template <Dim2 d> struct LexGreater;
162 /** @brief Lexicographical ordering functor with runtime dimension. */
163 struct LexLessRt {
164 LexLessRt(Dim2 d) : dim(d) {}
165 inline bool operator()(IntPoint const &a, IntPoint const &b) const;
166 private:
167 Dim2 dim;
168 };
169 /** @brief Lexicographical ordering functor with runtime dimension. */
170 struct LexGreaterRt {
171 LexGreaterRt(Dim2 d) : dim(d) {}
172 inline bool operator()(IntPoint const &a, IntPoint const &b) const;
173 private:
174 Dim2 dim;
175 };
176 };
177
178 template<> struct IntPoint::LexLess<X> {
179 bool operator()(IntPoint const &a, IntPoint const &b) const {
180 return a[X] < b[X] || (a[X] == b[X] && a[Y] < b[Y]);
181 }
182 };
183 template<> struct IntPoint::LexLess<Y> {
184 bool operator()(IntPoint const &a, IntPoint const &b) const {
185 return a[Y] < b[Y] || (a[Y] == b[Y] && a[X] < b[X]);
186 }
187 };
188 template<> struct IntPoint::LexGreater<X> {
189 bool operator()(IntPoint const &a, IntPoint const &b) const {
190 return a[X] > b[X] || (a[X] == b[X] && a[Y] > b[Y]);
191 }
192 };
193 template<> struct IntPoint::LexGreater<Y> {
194 bool operator()(IntPoint const &a, IntPoint const &b) const {
195 return a[Y] > b[Y] || (a[Y] == b[Y] && a[X] > b[X]);
196 }
197 };
198 inline bool IntPoint::LexLessRt::operator()(IntPoint const &a, IntPoint const &b) const {
199 return dim ? IntPoint::LexLess<Y>()(a, b) : IntPoint::LexLess<X>()(a, b);
200 }
201 inline bool IntPoint::LexGreaterRt::operator()(IntPoint const &a, IntPoint const &b) const {
202 return dim ? IntPoint::LexGreater<Y>()(a, b) : IntPoint::LexGreater<X>()(a, b);
203 }
204
205 } // namespace Geom
206
207 // Structured binding support
208 template <> struct std::tuple_size<Geom::IntPoint> : std::integral_constant<size_t, 2> {};
209 template <size_t I> struct std::tuple_element<I, Geom::IntPoint> { using type = Geom::IntCoord; };
210
211 // Hash support
212 template <> struct std::hash<Geom::IntPoint>
213 {
214 size_t operator()(Geom::IntPoint const &p) const noexcept {
215 size_t hash = 0;
216 boost::hash_combine(hash, p.x());
217 boost::hash_combine(hash, p.y());
218 return hash;
219 }
220 };
221
222 #endif // LIB2GEOM_SEEN_INT_POINT_H
223
224 /*
225 Local Variables:
226 mode:c++
227 c-file-style:"stroustrup"
228 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
229 indent-tabs-mode:nil
230 fill-column:99
231 End:
232 */
233 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
234