Gorgon Game Engine
Size.h
Go to the documentation of this file.
1 
3 #pragma once
4 
5 #include <iostream>
6 #include <ostream>
7 #include <string>
8 #include <iomanip>
9 #include <limits>
10 #include <sstream>
11 
12 #include "../Types.h"
13 #include "Point.h"
14 #include "../String.h"
15 
16 #include <ctype.h>
17 
18 namespace Gorgon { namespace Geometry {
19 
22  template<class T_>
23  class basic_Size {
24  public:
26  typedef T_ BaseType;
27 
30  basic_Size() { }
31 
34  explicit basic_Size(const T_ &s) : Width(s), Height(s) { }
35 
37  basic_Size(const T_ &w, const T_ &h) : Width(w), Height(h) { }
38 
41  template <class O_>
42  basic_Size(const basic_Size<O_> &size) : Width((T_)size.Width), Height((T_)size.Height) { }
43 
46  explicit basic_Size(const basic_Point<T_> &point) : Width((T_)point.X), Height((T_)point.Y) { }
47 
49  explicit basic_Size(const std::string &str) {
50  auto s=str.begin();
51 
52  if(s == str.end())
53  Width = Height = 0;
54 
55  while(s != str.end() && (*s==' ' || *s=='\t')) s++;
56 
57  if(s == str.end())
58  Width = Height = 0;
59 
60  auto pos = str.find_first_of('x', s-str.begin());
61  if(pos != str.npos)
62  Width=String::To<T_>(str.substr(s-str.begin(), pos-(s-str.begin())));
63  else
64  Width=String::To<T_>(&str[s-str.begin()]);
65 
66  while(s!=str.end() && *s!='x' && *s!=',') s++;
67 
68  if(s != str.end()) {
69  if(*s=='x' || *s==',') s++;
70 
71  Height = String::To<T_>(&str[s-str.begin()]);
72  }
73  }
74 
75 
77  explicit operator std::string() const {
78  std::string ret;
79  ret += String::From(Width);
80  ret.push_back('x');
81  ret += String::From(Height);
82 
83  return ret;
84  }
85 
86 
95  static basic_Size Parse(const std::string &str) {
96  basic_Size sz;
97 
98  auto s=str.begin();
99 
100  if(s==str.end()) {
101  throw String::IllegalTokenError(s-str.begin(), 121002, "Unexpected end of input");
102  }
103 
104  while(*s==' ' || *s=='\t') s++;
105 
106  char *endptr;
107  sz.Width = T_(strtod(&*s, &endptr));
108  if(endptr==&*s) {
109  throw String::IllegalTokenError(0, 120001);
110  }
111  s+=endptr-&*s;
112 
113  while(s!=str.end() && isspace(*s)) s++;
114  if(s==str.end()) {
115  throw String::IllegalTokenError(s-str.begin(), 121002, "Unexpected end of input");
116  }
117  if(*s!='x') {
118  throw String::IllegalTokenError(s-str.begin(), 121002, std::string("Illegal token: ")+*s);
119  }
120  s++;
121 
122  if(s==str.end()) {
123  throw String::IllegalTokenError(s-str.begin(), 121002, "Unexpected end of input");
124  }
125 
126  sz.Height=T_(strtod(&*s, &endptr));
127  if(endptr==&*s) {
128  throw String::IllegalTokenError(s-str.begin(), 121003);
129  }
130  s+=endptr-&*s;
131 
132  if(s==str.end()) return sz;
133 
134  //eat white space + a single )
135  while(s!=str.end() && isspace(*s)) s++;
136 
137  if(s!=str.end()) {
138  throw String::IllegalTokenError(s-str.begin(), 121004, std::string("Illegal token: ")+*s);
139  }
140 
141  return sz;
142  }
143 
145  template <class O_>
147  Width=size.Width;
148  Height=size.Height;
149 
150  return *this;
151  }
152 
155  template <class O_>
157  Width=point.X;
158  Height=point.Y;
159 
160  return *this;
161  }
162 
164  bool operator ==(const basic_Size &size) const {
165  return Width==size.Width && Height==size.Height;
166  }
167 
169  bool operator !=(const basic_Size &size) const {
170  return Width!=size.Width || Height!=size.Height;
171  }
172 
174  template<class O_>
175  basic_Size operator +(const basic_Size<O_> &size) const {
176  return basic_Size(size.Width+Width, size.Height+Height);
177  }
178 
180  template<class O_>
181  basic_Size operator -(const basic_Size<O_> &size) const {
182  return basic_Size(Width-size.Width, Height-size.Height);
183  }
184 
187  return{-Width, -Height};
188  }
189 
191  template<class O_>
193  Width=size.Width +Width;
194  Height=size.Height+Height;
195 
196  return *this;
197  }
198 
200  template<class O_>
202  Width=Width-size.Width;
203  Height=Height-size.Height;
204 
205  return *this;
206  }
207 
209  template<class _S>
211  Width =T_(size *Width);
212  Height=T_(size*Height);
213 
214  return *this;
215  }
216 
218  template<class _S>
220  Width =T_(Width/size);
221  Height=T_(Height/size);
222 
223  return *this;
224  }
225 
229  explicit operator basic_Point<T_>() const {
230  return{Width, Height};
231  }
232 
235  T_ Cells() const {
236  return T_(std::floor(Width)*std::floor(Height));
237  }
238 
240  T_ Area() const {
241  return Width*Height;
242  }
243 
245  bool IsValid() const {
246  return Width>=0 && Height>=0;
247  }
248 
251  static basic_Size Max() {
252  static_assert(std::numeric_limits<T_>::is_specialized, "Max function can only be used with "
253  "arithmetic types that have numeric_limits specialized");
254  return {std::numeric_limits<T_>::max(), std::numeric_limits<T_>::max()};
255  }
256 
258  T_ Width;
259 
261  T_ Height;
262  };
263 
265  template<class T_>
266  basic_Size<T_> operator *(const basic_Size<T_> &size, double factor) {
267  return{T_(size.Width*factor), T_(size.Height*factor)};
268  }
269 
271  template<class T_>
272  basic_Size<T_> operator *(double factor, const basic_Size<T_> &size) {
273  return operator*(size, factor);
274  }
275 
277  template<class T_>
278  basic_Size<T_> operator /(const basic_Size<T_> &size, double factor) {
279  return{T_(size.Width/factor), T_(size.Height/factor)};
280  }
281 
283  template<class T_>
284  basic_Size<T_> operator /(double factor, const basic_Size<T_> &size) {
285  return operator/(size, factor);
286  }
287 
290  template<class T_>
291  static std::ostream &operator <<(std::ostream &out, const basic_Size<T_> &size) {
292  out<<size.Width<<"x"<<size.Height;
293 
294  return out;
295  }
296 
299  template <class T_>
300  std::istream &operator >> (std::istream &in, basic_Size<T_> &size) {
301  while(in.peek()==' ' || in.peek()=='\t')
302  in.ignore(1);
303 
304  std::string s;
305 
306  while(in.peek()!='x' && !in.eof())
307  s.append(1, (char)in.get());
308 
309  if(in.eof()) {
310  in.setstate(in.failbit);
311  return in;
312  }
313  in.ignore(1);
314 
315  auto w=String::To<T_>(s);
316 
317  s="";
318 
319  while(in.peek()==' ' || in.peek()=='\t')
320  in.ignore(1);
321 
322  while(in.peek()!=' ' && in.peek()!='\t' && in.peek()!='\n' && in.peek()!='\r' && !in.eof())
323  s.append(1, in.get());
324 
325  size.Width=w;
326  size.Height=String::To<T_>(s);
327 
328  return in;
329  }
330 
332  template<class T_, class O_>
333  auto operator *(const basic_Point<T_> &l, const basic_Size<O_> &r) -> basic_Point<decltype(l.X*r.Width)> {
334  return{l.X*r.Width, l.Y*r.Height};
335  }
336 
338  template<class T_, class O_>
339  auto operator /(const basic_Point<T_> &l, const basic_Size<O_> &r) -> basic_Point<decltype(l.X*r.Width)> {
340  return{l.X/r.Width, l.Y/r.Height};
341  }
342 
344  template <class T_, class O_>
345  void Scale(basic_Point<T_> &point, const basic_Size<O_> &size) {
346  point.X = T_(point.X*size.Width);
347  point.Y = T_(point.Y*size.Height);
348  }
349 
351  template <class T_, class O_>
352  void Scale(basic_Size<T_> &l, const O_ &size) {
353  l.Width = T_(l.Width*size);
354  l.Height = T_(l.Height*size);
355  }
356 
358  template <class T_, class O1_, class O2_>
359  void Scale(basic_Size<T_> &l, const O1_ &sizex, const O2_ &sizey) {
360  l.Width = T_(l.Width*sizex);
361  l.Height = T_(l.Height*sizey);
362  }
363 
365  template <class T_, class O_>
366  void Scale(basic_Size<T_> &l, const basic_Size<O_> &size) {
367  l.Width = T_(l.Width*size.Width);
368  l.Height = T_(l.Height*size.Height);
369  }
370 
372  template <class T_>
374  return {std::min(l.Width, r.Width), std::min(l.Height, r.Height)};
375  }
376 
378  template <class T_>
380  return {std::max(l.Width, r.Width), std::max(l.Height, r.Height)};
381  }
382 
383 
386 
389 
390 } }
Gorgon::Geometry::basic_Size::operator!=
bool operator!=(const basic_Size &size) const
Compares two size objects.
Definition: Size.h:169
Gorgon::Geometry::basic_Size::basic_Size
basic_Size(const T_ &s)
Filling constructor.
Definition: Size.h:34
Gorgon::Geometry::basic_Size::operator+
basic_Size operator+(const basic_Size< O_ > &size) const
Adds two size objects.
Definition: Size.h:175
Gorgon::String::From
std::enable_if< decltype(gorgon__enum_tr_loc(T_()))::isupgradedenum, std::string >::type From(const T_ &e)
Definition: Enum.h:303
Gorgon::Geometry::basic_Size::basic_Size
basic_Size(const std::string &str)
Conversion from string.
Definition: Size.h:49
Gorgon::Containers::Hashmap::GetCount
long GetCount() const
Returns the number of elements in the map.
Definition: Hashmap.h:375
Point.h
contains point class.
Gorgon::Geometry::init_scripting
void init_scripting()
Definition: Scripting.cpp:13
Gorgon::Geometry::operator/
basic_Size< T_ > operator/(const basic_Size< T_ > &size, double factor)
Divides a size with a scalar, effectively resizing it.
Definition: Size.h:278
Gorgon::Geometry::basic_Point::X
T_ X
X coordinate.
Definition: Point.h:368
Reflection.h
Gorgon::Geometry::basic_Size::IsValid
bool IsValid() const
Returns whether the size is valid, i.e. both dimensions are positive.
Definition: Size.h:245
Gorgon::Geometry::basic_Size::Height
T_ Height
Height of this size object.
Definition: Size.h:261
Gorgon::Geometry::LibGeometry
Scripting::Library LibGeometry("Geometry", "Data types under geometry module and their member functions and operators")
Gorgon::Geometry::basic_Point::Move
void Move(const T_ &x, const T_ &y)
Moves this point to the given coordinates.
Definition: Point.h:360
Gorgon::Geometry::basic_Point::Angle
Float Angle(const basic_Point &origin) const
Calculates the angle of the line formed from the given point to this point.
Definition: Point.h:320
Embedding.h
Gorgon::Scripting::Namespace::Members
const StaticMemberList & Members
List of static members.
Definition: Reflection.h:1148
Gorgon::Float
float Float
Represents floating point data type.
Definition: Types.h:16
Gorgon::Geometry::operator>>
std::istream & operator>>(std::istream &in, basic_Bounds< T_ > &bounds)
Stream extractor for bounds.
Definition: Bounds.h:423
Gorgon::Geometry::basic_Size::operator+=
basic_Size & operator+=(const basic_Size< O_ > &size)
Adds the given size object to this size.
Definition: Size.h:192
Gorgon::Geometry::Scale
void Scale(basic_Bounds< T_ > &bounds, const O_ &size)
Scales the given bounds by the given factor. Center of the bounds is used as origin.
Definition: Bounds.h:544
Gorgon::Geometry::basic_Size::operator*=
basic_Size operator*=(_S size)
Multiplies this size object with the given factor.
Definition: Size.h:210
Gorgon::String::IllegalTokenError
This error will be thrown if a parsing function encounters with an illegal token.
Definition: Exceptions.h:25
Gorgon::Input::Keyboard::Keycodes::X
constexpr Key X
Definition: Keyboard.h:103
Gorgon::Geometry::Union
basic_Bounds< T_ > Union(const basic_Bounds< T_ > &l, const basic_Bounds< T_ > &r)
Returns the smallest bounds that contains given bounds.
Definition: Bounds.h:488
Gorgon::Scripting::MappedOperator
This class makes working with operators easier.
Definition: Embedding.h:635
Gorgon::Graphics::internal::isspace
bool isspace(Glyph g)
Definition: Font.cpp:96
Gorgon::Geometry::basic_Size::Max
static basic_Size Max()
Returns the maximum representable size.
Definition: Size.h:251
Gorgon::Geometry::basic_Size::basic_Size
basic_Size(const T_ &w, const T_ &h)
Filling constructor.
Definition: Size.h:37
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Geometry::basic_Size
This class represents a 2D geometric size.
Definition: Size.h:23
Gorgon::Scripting::Library
This class represents a library.
Definition: Reflection.h:1596
Gorgon::Geometry::basic_Size::operator=
basic_Size & operator=(const basic_Size< O_ > &size)
Converting assignment operator.
Definition: Size.h:146
Gorgon::Geometry::basic_Size::basic_Size
basic_Size()
Default constructor.
Definition: Size.h:30
Gorgon::Geometry::basic_Size::basic_Size
basic_Size(const basic_Size< O_ > &size)
Converting constructor.
Definition: Size.h:42
Gorgon::Geometry::basic_Size::operator-
basic_Size operator-() const
Negation operator.
Definition: Size.h:186
Gorgon::Geometry::Point
basic_Point< int > Point
Definition: Point.h:598
VirtualMachine.h
Gorgon::Geometry::basic_Size::Cells
T_ Cells() const
Returns the number of fully encompassed cells.
Definition: Size.h:235
Gorgon::Geometry::basic_Size::BaseType
T_ BaseType
Base type of the size elements.
Definition: Size.h:26
Gorgon::Geometry::basic_Point::Distance
Float Distance(const basic_Point &target) const
Calculates Euclidean distance from this point to the given target.
Definition: Point.h:276
Gorgon::Geometry::Combine
basic_Size< T_ > Combine(const basic_Size< T_ > &l, const basic_Size< T_ > &r)
Returns the minimum required size that can hold both size objects.
Definition: Size.h:379
Gorgon::Geometry::basic_Point
This class represents a 2D point.
Definition: Point.h:32
Gorgon::Scripting::ConstTag
@ ConstTag
Marks a parameter or a function constant.
Definition: Reflection.h:95
Gorgon::Scripting::MappedInstanceMember
This class allows a one to one mapping of a data member to a c++ data member.
Definition: Embedding.h:951
Gorgon::Scripting::MappedValueType
This class allows embedded types to become scripting types that are passed around as values.
Definition: Embedding.h:1300
Gorgon::Geometry::basic_Size::operator==
bool operator==(const basic_Size &size) const
Compares two size objects.
Definition: Size.h:164
Gorgon::Geometry::operator*
basic_Size< T_ > operator*(const basic_Size< T_ > &size, double factor)
Multiplies a size with a scalar, effectively resizing it.
Definition: Size.h:266
Gorgon::Scripting::KeywordNames
std::set< std::string, String::CaseInsensitiveLess > KeywordNames
Definition: Scripting.cpp:13
Gorgon::Scripting::Parameter
This class represents a function parameter description.
Definition: Reflection.h:137
Gorgon::Geometry::basic_Size::operator-=
basic_Size & operator-=(const basic_Size< O_ > &size)
Subtracts the given size object from this size.
Definition: Size.h:201
Gorgon::Geometry::basic_Point::ManhattanDistance
Float ManhattanDistance(const basic_Point &target) const
Calculates Manhattan distance from this point to the given target.
Definition: Point.h:297
Gorgon::Geometry::basic_Size::Area
T_ Area() const
Returns the exact area of the rectangle has the size of this object.
Definition: Size.h:240
Gorgon::Geometry::basic_Size::basic_Size
basic_Size(const basic_Point< T_ > &point)
Converts a point to size object.
Definition: Size.h:46
Gorgon::Geometry::basic_Point::Y
T_ Y
Y coordinate.
Definition: Point.h:371
Gorgon::Geometry::operator<<
std::ostream & operator<<(std::ostream &out, const basic_Bounds< T_ > &bounds)
Allows streaming of bounds.
Definition: Bounds.h:415
Gorgon::Scripting::Namespace::AddMember
virtual void AddMember(StaticMember &member)
Adds a new member to this namespace.
Definition: Reflection.h:1088
Gorgon::Geometry::basic_Size::Width
T_ Width
Width of this size object.
Definition: Size.h:258
Gorgon::Scripting::MapFunction
Scripting::Function::Overload * MapFunction(F_ fn, const Type *returntype, ParameterList parameters, P_ ...tags)
Definition: Embedding.h:614
Gorgon::Scripting::Function
Represents a function.
Definition: Reflection.h:557
Gorgon::Geometry::basic_Point::Compare
bool Compare(const basic_Point &point) const
Compares two points.
Definition: Point.h:345
Gorgon::Geometry::basic_Size::operator/=
basic_Size operator/=(_S size)
Divides this size object to the given factor.
Definition: Size.h:219
Gorgon::Geometry::basic_Point::Slope
Float Slope(const basic_Point &point) const
Calculates the slope of the line formed from the given point to this point.
Definition: Point.h:334
Gorgon::Geometry::basic_Size::Parse
static basic_Size Parse(const std::string &str)
Properly parses given string into a size.
Definition: Size.h:95
Gorgon::Input::Keyboard::Keycodes::Y
constexpr Key Y
Definition: Keyboard.h:104