From d1152ad6f1342a9caa20dc198e90df9c53ace09e Mon Sep 17 00:00:00 2001 From: yumetodo Date: Thu, 11 Aug 2016 17:17:27 +0900 Subject: [PATCH] breaking change : change return type of dxle::cross (T1 : first argumrnt type, T2 : second argumet type) result type : 1. when T1 or T2 is not arithemtic type, result type is not-arithmetic one(T1 has high pritority). 2. when T1 or T2 is floating point type, result type is double. 3. when T1 or T2 is integral type, result type is integral type. sizeof(result type) is twice as many size as bigger one. 4. In other case, result type is T1. ref: #88 --- dxlibex/basic_types/point2d.hpp | 57 +++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/dxlibex/basic_types/point2d.hpp b/dxlibex/basic_types/point2d.hpp index 0c5d38d..d2a8a3f 100644 --- a/dxlibex/basic_types/point2d.hpp +++ b/dxlibex/basic_types/point2d.hpp @@ -624,7 +624,40 @@ namespace dxle { { return p1.x * p2.x + p1.y * p2.y; } - + namespace detail { + template::value, bool is_signed = std::is_signed::value, std::size_t sizeof_T = sizeof(T)> + struct point_c_mem_cross_helper_integral { using type = T; }; + template struct point_c_mem_cross_helper_integral { using type = std::int16_t; }; + template struct point_c_mem_cross_helper_integral { using type = std::uint16_t; }; + template struct point_c_mem_cross_helper_integral { using type = std::int32_t; }; + template struct point_c_mem_cross_helper_integral { using type = std::uint32_t; }; + template struct point_c_mem_cross_helper_integral { using type = std::int64_t; }; + template struct point_c_mem_cross_helper_integral { using type = std::uint64_t; }; + template struct point_c_mem_cross_helper_integral { using type = std::int64_t; }; + template struct point_c_mem_cross_helper_integral { using type = std::uint64_t; }; + + template< + typename T1, typename T2, + bool both_arithmetic = std::is_arithmetic::value && std::is_arithmetic::value, + bool T1_is_integral = std::is_integral::value, + bool T2_is_integral = std::is_integral::value, + bool T1_or_T2_is_floating_point = std::is_floating_point::value || std::is_floating_point::value + > + struct point_c_mem_cross_helper { using type = T1; }; + template + struct point_c_mem_cross_helper { using type = double; }; + template struct point_c_mem_cross_helper : point_c_mem_cross_helper_integral {}; + template struct point_c_mem_cross_helper : point_c_mem_cross_helper_integral {}; + template struct point_c_mem_cross_helper : point_c_mem_cross_helper_integral {}; + template struct point_c_mem_cross_helper : point_c_mem_cross_helper_integral< + typename std::conditional<(sizeof(T1) > sizeof(T2)), T1, T2>::type, true, std::is_signed::value || std::is_signed::value + > {}; + template struct point_c_mem_cross_helper { using type = T2; }; + template struct point_c_mem_cross_helper { using type = T1; }; + + template + using point_c_mem_cross_helper_result_type = typename point_c_mem_cross_helper::type; + } /** @relates point_c \~japanese @brief 2つのpoint_cクラスオブジェクトをベクトルとして外積を計算する @@ -634,16 +667,28 @@ namespace dxle { \~japanese @param p2 point_cクラスオブジェクト \~english @param p2 point_c value \~japanese @return 計算結果。 + (T1 : 第1引数の型, T2 : 第2引数の型) + 戻り値の型 + 1. T1もしくはT2がarithmeticではない場合、arithmeticではない方(T1が優先) + 2. T1もしくはT2が浮動小数点型の場合、double + 3. T1もしくはT2が整数型の場合、大きい方の型の倍の大きさの整数型 + 4. いずれでもない時はT1 \~english @return Computed result. + (T1 : first argumrnt type, T2 : second argumet type) + result type : + 1. when T1 or T2 is not arithemtic type, result type is not-arithmetic one(T1 has high pritority). + 2. when T1 or T2 is floating point type, result type is double. + 3. when T1 or T2 is integral type, result type is integral type. sizeof(result type) is twice as many size as bigger one. + 4. In other case, result type is T1. */ - template - DXLE_CONSTEXPR double cross(const point_c& p1, const point_c& p2) + template> + DXLE_CONSTEXPR ResultType cross(const point_c& p1, const point_c& p2) DXLE_NOEXCEPT_IF_EXPR(( - static_cast_if::value>(std::declval()) * std::declval() - + static_cast_if::value>(std::declval()) * std::declval() + static_cast(std::declval()) * static_cast(std::declval()) + + static_cast(std::declval()) * static_cast(std::declval()) )) { - return static_cast_if::value>(p1.x) * p2.y + static_cast_if::value>(p1.y) * p2.x; + return static_cast(p1.x) * static_cast(p2.y) + static_cast(p1.y) * static_cast(p2.x); } /** @relates point_c