FINAL CUT
fsize.h
1 /***********************************************************************
2 * fsize.h - Height and width of a two-dimensional surface *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2014-2025 Markus Gans *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Standalone class
24  * ════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▏
27  * ▕ FSize ▏
28  * ▕▁▁▁▁▁▁▁▏
29  */
30 
31 #ifndef FSIZE_H
32 #define FSIZE_H
33 
34 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
35  #error "Only <final/final.h> can be included directly."
36 #endif
37 
38 #include <iostream>
39 #include <limits>
40 #include <utility>
41 
42 #include "final/ftypes.h"
43 #include "final/util/fstring.h"
44 
45 namespace finalcut
46 {
47 
48 // class forward declaration
49 class FPoint;
50 
51 //----------------------------------------------------------------------
52 // class FSize
53 //----------------------------------------------------------------------
54 
55 class FSize
56 {
57  public:
58  // Using-declarations
59  using size_type = std::size_t;
60  using size_reference = size_type&;
61  using area_type = std::size_t;
62 
63  // Constructors
64  constexpr FSize () noexcept = default;
65 
66  template<typename WidthT, typename HeightT
67  , typename = std::enable_if_t< std::is_arithmetic<WidthT>::value
68  && std::is_arithmetic<HeightT>::value >>
69  constexpr FSize (WidthT, HeightT) noexcept;
70 
71  // Copy constructor
72  constexpr FSize (const FSize&) noexcept = default;
73 
74  // Move constructor
75  constexpr FSize (FSize&&) noexcept = default;
76 
77  // Destructor
78  ~FSize() noexcept = default;
79 
80  // Copy assignment operator (=)
81  constexpr auto operator = (const FSize&) noexcept -> FSize& = default;
82 
83  // Move assignment operator (=)
84  constexpr auto operator = (FSize&&) noexcept -> FSize& = default;
85 
86  // Overloaded operators
87  auto operator += (const FSize&) noexcept -> FSize&;
88  auto operator -= (const FSize&) noexcept -> FSize&;
89 
90  // Accessors
91  auto getClassName() const -> FString;
92  constexpr auto getWidth() const noexcept -> size_type;
93  constexpr auto getHeight() const noexcept -> size_type;
94  constexpr auto getArea() const noexcept -> area_type;
95 
96  // Mutators
97  constexpr void setWidth (size_type) noexcept;
98  constexpr void setHeight (size_type) noexcept;
99  constexpr void setSize (const FSize&) noexcept;
100  constexpr void setSize (size_type, size_type) noexcept;
101 
102  // Predicate
103  constexpr auto isEmpty() const noexcept -> bool;
104 
105  // Side references
106  constexpr auto width_ref() & noexcept -> size_reference;
107  constexpr auto height_ref() & noexcept -> size_reference;
108 
109  // Methods
110  void scaleBy (int, int) noexcept;
111  void scaleBy (const FPoint&) noexcept;
112  constexpr void swap (FSize&) noexcept;
113 
114  private:
115  // Data members
116  size_type width{0};
117  size_type height{0};
118 
119  // Friend operator functions
120  friend constexpr auto operator < (const FSize& s1, const FSize& s2) -> bool
121  {
122  return s1.width < s2.width && s1.height < s2.height;
123  }
124 
125  friend constexpr auto operator <= (const FSize& s1, const FSize& s2) -> bool
126  {
127  return s1.width <= s2.width && s1.height <= s2.height;
128  }
129 
130  friend constexpr auto operator == (const FSize& s1, const FSize& s2) -> bool
131  {
132  return s1.width == s2.width && s1.height == s2.height;
133  }
134 
135  friend constexpr auto operator != (const FSize& s1, const FSize& s2) -> bool
136  {
137  return s1.width != s2.width || s1.height != s2.height;
138  }
139 
140  friend constexpr auto operator >= (const FSize& s1, const FSize& s2) -> bool
141  {
142  return s1.width >= s2.width && s1.height >= s2.height;
143  }
144 
145  friend constexpr auto operator > (const FSize& s1, const FSize& s2) -> bool
146  {
147  return s1.width > s2.width && s1.height > s2.height;
148  }
149 
150  friend constexpr auto operator + (const FSize& s1, const FSize& s2) -> FSize
151  {
152  constexpr size_type max = std::numeric_limits<size_type>::max();
153  const size_type w = ( s1.width < max - s2.width) ? s1.width + s2.width : max;
154  const size_type h = ( s1.height < max - s2.height) ? s1.height + s2.height : max;
155  return { FSize{w, h} };
156  }
157 
158  friend constexpr auto operator - (const FSize& s1, const FSize& s2) -> FSize
159  {
160  const size_type w = ( s1.width >= s2.width ) ? s1.width - s2.width : 0;
161  const size_type h = ( s1.height >= s2.height ) ? s1.height - s2.height : 0;
162  return { FSize{w, h} };
163  }
164 
165  friend inline auto operator << (std::ostream& outstr, const FSize& s) -> std::ostream&
166  {
167  outstr << s.width << " " << s.height;
168  return outstr;
169  }
170 
171  friend inline auto operator >> (std::istream& instr, FSize& s) -> std::istream&
172  {
173  size_type w{};
174  size_type h{};
175 
176  if ( instr >> w >> h )
177  s.setSize (w, h);
178 
179  return instr;
180  }
181 };
182 
183 // FSize inline functions
184 //----------------------------------------------------------------------
185 template<typename WidthT, typename HeightT, typename>
186 constexpr FSize::FSize (WidthT w, HeightT h) noexcept
187  : width{static_cast<size_type>(w > 0 ? w : 0)}
188  , height{static_cast<size_type>(h > 0 ? h : 0)}
189 { }
190 
191 //----------------------------------------------------------------------
192 inline auto FSize::getClassName() const -> FString
193 { return "FSize"; }
194 
195 //----------------------------------------------------------------------
196 constexpr auto FSize::getWidth() const noexcept -> size_type
197 { return width; }
198 
199 //----------------------------------------------------------------------
200 constexpr auto FSize::getHeight() const noexcept -> size_type
201 { return height; }
202 
203 //----------------------------------------------------------------------
204 constexpr auto FSize::getArea() const noexcept -> area_type
205 { return width * height; }
206 
207 //----------------------------------------------------------------------
208 constexpr void FSize::setWidth (size_type w) noexcept
209 { width = w; }
210 
211 //----------------------------------------------------------------------
212 constexpr void FSize::setHeight (size_type h) noexcept
213 { height = h; }
214 
215 //----------------------------------------------------------------------
216 constexpr void FSize::setSize (const FSize& s) noexcept
217 {
218  width = s.width;
219  height = s.height;
220 }
221 
222 //----------------------------------------------------------------------
223 constexpr void FSize::setSize (size_type w, size_type h) noexcept
224 {
225  width = w;
226  height = h;
227 }
228 
229 //----------------------------------------------------------------------
230 constexpr auto FSize::isEmpty() const noexcept -> bool
231 { return width == 0 && height == 0; }
232 
233 //----------------------------------------------------------------------
234 constexpr auto FSize::width_ref() & noexcept -> size_reference
235 { return width; }
236 
237 //----------------------------------------------------------------------
238 constexpr auto FSize::height_ref() & noexcept -> size_reference
239 { return height; }
240 
241 //----------------------------------------------------------------------
242 constexpr void FSize::swap (FSize& s) noexcept
243 {
244  size_type tmp_width{width};
245  size_type tmp_height{height};
246  width = s.width;
247  height = s.height;
248  s.width = tmp_width;
249  s.height = tmp_height;
250 }
251 
252 } // namespace finalcut
253 
254 #endif // FSIZE_H
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fsize.h:55
Definition: fstring.h:82