Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef MOZILLA_GFX_BASECOORD_H_
7 : #define MOZILLA_GFX_BASECOORD_H_
8 :
9 : #include "mozilla/Attributes.h"
10 :
11 : namespace mozilla {
12 : namespace gfx {
13 :
14 : /**
15 : * Do not use this class directly. Subclass it, pass that subclass as the
16 : * Sub parameter, and only use that subclass. This allows methods to safely
17 : * cast 'this' to 'Sub*'.
18 : */
19 : template <class T, class Sub>
20 : struct BaseCoord {
21 : T value;
22 :
23 : // Constructors
24 1448 : constexpr BaseCoord() : value(0) {}
25 91080 : explicit constexpr BaseCoord(T aValue) : value(aValue) {}
26 :
27 : // Note that '=' isn't defined so we'll get the
28 : // compiler generated default assignment operator
29 :
30 91062 : operator T() const { return value; }
31 :
32 96 : friend bool operator==(Sub aA, Sub aB) {
33 96 : return aA.value == aB.value;
34 : }
35 0 : friend bool operator!=(Sub aA, Sub aB) {
36 0 : return aA.value != aB.value;
37 : }
38 :
39 0 : friend Sub operator+(Sub aA, Sub aB) {
40 0 : return Sub(aA.value + aB.value);
41 : }
42 0 : friend Sub operator-(Sub aA, Sub aB) {
43 0 : return Sub(aA.value - aB.value);
44 : }
45 0 : friend Sub operator*(Sub aCoord, T aScale) {
46 0 : return Sub(aCoord.value * aScale);
47 : }
48 0 : friend Sub operator*(T aScale, Sub aCoord) {
49 0 : return Sub(aScale * aCoord.value);
50 : }
51 0 : friend Sub operator/(Sub aCoord, T aScale) {
52 0 : return Sub(aCoord.value / aScale);
53 : }
54 : // 'scale / coord' is intentionally omitted because it doesn't make sense.
55 :
56 0 : Sub& operator+=(Sub aCoord) {
57 0 : value += aCoord.value;
58 0 : return *static_cast<Sub*>(this);
59 : }
60 0 : Sub& operator-=(Sub aCoord) {
61 0 : value -= aCoord.value;
62 0 : return *static_cast<Sub*>(this);
63 : }
64 0 : Sub& operator*=(T aScale) {
65 0 : value *= aScale;
66 0 : return *static_cast<Sub*>(this);
67 : }
68 : Sub& operator/=(T aScale) {
69 : value /= aScale;
70 : return *static_cast<Sub*>(this);
71 : }
72 :
73 : // Since BaseCoord is implicitly convertible to its value type T, we need
74 : // mixed-type operator overloads to avoid ambiguities at mixed-type call
75 : // sites. As we transition more of our code to strongly-typed classes, we
76 : // may be able to remove some or all of these overloads.
77 : friend bool operator==(Sub aA, T aB) {
78 : return aA.value == aB;
79 : }
80 : friend bool operator==(T aA, Sub aB) {
81 : return aA == aB.value;
82 : }
83 116 : friend bool operator!=(Sub aA, T aB) {
84 116 : return aA.value != aB;
85 : }
86 : friend bool operator!=(T aA, Sub aB) {
87 : return aA != aB.value;
88 : }
89 0 : friend T operator+(Sub aA, T aB) {
90 0 : return aA.value + aB;
91 : }
92 : friend T operator+(T aA, Sub aB) {
93 : return aA + aB.value;
94 : }
95 0 : friend T operator-(Sub aA, T aB) {
96 0 : return aA.value - aB;
97 : }
98 0 : friend T operator-(T aA, Sub aB) {
99 0 : return aA - aB.value;
100 : }
101 :
102 0 : Sub operator-() const {
103 0 : return Sub(-value);
104 : }
105 : };
106 :
107 : } // namespace gfx
108 : } // namespace mozilla
109 :
110 : #endif /* MOZILLA_GFX_BASECOORD_H_ */
|