DxLibEx
size.hpp
Go to the documentation of this file.
1 /*=============================================================================
2  Copyright (C) 2015-2017 DxLibEx project
3  https://github.com/Nagarei/DxLibEx/
4 
5  Distributed under the Boost Software License, Version 1.0.
6  (See http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #ifndef DXLE_INC_BASIC_TYPES_SIZE_HPP_
9 #define DXLE_INC_BASIC_TYPES_SIZE_HPP_
18 #include "dxlibex/math.hpp"
19 #include "dxlibex/cstdlib.hpp"
21 //#include "dxlibex/basic_types.hpp"//DO NOT REMOVE COMMENT-OUT to avoid redefine
22 #include <iostream>
23 #include <utility>//std::pair
24 #include <type_traits>
25 #include <algorithm>
26 #include <cmath>
27 #include <limits>
28 #include "dxlibex/config/defines.h"
29 
30 namespace dxle {
31  template<typename T, enable_if_t<std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value, nullptr_t>>
32  class point_c;
33 
99  template<typename T, enable_if_t<std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value, nullptr_t> = nullptr>
100  class size_c final
101  {
102  public:
103  typedef T value_type;
104  value_type width, height;
105  DXLE_CONSTEXPR size_c() DXLE_NOEXCEPT_IF((std::is_nothrow_constructible<value_type>::value)) : width(), height() {}
106  DXLE_CONSTEXPR size_c(const value_type& width_, const value_type& height_) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_constructible<value_type>::value)) : width(width_), height(height_) {}
107  DXLE_CONSTEXPR size_c(value_type&& width_, value_type&& height_) DXLE_NOEXCEPT_OR_NOTHROW : width(std::move(width_)), height(std::move(height_)) {}
108 
112  : width(static_cast<value_type>(other.width)), height(static_cast<value_type>(other.height)) {}
115  template<typename Tp2_> DXLE_CONSTEXPR explicit size_c(size_c<Tp2_>&& other) DXLE_NOEXCEPT_IF((dxle::is_nothrow_convertable<Tp2_&&, value_type>::value))
116  : width(static_cast<value_type>(std::move(other.width))), height(static_cast<value_type>(std::move(other.height))) {}
117  //copy constructor
118  DXLE_CONSTEXPR size_c(const size_c<value_type>& o) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_constructible<value_type>::value)) : width(o.width), height(o.height) {}
119  //move constructor
120  DXLE_CONSTEXPR size_c(size_c<value_type>&& o) DXLE_NOEXCEPT_OR_NOTHROW : width(std::move(o.width)), height(std::move(o.height)) {}
121 
125  : width(static_cast<value_type>(other.x)), height(static_cast<value_type>(other.y)) {}
128  template<typename Tp2_> DXLE_CONSTEXPR explicit size_c(point_c<Tp2_, nullptr>&& other) DXLE_NOEXCEPT_IF((dxle::is_nothrow_convertable<Tp2_&&, value_type>::value))
129  : width(static_cast<value_type>(std::move(other.x))), height(static_cast<value_type>(std::move(other.y))) {}
133  : width(other.x), height(other.y) {}
137  : width(std::move(other.x)), height(std::move(other.y)) {}
138 
139  //copy assignment operator
140  size_c& operator=(const size_c<value_type>& r) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_assignable<value_type>::value))
141  {
142  this->width = r.width;
143  this->height = r.height;
144  return *this;
145  }
146  //move assignment operator
148  {
149  this->width = std::move(r.width);
150  this->height = std::move(r.height);
151  return *this;
152  }
153 
158  DXLE_CONSTEXPR explicit operator bool() const DXLE_NOEXCEPT_IF_EXPR((dxle::detail::operator_bool_helper(std::declval<value_type>(), std::declval<value_type>())))
159  {
160  return dxle::detail::operator_bool_helper(this->width, this->height);
161  }
165  {
166  return{ static_cast<Tp2_>(this->width), static_cast<Tp2_>(this->height) };
167  }
170  template<typename Tp2_> explicit operator std::pair<Tp2_, Tp2_>() const DXLE_NOEXCEPT_IF((dxle::is_nothrow_convertable<value_type, Tp2_>::value))
171  {
172  return std::pair<Tp2_, Tp2_>(static_cast<Tp2_>(this->width), static_cast<Tp2_>(this->height));
173  }
174  };
175  //convert from std::pair
176 
186  template<typename T> size_c<T> make_size_c(const std::pair<T, T>& pa) DXLE_NOEXCEPT_IF(std::is_nothrow_copy_constructible<T>::value)
187  {
188  return size_c<T>(pa.first, pa.second);
189  }
199  template<typename T> size_c<T> make_size_c(std::pair<T, T>&& pa) DXLE_NOEXCEPT_OR_NOTHROW
200  {
201  return size_c<T>(std::move(pa.first), std::move(pa.second));
202  }
203 
204  //ostream operator
205  namespace detail {
206  template<typename CharType, typename Size_cType>
207  void ostream_operator_helper(std::basic_ostream<CharType>& os, const CharType* str, const size_c<Size_cType>& s)
208  {
209  using use_big_type_when_one_byte_p = use_big_type_when_one_byte_t<Size_cType>;
210  os << static_cast<use_big_type_when_one_byte_p>(s.width) << str << static_cast<use_big_type_when_one_byte_p>(s.height);
211  }
212  template<typename CharType, typename Size_cType>
213  void istream_operator_helper(std::basic_istream<CharType>& is, size_c<Size_cType>& s)
214  {
216  is >> width;
217  is.ignore((std::numeric_limits<std::streamsize>::max)(), dxle::char_constant::comma<CharType>());
218  is >> height;
219  s.width = static_cast<Size_cType>(width); s.height = static_cast<Size_cType>(height);
220  }
221  }
233  template<typename T> std::ostream& operator<<(std::ostream& os, const size_c<T>& s)
234  {
235  dxle::detail::ostream_operator_helper<char, T>(os, ", ", s);
236  return os;
237  }
249  template<typename T> std::wostream& operator<<(std::wostream& os, const size_c<T>& s)
250  {
251  dxle::detail::ostream_operator_helper<wchar_t, T>(os, L", ", s);
252  return os;
253  }
265  template<typename T> std::istream& operator>>(std::istream& is, size_c<T>& s)
266  {
267  dxle::detail::istream_operator_helper<char, T>(is, s);
268  return is;
269  }
281  template<typename T> std::wistream& operator>>(std::wistream& is, size_c<T>& s)
282  {
283  dxle::detail::istream_operator_helper<wchar_t, T>(is, s);
284  return is;
285  }
286 
296  template <typename T>
298  {
299  return { -r.width, -r.height };
300  }
301 
311  template <typename T>
312  DXLE_CONSTEXPR inline size_c<T> operator +(const size_c<T>& r) DXLE_NOEXCEPT_IF(std::is_nothrow_copy_constructible<T>::value) { return r; }
313 
323  template <typename T>
325 
337  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
338  size_c<T1>& operator +=(size_c<T1>& l, const size_c<T2>& r) DXLE_NOEXCEPT_IF_EXPR(l.width += r.width)
339  {
340  l.width += r.width;
341  l.height += r.height;
342  return l;
343  }
344 
356  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
357  size_c<T1>& operator -=(size_c<T1>& l, const size_c<T2>& r) DXLE_NOEXCEPT_IF_EXPR(l.width -= r.width)
358  {
359  l.width -= r.width;
360  l.height -= r.height;
361  return l;
362  }
363 
375  template <typename T1, typename T2>
376  DXLE_CONSTEXPR auto operator +(const size_c<T1>& l, const size_c<T2>& r) DXLE_NOEXCEPT_IF_EXPR(l.width + r.width)
377  ->size_c<decltype(std::declval<std::remove_cv_t<T1>>() + std::declval<std::remove_cv_t<T2>>())>
378  {
379  return {l.width + r.width, l.height + r.height};
380  }
381 
393  template <typename T1, typename T2>
394  DXLE_CONSTEXPR auto operator -(const size_c<T1>& l, const size_c<T2>& r) DXLE_NOEXCEPT_IF_EXPR(l.width - r.width)
395  ->size_c<decltype(std::declval<std::remove_cv_t<T1>>() - std::declval<std::remove_cv_t<T2>>())>
396  {
397  return {l.width - r.width, l.height - r.height};
398  }
399 
411  template <typename T1, typename T2>
413  ->size_c<decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())>
414  {
415  return {l.width * r, l.height * r};
416  }
417 
429  template <typename T1, typename T2>
430  DXLE_CONSTEXPR auto operator *(T1 l, const size_c<T2>& r) DXLE_NOEXCEPT_IF_EXPR(l * r.width)
431  ->size_c<decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())>
432  {
433  return {l * r.width, l * r.height};
434  }
435 
447  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
449  {
450  l.width *= r;
451  l.height *= r;
452  return l;
453  }
454 
466  template <typename T1, typename T2>
468  ->size_c<decltype(std::declval<std::remove_cv_t<T1>>() / std::declval<std::remove_cv_t<T2>>())>
469  {
470  return {l.width / r, l.height / r};
471  }
472 
484  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
486  {
487  l.width /= r;
488  l.height /= r;
489  return l;
490  }
491 
503  template <typename T>
504  DXLE_CONSTEXPR bool operator !=(const size_c<T>& l, const size_c<T>& r) DXLE_NOEXCEPT_IF_EXPR(l.width != r.width)
505  {
506  return (l.width != r.width) || (l.height != r.height);
507  }
508 
520  template <typename T>
521  DXLE_CONSTEXPR bool operator ==(const size_c<T>& l, const size_c<T>& r) DXLE_NOEXCEPT_IF_EXPR(l != r) { return !(l != r); }
522 
536  template <typename T>
537  DXLE_CONSTEXPR bool operator !=(const size_c<T>& s, std::nullptr_t) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(s))
538  {
539  return static_cast<bool>(s);
540  }
554  template <typename T>
555  DXLE_CONSTEXPR bool operator !=(std::nullptr_t, const size_c<T>& s) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(s))
556  {
557  return static_cast<bool>(s);
558  }
572  template <typename T>
573  DXLE_CONSTEXPR bool operator ==(const size_c<T>& s, nullptr_t) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(s))
574  {
575  return !static_cast<bool>(s);
576  }
590  template <typename T>
591  DXLE_CONSTEXPR bool operator ==(nullptr_t, const size_c<T>& s) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(s))
592  {
593  return !static_cast<bool>(s);
594  }
595 
609  template<typename T>
610  DXLE_CONSTEXPR size_c<T> abs(const size_c<T>& o) DXLE_NOEXCEPT_IF_EXPR(abs(o.width)) { return { abs(o.width), abs(o.height) }; }
611 
612  typedef size_c<int> sizei;
617 };
618 
619 namespace std
620 {
621  //hash
622 #define DXLE_TEMP_make_hash(int_t, bit, bit2)\
623  template <> struct hash<dxle::size_c<int_t##bit##_t>> {\
624  hash() = default;\
625  hash(const hash&) = default;\
626  hash(hash&& other) :hash_run(std::move(other.hash_run)) {}\
627  ~hash() {}\
628  hash& operator=(const hash& other) { hash_run = other.hash_run; return *this; }\
629  hash& operator=(hash&& other) { hash_run = std::move(other.hash_run); return *this; }\
630  size_t operator()(const dxle::size_c<int_t##bit##_t>& key) const { return hash_run((static_cast<int_t##_fast##bit2##_t>(key.width) << bit) | static_cast<int_t##_fast##bit2##_t>(key.height)); }\
631  private:\
632  std::hash<int_t##_fast##bit2##_t> hash_run;\
633  }
634 
635  DXLE_TEMP_make_hash(int, 8, 16);
636  DXLE_TEMP_make_hash(int, 16, 32);
637  DXLE_TEMP_make_hash(int, 32, 64);
638  DXLE_TEMP_make_hash(uint, 8, 16);
639  DXLE_TEMP_make_hash(uint, 16, 32);
640  DXLE_TEMP_make_hash(uint, 32, 64);
641 
642 #undef DXLE_TEMP_make_hash
643 }
644 
645 #endif //DXLE_INC_BASIC_TYPES_SIZE_HPP_
Template class for 2D sizes specified by its coordinates width and height.
Definition: point2d.hpp:36
DXLE_CONSTEXPR size_c< T > operator-(const size_c< T > &r) DXLE_NOEXCEPT_IF_EXPR(-r.width)
Overload of unary operator -.
Definition: size.hpp:297
#define DXLE_CONSTEXPR
Definition: suffix.hpp:21
DXLE_CONSTEXPR size_c(const point_c< value_type, nullptr > &other) DXLE_NOEXCEPT_IF((dxle
Definition: size.hpp:132
DXLE_CONSTEXPR size_c(point_c< Tp2_, nullptr > &&other) DXLE_NOEXCEPT_IF((dxle
Definition: size.hpp:128
size_c< std::size_t > size
Definition: size.hpp:616
void istream_operator_helper(std::basic_istream< CharType > &is, size_c< Size_cType > &s)
Definition: size.hpp:213
#define DXLE_TEMP_make_hash(int_t, bit, bit2)
Definition: size.hpp:622
size_c< T1 > & operator/=(size_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.width/
Overload of binary operator /=.
DXLE_CONSTEXPR size_c(size_c< value_type > &&o) DXLE_NOEXCEPT_OR_NOTHROW
Definition: size.hpp:120
DXLE_CONSTEXPR int abs(int j) DXLE_NOEXCEPT_OR_NOTHROW
Definition: abs.hpp:22
DXLE_CONSTEXPR bool operator_bool_helper(const T &first, const T &second) DXLE_NOEXCEPT_IF_EXPR(dxle
point_c< T1 > T2 DXLE_CONSTEXPR auto operator/(const point_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.x/r) -> point_c< decltype(std::declval< std::remove_cv_t< T1 >>()/std::declval< std::remove_cv_t< T2 >>())>
Definition: point2d.hpp:464
typename use_big_type_when_one_byte< T >::type use_big_type_when_one_byte_t
for int8_t/uint8_t
std::wistream & operator>>(std::wistream &is, size_c< T > &s)
istream operator
Definition: size.hpp:281
DXLE_CONSTEXPR auto operator*(const size_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.width *r) -> size_c< decltype(std::declval< std::remove_cv_t< T1 >>() *std::declval< std::remove_cv_t< T2 >>())>
Overload of binary operator *.
Definition: size.hpp:412
DXLE_CONSTEXPR size_c(point_c< value_type, nullptr > &&other) DXLE_NOEXCEPT_IF((dxle
Definition: size.hpp:136
DXLE_CONSTEXPR size_c(size_c< Tp2_ > &&other) DXLE_NOEXCEPT_IF((dxle
Definition: size.hpp:115
Definition: point2d.hpp:672
DXLE_CONSTEXPR size_c< T > operator+(const size_c< T > &r) DXLE_NOEXCEPT_IF(std
Overload of unary operator +.
Definition: size.hpp:312
size_c< T1 > & operator+=(size_c< T1 > &l, const size_c< T2 > &r) DXLE_NOEXCEPT_IF_EXPR(l.width+
Overload of binary operator +=.
point_c< T1 > T2
Definition: point2d.hpp:353
Definition: cast_if.hpp:12
size_c & operator=(const size_c< value_type > &r) DXLE_NOEXCEPT_IF((std
Definition: size.hpp:140
DXLE_CONSTEXPR size_c(const point_c< Tp2_, nullptr > &other) DXLE_NOEXCEPT_IF((dxle
Definition: size.hpp:124
size_c< double > sized
Definition: size.hpp:614
DXLE_CONSTEXPR size_c(value_type &&width_, value_type &&height_) DXLE_NOEXCEPT_OR_NOTHROW
Definition: size.hpp:107
value_type width
Definition: size.hpp:104
#define DXLE_NOEXCEPT_IF_EXPR(EXPR)
Definition: suffix.hpp:110
DXLE_CONSTEXPR size_c() DXLE_NOEXCEPT_IF((std
Definition: size.hpp:105
DXLE_CONSTEXPR size_c(const size_c< Tp2_ > &other) DXLE_NOEXCEPT_IF((dxle
Definition: size.hpp:111
size_c & operator=(size_c< value_type > &&r) DXLE_NOEXCEPT_OR_NOTHROW
Definition: size.hpp:147
size_c< T > make_size_c(std::pair< T, T > &&pa) DXLE_NOEXCEPT_OR_NOTHROW
conversion from std::pair
Definition: size.hpp:199
size_c< float > sizef
Definition: size.hpp:615
#define DXLE_NOEXCEPT_IF(COND)
Definition: suffix.hpp:107
size_c< T > make_size_c(const std::pair< T, T > &pa) DXLE_NOEXCEPT_IF(std
conversion from std::pair
Definition: size.hpp:186
#define DXLE_NOEXCEPT_OR_NOTHROW
Definition: suffix.hpp:94
value_type height
Definition: size.hpp:104
DXLE_CONSTEXPR size_c(const value_type &width_, const value_type &height_) DXLE_NOEXCEPT_IF((std
Definition: size.hpp:106
Template class for 2D points specified by its coordinates x and y.
Definition: point2d.hpp:105
std::istream & operator>>(std::istream &is, size_c< T > &s)
istream operator
Definition: size.hpp:265
DXLE_CONSTEXPR size_c(const size_c< value_type > &o) DXLE_NOEXCEPT_IF((std
Definition: size.hpp:118
void ostream_operator_helper(std::basic_ostream< CharType > &os, const CharType *str, const size_c< Size_cType > &s)
Definition: size.hpp:207
T value_type
Definition: size.hpp:103
size_c< unsigned int > sizeui
Definition: size.hpp:613
size_c< T1 > & operator*=(size_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.width *
Overload of binary operator *=.