DxLibEx
point2d.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_POINT2D_HPP_
9 #define DXLE_INC_BASIC_TYPES_POINT2D_HPP_
20 #include "dxlibex/algorithm.hpp"
21 #include "dxlibex/math.hpp"
22 #include "dxlibex/cstdlib.hpp"
24 //#include "dxlibex/basic_types.hpp"//DO NOT REMOVE COMMENT-OUT to avoid redefine
25 #include <iostream>
26 #include <utility>//std::pair
27 #include <type_traits>
28 #include <algorithm>
29 #include <cmath>
30 #include <cstdint>
31 #include <limits>
32 #include "dxlibex/config/defines.h"
33 
34 namespace dxle {
35  template<typename T, enable_if_t<std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value, nullptr_t>>
36  class size_c;
104  template<typename T, enable_if_t<std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value, nullptr_t> = nullptr>
105  class point_c final
106  {
107  public:
108  typedef typename std::remove_cv<T>::type value_type;
109  value_type x, y;
110  DXLE_CONSTEXPR point_c() DXLE_NOEXCEPT_IF((std::is_nothrow_constructible<value_type>::value)) : x(), y() {}
111  DXLE_CONSTEXPR point_c(const value_type& x_, const value_type& y_) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_constructible<value_type>::value)) : x(x_), y(y_) {}
112  DXLE_CONSTEXPR point_c(value_type&& x_, value_type&& y_) DXLE_NOEXCEPT_OR_NOTHROW : x(std::move(x_)), y(std::move(y_)) {}
113 
116  template<typename Tp2_> DXLE_CONSTEXPR explicit point_c(const point_c<Tp2_>& other) DXLE_NOEXCEPT_IF((dxle::is_nothrow_convertable<Tp2_, value_type>::value)) : x(static_cast<value_type>(other.x)), y(static_cast<value_type>(other.y)){}
119  template<typename Tp2_> DXLE_CONSTEXPR explicit point_c(point_c<Tp2_>&& other) DXLE_NOEXCEPT_IF((dxle::is_nothrow_convertable<Tp2_&&, value_type>::value)) : x(static_cast<value_type>(std::move(other.x))), y(static_cast<value_type>(std::move(other.y))) {}
120 
121  //copy constructor
122  DXLE_CONSTEXPR point_c(const point_c<value_type>& o) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_constructible<value_type>::value)) : x(o.x), y(o.y) {}
123  //move constructor
125  : x(std::move(o.x)), y(std::move(o.y)) {}
126 
130  : x(static_cast<value_type>(other.width)), y(static_cast<value_type>(other.height)) {}
133  template<typename Tp2_> DXLE_CONSTEXPR explicit point_c(size_c<Tp2_, nullptr>&& other) DXLE_NOEXCEPT_IF((dxle::is_nothrow_convertable<Tp2_&&, value_type>::value))
134  : x(static_cast<value_type>(std::move(other.width))), y(static_cast<value_type>(std::move(other.height))) {}
138  : x(other.width), y(other.height) {}
142  : x(std::move(other.width)), y(std::move(other.height)) {}
143 
144  //copy assignment operator
145  point_c& operator=(const point_c<value_type>& r) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_assignable<value_type>::value))
146  {
147  this->x = r.x;
148  this->y = r.y;
149  return *this;
150  }
151  //move assignment operator
153  {
154  this->x = std::move(r.x);
155  this->y = std::move(r.y);
156  return *this;
157  }
162  DXLE_CONSTEXPR explicit operator bool() const DXLE_NOEXCEPT_IF_EXPR((dxle::detail::operator_bool_helper(std::declval<value_type>(), std::declval<value_type>()))){
163  return dxle::detail::operator_bool_helper(this->x, this->y);
164  }
167  template<typename Tp2_> explicit operator std::pair<Tp2_, Tp2_>() const DXLE_NOEXCEPT_IF((dxle::is_nothrow_convertable<value_type, Tp2_>::value))
168  {
169  return std::pair<Tp2_, Tp2_>(static_cast<Tp2_>(this->x), static_cast<Tp2_>(this->y));
170  }
171  };
172  //convert from std::pair
173 
183  template<typename T> point_c<T> make_point_c(const std::pair<T, T>& pa) DXLE_NOEXCEPT_IF(std::is_nothrow_copy_constructible<T>::value)
184  {
185  return point_c<T>(pa.first, pa.second);
186  }
196  template<typename T> point_c<T> make_point_c(std::pair<T, T>&& pa) DXLE_NOEXCEPT_OR_NOTHROW
197  {
198  return point_c<T>(std::move(pa.first), std::move(pa.second));
199  }
200 
201  //ostream operator
202  namespace detail {
203  template<typename CharType, typename PointType>
204  void ostream_operator_helper(std::basic_ostream<CharType>& os, const CharType* str, const point_c<PointType>& p)
205  {
206  using use_big_type_when_one_byte_p = use_big_type_when_one_byte_t<PointType>;
207  os << static_cast<use_big_type_when_one_byte_p>(p.x) << str << static_cast<use_big_type_when_one_byte_p>(p.y);
208  }
209  template<typename CharType, typename PointType>
210  void istream_operator_helper(std::basic_istream<CharType>& is, point_c<PointType>& p)
211  {
213  is >> x;
214  is.ignore((std::numeric_limits<std::streamsize>::max)(), dxle::char_constant::comma<CharType>());
215  is >> y;
216  p.x = static_cast<PointType>(x); p.y = static_cast<PointType>(y);
217  }
218  }
230  template<typename T> std::ostream& operator<<(std::ostream& os, const point_c<T>& p)
231  {
232  dxle::detail::ostream_operator_helper<char, T>(os, ", ", p);
233  return os;
234  }
246  template<typename T> std::wostream& operator<<(std::wostream& os, const point_c<T>& p)
247  {
248  dxle::detail::ostream_operator_helper<wchar_t, T>(os, L", ", p);
249  return os;
250  }
262  template<typename T> std::istream& operator>>(std::istream& is, point_c<T>& p)
263  {
264  dxle::detail::istream_operator_helper<char, T>(is, p);
265  return is;
266  }
278  template<typename T> std::wistream& operator>>(std::wistream& is, point_c<T>& p)
279  {
280  dxle::detail::istream_operator_helper<wchar_t, T>(is, p);
281  return is;
282  }
283 
293  template <typename T>
295  {
296  return { -r.x, -r.y };
297  }
298 
308  template <typename T>
309  DXLE_CONSTEXPR inline point_c<T> operator +(const point_c<T>& r) DXLE_NOEXCEPT_IF(std::is_nothrow_copy_constructible<T>::value) { return r; }
310 
320  template <typename T>
322 
334  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
336  {
337  l.x += r.x;
338  l.y += r.y;
339  return l;
340  }
341 
353  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
354  point_c<T1>& operator -=(point_c<T1>& l, const point_c<T2>& r) DXLE_NOEXCEPT_IF_EXPR(l.x -= r.x)
355  {
356  l.x -= r.x;
357  l.y -= r.y;
358  return l;
359  }
360 
372  template <typename T1, typename T2>
374  ->point_c<decltype(std::declval<std::remove_cv_t<T1>>() + std::declval<std::remove_cv_t<T2>>())>
375  {
376  return {l.x + r.x, l.y + r.y};
377  }
378 
390  template <typename T1, typename T2>
392  ->point_c<decltype(std::declval<std::remove_cv_t<T1>>() - std::declval<std::remove_cv_t<T2>>())>
393  {
394  return {l.x - r.x, l.y - r.y};
395  }
396 
408  template <typename T1, typename T2>
410  ->point_c<decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())>
411  {
412  return {l.x * r, l.y * r};
413  }
414 
426  template <typename T1, typename T2>
428  ->point_c<decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())>
429  {
430  return {l * r.x, l * r.y};
431  }
432 
444  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
446  {
447  l.x *= r;
448  l.y *= r;
449  return l;
450  }
451 
463  template <typename T1, typename T2>
465  ->point_c<decltype(std::declval<std::remove_cv_t<T1>>() / std::declval<std::remove_cv_t<T2>>())>
466  {
467  return {l.x / r, l.y / r};
468  }
469 
481  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
483  {
484  l.x /= r;
485  l.y /= r;
486  return l;
487  }
488 
500  template <typename T>
501  DXLE_CONSTEXPR bool operator !=(const point_c<T>& l, const point_c<T>& r) DXLE_NOEXCEPT_IF_EXPR(l.x != r.x)
502  {
503  return (l.x != r.x) || (l.y != r.y);
504  }
505 
517  template <typename T>
518  DXLE_CONSTEXPR bool operator ==(const point_c<T>& l, const point_c<T>& r) DXLE_NOEXCEPT_IF_EXPR(l.x != r.x) { return !(l != r); }
519 
533  template <typename T>
534  DXLE_CONSTEXPR bool operator !=(const point_c<T>& p, std::nullptr_t) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
535  {
536  return static_cast<bool>(p);
537  }
551  template <typename T>
552  DXLE_CONSTEXPR bool operator !=(std::nullptr_t, const point_c<T>& p) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
553  {
554  return static_cast<bool>(p);
555  }
569  template <typename T>
570  DXLE_CONSTEXPR bool operator ==(const point_c<T>& p, nullptr_t) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
571  {
572  return !static_cast<bool>(p);
573  }
587  template <typename T>
588  DXLE_CONSTEXPR bool operator ==(nullptr_t, const point_c<T>& p) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
589  {
590  return !static_cast<bool>(p);
591  }
592 
606  template<typename T>
607  DXLE_CONSTEXPR point_c<T> abs(const point_c<T>& o) DXLE_NOEXCEPT_IF_EXPR(abs(o.x)) { return{ abs(o.x), abs(o.y) }; }
608 
609 
621  template<typename T1, typename T2>
622  DXLE_CONSTEXPR auto dot(const point_c<T1>& p1, const point_c<T2>& p2) DXLE_NOEXCEPT_IF_EXPR(p1.x * p2.x + p1.y * p2.y)
623  ->decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())
624  {
625  return p1.x * p2.x + p1.y * p2.y;
626  }
627 
639  template<typename T1, typename T2>
640  DXLE_CONSTEXPR double cross(const point_c<T1>& p1, const point_c<T2>& p2)
642  static_cast_if<T1, double, !std::is_floating_point<T1>::value>(std::declval<T1>()) * std::declval<T2>()
643  + static_cast_if<T1, double, !std::is_floating_point<T1>::value>(std::declval<T1>()) * std::declval<T2>()
644  ))
645  {
646  return static_cast_if<T1, double, !std::is_floating_point<T1>::value>(p1.x) * p2.y + static_cast_if<T1, double, !std::is_floating_point<T1>::value>(p1.y) * p2.x;
647  }
659  template<typename T1, typename T2>
661  DXLE_NOEXCEPT_IF_EXPR(hypot(safe_dist(std::declval<T1>(), std::declval<T2>()), safe_dist(std::declval<T1>(), std::declval<T2>())))
662  {
663  return hypot(safe_dist(p1.x, p2.x), safe_dist(p1.y, p2.y));
664  }
670 };
671 
672 namespace std
673 {
674  //hash
675 #define DXLE_TEMP_make_hash(int_t, bit, bit2)\
676  template <> struct hash<dxle::point_c<int_t##bit##_t>> {\
677  hash() = default;\
678  hash(const hash&) = default;\
679  hash(hash&& other) :hash_run(std::move(other.hash_run)) {}\
680  ~hash() {}\
681  hash& operator=(const hash& other) { hash_run = other.hash_run; return *this; }\
682  hash& operator=(hash&& other) { hash_run = std::move(other.hash_run); return *this; }\
683  size_t operator()(const dxle::point_c<int_t##bit##_t>& key) const { return hash_run((static_cast<int_t##_fast##bit2##_t>(key.x) << bit) | static_cast<int_t##_fast##bit2##_t>(key.y)); }\
684  private:\
685  std::hash<int_t##_fast##bit2##_t> hash_run;\
686  }
687 
688  DXLE_TEMP_make_hash(int, 8, 16);
689  DXLE_TEMP_make_hash(int, 16, 32);
690  DXLE_TEMP_make_hash(int, 32, 64);
691  DXLE_TEMP_make_hash(uint, 8, 16);
692  DXLE_TEMP_make_hash(uint, 16, 32);
693  DXLE_TEMP_make_hash(uint, 32, 64);
694 
695 #undef DXLE_TEMP_make_hash
696 }
697 
698 #endif //DXLE_INC_BASIC_TYPES_POINT2D_HPP_
DXLE_CONSTEXPR point_c() DXLE_NOEXCEPT_IF((std
Definition: point2d.hpp:110
DXLE_CONSTEXPR point_c(size_c< value_type, nullptr > &&other) DXLE_NOEXCEPT_IF((dxle
Definition: point2d.hpp:141
Template class for 2D sizes specified by its coordinates width and height.
Definition: point2d.hpp:36
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 >>())>
Overload of binary operator *.
Definition: point2d.hpp:409
#define DXLE_CONSTEXPR
Definition: suffix.hpp:21
DXLE_CONSTEXPR point_c(const point_c< Tp2_ > &other) DXLE_NOEXCEPT_IF((dxle
Definition: point2d.hpp:116
point_c< T1 > T2 DXLE_CONSTEXPR auto dot(const point_c< T1 > &p1, const point_c< T2 > &p2) DXLE_NOEXCEPT_IF_EXPR(p1.x *p2.x+p1.y *p2.y) -> decltype(std::declval< std::remove_cv_t< T1 >>() *std::declval< std::remove_cv_t< T2 >>())
Definition: point2d.hpp:622
point_c< T1 > & operator/=(point_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.x/
Overload of binary operator /=.
DXLE_CONSTEXPR point_c(const value_type &x_, const value_type &y_) DXLE_NOEXCEPT_IF((std
Definition: point2d.hpp:111
point_c< T > make_point_c(std::pair< T, T > &&pa) DXLE_NOEXCEPT_OR_NOTHROW
conversion from std::pair
Definition: point2d.hpp:196
std::wistream & operator>>(std::wistream &is, point_c< T > &p)
istream operator
Definition: point2d.hpp:278
DXLE_CONSTEXPR int abs(int j) DXLE_NOEXCEPT_OR_NOTHROW
Definition: abs.hpp:22
DXLE_CONSTEXPR point_c(point_c< Tp2_ > &&other) DXLE_NOEXCEPT_IF((dxle
Definition: point2d.hpp:119
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
DXLE_CONSTEXPR point_c(value_type &&x_, value_type &&y_) DXLE_NOEXCEPT_OR_NOTHROW
Definition: point2d.hpp:112
distance_result_type_t< T1, T2 > distance(const point_c< T1 > &p1, const point_c< T2 > &p2) DXLE_NOEXCEPT_IF_EXPR(hypot(safe_dist(std
Calculate the distance of the two point_c class object based on the Pythagorean theorem(std::hypot) ...
Definition: point2d.hpp:660
typename use_big_type_when_one_byte< T >::type use_big_type_when_one_byte_t
for int8_t/uint8_t
point_c & operator=(point_c< value_type > &&r) DXLE_NOEXCEPT_OR_NOTHROW
Definition: point2d.hpp:152
void ostream_operator_helper(std::basic_ostream< CharType > &os, const CharType *str, const point_c< PointType > &p)
Definition: point2d.hpp:204
value_type y
Definition: point2d.hpp:109
point_c< std::int8_t > point8i
Definition: point2d.hpp:667
DXLE_CONSTEXPR point_c(size_c< Tp2_, nullptr > &&other) DXLE_NOEXCEPT_IF((dxle
Definition: point2d.hpp:133
point_c< int > pointi
Definition: point2d.hpp:665
std::remove_cv< T >::type value_type
Definition: point2d.hpp:108
point_c & operator=(const point_c< value_type > &r) DXLE_NOEXCEPT_IF((std
Definition: point2d.hpp:145
Definition: point2d.hpp:672
point_c< T1 > T2
Definition: point2d.hpp:353
Definition: cast_if.hpp:12
#define DXLE_TEMP_make_hash(int_t, bit, bit2)
Definition: point2d.hpp:675
DXLE_CONSTEXPR point_c< T > operator+(const point_c< T > &r) DXLE_NOEXCEPT_IF(std
Overload of unary operator +.
Definition: point2d.hpp:309
point_c< T > make_point_c(const std::pair< T, T > &pa) DXLE_NOEXCEPT_IF(std
conversion from std::pair
Definition: point2d.hpp:183
DXLE_CONSTEXPR point_c(const size_c< value_type, nullptr > &other) DXLE_NOEXCEPT_IF((dxle
Definition: point2d.hpp:137
#define DXLE_NOEXCEPT_IF_EXPR(EXPR)
Definition: suffix.hpp:110
DXLE_CONSTEXPR auto safe_dist(const T1 &n1, const T2 &n2) DXLE_NOEXCEPT_IF_EXPR((n1 - n2)) -> decltype(n1 - n2)
Definition: safe_dist.hpp:14
point_c< T1 > & operator*=(point_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.x *
Overload of binary operator *=.
DXLE_CONSTEXPR point_c< T > operator-(const point_c< T > &r) DXLE_NOEXCEPT_IF_EXPR(-r.x)
Overload of unary operator -.
Definition: point2d.hpp:294
DXLE_CONSTEXPR point_c(const point_c< value_type > &o) DXLE_NOEXCEPT_IF((std
Definition: point2d.hpp:122
#define DXLE_NOEXCEPT_IF(COND)
Definition: suffix.hpp:107
point_c< T1 > & operator+=(point_c< T1 > &l, const point_c< T2 > &r) DXLE_NOEXCEPT_IF_EXPR(l.x+
Overload of binary operator +=.
#define DXLE_NOEXCEPT_OR_NOTHROW
Definition: suffix.hpp:94
point_c< double > pointd
Definition: point2d.hpp:668
DXLE_CONSTEXPR double cross(const point_c< T1 > &p1, const point_c< T2 > &p2) DXLE_NOEXCEPT_IF_EXPR((static_cast_if< T1
Computes a cross-product of two point_c value as vectors.
value_type x
Definition: point2d.hpp:109
typename distance_result_type< T1, T2 >::type distance_result_type_t
Template class for 2D points specified by its coordinates x and y.
Definition: point2d.hpp:105
std::istream & operator>>(std::istream &is, point_c< T > &p)
istream operator
Definition: point2d.hpp:262
DXLE_CONSTEXPR to static_cast_if(const from &n) DXLE_NOEXCEPT_IF_EXPR((dxle
Definition: cast_if.hpp:52
point_c< float > pointf
Definition: point2d.hpp:669
DXLE_CONSTEXPR point_c(const size_c< Tp2_, nullptr > &other) DXLE_NOEXCEPT_IF((dxle
Definition: point2d.hpp:129
void istream_operator_helper(std::basic_istream< CharType > &is, point_c< PointType > &p)
Definition: point2d.hpp:210
point_c< std::uint8_t > pointu8i
Definition: point2d.hpp:666
DXLE_CONSTEXPR point_c(point_c< value_type > &&o) DXLE_NOEXCEPT_OR_NOTHROW
Definition: point2d.hpp:124