00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef quaternion_comparison_h
00014 #define quaternion_comparison_h
00015
00016 #include <cml/core/cml_assert.h>
00017 #include <cml/et/scalar_ops.h>
00018
00019
00020
00021
00022 struct quaternion_comparison_expects_quaternion_args_error;
00023
00024 #define CML_QUAT_QUAT_ORDER(_order_, _op_, _OpT_) \
00025 template< \
00026 typename E1, class AT1, typename E2, class AT2, class O, class C > \
00027 inline bool \
00028 _op_ ( \
00029 const quaternion<E1,AT1,O,C>& left, \
00030 const quaternion<E2,AT2,O,C>& right) \
00031 { \
00032 return detail::quaternion_##_order_ (left, right, _OpT_ <E1,E2>()); \
00033 }
00034
00035 #define CML_QUAT_QUATXPR_ORDER(_order_, _op_, _OpT_) \
00036 template<typename E, class AT, class O, class C, class XprT> \
00037 inline bool \
00038 _op_ ( \
00039 const quaternion<E,AT,O,C>& left, \
00040 QUATXPR_ARG_TYPE right) \
00041 { \
00042 return detail::quaternion_##_order_ (left, right, \
00043 _OpT_ <E, typename XprT::value_type>()); \
00044 }
00045
00046 #define CML_QUATXPR_QUAT_ORDER(_order_, _op_, _OpT_) \
00047 template<class XprT, typename E, class AT, class O, class C > \
00048 inline bool \
00049 _op_ ( \
00050 QUATXPR_ARG_TYPE left, \
00051 const quaternion<E,AT,O,C>& right) \
00052 { \
00053 return detail::quaternion_##_order_ (left, right, \
00054 _OpT_ <typename XprT::value_type, E>()); \
00055 }
00056
00057 #define CML_QUATXPR_QUATXPR_ORDER(_order_, _op_, _OpT_) \
00058 template<class XprT1, class XprT2> \
00059 inline bool \
00060 _op_ ( \
00061 QUATXPR_ARG_TYPE_N(1) left, \
00062 QUATXPR_ARG_TYPE_N(2) right) \
00063 { \
00064 return detail::quaternion_##_order_ (left, right, \
00065 _OpT_ < \
00066 typename XprT1::value_type, \
00067 typename XprT2::value_type>()); \
00068 }
00069
00070
00071 namespace cml {
00072 namespace detail {
00073
00080 template<typename LeftT, typename RightT, typename OpT>
00081 inline bool
00082 quaternion_weak_order(const LeftT& left, const RightT& right, OpT)
00083 {
00084
00085 typedef et::ExprTraits<LeftT> left_traits;
00086 typedef et::ExprTraits<RightT> right_traits;
00087
00088
00089 CML_STATIC_REQUIRE_M(
00090 (et::QuaternionExpressions<LeftT,RightT>::is_true),
00091 quaternion_comparison_expects_quaternion_args_error);
00092
00093
00094
00095
00096 typedef typename et::QuaternionPromote<
00097 typename left_traits::result_type,
00098 typename right_traits::result_type
00099 >::type result_type;
00100
00101 for(ssize_t i = 0; i < result_type::array_size; ++ i) {
00102
00103 if(OpT().apply(
00104 left_traits().get(left,i),
00105 right_traits().get(right,i)
00106 ))
00107 {
00108
00109 return true;
00110 } else if(OpT().apply(
00111 right_traits().get(right,i),
00112 left_traits().get(left,i)
00113 ))
00114 {
00115
00116 return false;
00117 } else {
00118
00119
00120
00121
00122 continue;
00123 }
00124 }
00125
00126
00127
00128 return false;
00129 }
00130
00136 template<typename LeftT, typename RightT, typename OpT>
00137 inline bool
00138 quaternion_total_order(const LeftT& left, const RightT& right, OpT)
00139 {
00140
00141 typedef et::ExprTraits<LeftT> left_traits;
00142 typedef et::ExprTraits<RightT> right_traits;
00143
00144
00145 CML_STATIC_REQUIRE_M(
00146 (et::QuaternionExpressions<LeftT,RightT>::is_true),
00147 quaternion_comparison_expects_quaternion_args_error);
00148
00149
00150
00151
00152 typedef typename et::QuaternionPromote<
00153 typename left_traits::result_type,
00154 typename right_traits::result_type
00155 >::type result_type;
00156
00157 for(ssize_t i = 0; i < result_type::array_size; ++ i) {
00158
00159
00160 if(OpT().apply(
00161 left_traits().get(left,i),
00162 right_traits().get(right,i)
00163 ))
00164 {
00165
00166
00167
00168 if(!OpT().apply(
00169 right_traits().get(right,i),
00170 left_traits().get(left,i)
00171 ))
00172 return true;
00173
00174
00175
00176
00177 else
00178 continue;
00179
00180 } else {
00181
00182
00183 return false;
00184 }
00185 }
00186
00187
00188
00189 return true;
00190 }
00191
00192 }
00193
00194
00195
00196 CML_QUAT_QUAT_ORDER( total_order, operator==, et::OpEqual)
00197 CML_QUATXPR_QUAT_ORDER( total_order, operator==, et::OpEqual)
00198 CML_QUAT_QUATXPR_ORDER( total_order, operator==, et::OpEqual)
00199 CML_QUATXPR_QUATXPR_ORDER( total_order, operator==, et::OpEqual)
00200
00201 CML_QUAT_QUAT_ORDER( weak_order, operator!=, et::OpNotEqual)
00202 CML_QUATXPR_QUAT_ORDER( weak_order, operator!=, et::OpNotEqual)
00203 CML_QUAT_QUATXPR_ORDER( weak_order, operator!=, et::OpNotEqual)
00204 CML_QUATXPR_QUATXPR_ORDER( weak_order, operator!=, et::OpNotEqual)
00205
00206 CML_QUAT_QUAT_ORDER( weak_order, operator<, et::OpLess)
00207 CML_QUATXPR_QUAT_ORDER( weak_order, operator<, et::OpLess)
00208 CML_QUAT_QUATXPR_ORDER( weak_order, operator<, et::OpLess)
00209 CML_QUATXPR_QUATXPR_ORDER( weak_order, operator<, et::OpLess)
00210
00211 }
00212
00213 #endif
00214
00215
00216