00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef vector_comparison_h
00014 #define vector_comparison_h
00015
00016 #include <cml/core/cml_assert.h>
00017 #include <cml/et/size_checking.h>
00018 #include <cml/et/scalar_ops.h>
00019
00020
00021
00022
00023 struct vector_comparison_expects_vector_args_error;
00024
00025 #define CML_VEC_VEC_ORDER(_order_, _op_, _OpT_) \
00026 template<typename E1, class AT1, typename E2, class AT2> \
00027 inline bool \
00028 _op_ ( \
00029 const vector<E1,AT1>& left, \
00030 const vector<E2,AT2>& right) \
00031 { \
00032 return detail::vector_##_order_ (left, right, _OpT_ <E1,E2>()); \
00033 }
00034
00035 #define CML_VEC_VECXPR_ORDER(_order_, _op_, _OpT_) \
00036 template<typename E, class AT, class XprT> \
00037 inline bool \
00038 _op_ ( \
00039 const vector<E,AT>& left, \
00040 VECXPR_ARG_TYPE right) \
00041 { \
00042 return detail::vector_##_order_ (left, right, \
00043 _OpT_ <E, typename XprT::value_type>()); \
00044 }
00045
00046 #define CML_VECXPR_VEC_ORDER(_order_, _op_, _OpT_) \
00047 template<class XprT, typename E, class AT> \
00048 inline bool \
00049 _op_ ( \
00050 VECXPR_ARG_TYPE left, \
00051 const vector<E,AT>& right) \
00052 { \
00053 return detail::vector_##_order_ (left, right, \
00054 _OpT_ <typename XprT::value_type, E>()); \
00055 }
00056
00057 #define CML_VECXPR_VECXPR_ORDER(_order_, _op_, _OpT_) \
00058 template<class XprT1, class XprT2> \
00059 inline bool \
00060 _op_ ( \
00061 VECXPR_ARG_TYPE_N(1) left, \
00062 VECXPR_ARG_TYPE_N(2) right) \
00063 { \
00064 return detail::vector_##_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 vector_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::VectorExpressions<LeftT,RightT>::is_true),
00091 vector_comparison_expects_vector_args_error);
00092
00093
00094
00095
00096 typedef typename et::VectorPromote<
00097 typename left_traits::result_type,
00098 typename right_traits::result_type
00099 >::type result_type;
00100 typedef typename result_type::size_tag size_tag;
00101
00102
00103 ssize_t N = (ssize_t) et::CheckedSize(left,right,size_tag());
00104 for(ssize_t i = 0; i < N; ++ i) {
00105 if(OpT().apply(
00106 left_traits().get(left,i),
00107 right_traits().get(right,i)
00108 ))
00109 {
00110
00111 return true;
00112 } else if(OpT().apply(
00113 right_traits().get(right,i),
00114 left_traits().get(left,i)
00115 ))
00116 {
00117
00118 return false;
00119 } else {
00120
00121
00122
00123
00124 continue;
00125 }
00126 }
00127
00128
00129
00130 return false;
00131 }
00132
00138 template<typename LeftT, typename RightT, typename OpT>
00139 inline bool
00140 vector_total_order(const LeftT& left, const RightT& right, OpT)
00141 {
00142
00143 typedef et::ExprTraits<LeftT> left_traits;
00144 typedef et::ExprTraits<RightT> right_traits;
00145
00146
00147 CML_STATIC_REQUIRE_M(
00148 (et::VectorExpressions<LeftT,RightT>::is_true),
00149 vector_comparison_expects_vector_args_error);
00150
00151
00152
00153
00154 typedef typename et::VectorPromote<
00155 typename left_traits::result_type,
00156 typename right_traits::result_type
00157 >::type result_type;
00158 typedef typename result_type::size_tag size_tag;
00159
00160
00161 ssize_t N = (ssize_t) et::CheckedSize(left,right,size_tag());
00162 for(ssize_t i = 0; i < N; ++ i) {
00163
00164
00165 if(OpT().apply(
00166 left_traits().get(left,i),
00167 right_traits().get(right,i)
00168 ))
00169 {
00170
00171
00172
00173 if(!OpT().apply(
00174 right_traits().get(right,i),
00175 left_traits().get(left,i)
00176 ))
00177 return true;
00178
00179
00180
00181
00182 else
00183 continue;
00184
00185 } else {
00186
00187
00188 return false;
00189 }
00190 }
00191
00192
00193
00194 return true;
00195 }
00196
00197 }
00198
00199
00200
00201 CML_VEC_VEC_ORDER( total_order, operator==, et::OpEqual)
00202 CML_VECXPR_VEC_ORDER( total_order, operator==, et::OpEqual)
00203 CML_VEC_VECXPR_ORDER( total_order, operator==, et::OpEqual)
00204 CML_VECXPR_VECXPR_ORDER( total_order, operator==, et::OpEqual)
00205
00206 CML_VEC_VEC_ORDER( weak_order, operator!=, et::OpNotEqual)
00207 CML_VECXPR_VEC_ORDER( weak_order, operator!=, et::OpNotEqual)
00208 CML_VEC_VECXPR_ORDER( weak_order, operator!=, et::OpNotEqual)
00209 CML_VECXPR_VECXPR_ORDER( weak_order, operator!=, et::OpNotEqual)
00210
00211 CML_VEC_VEC_ORDER( weak_order, operator<, et::OpLess)
00212 CML_VECXPR_VEC_ORDER( weak_order, operator<, et::OpLess)
00213 CML_VEC_VECXPR_ORDER( weak_order, operator<, et::OpLess)
00214 CML_VECXPR_VECXPR_ORDER( weak_order, operator<, et::OpLess)
00215
00216 CML_VEC_VEC_ORDER( weak_order, operator>, et::OpGreater)
00217 CML_VECXPR_VEC_ORDER( weak_order, operator>, et::OpGreater)
00218 CML_VEC_VECXPR_ORDER( weak_order, operator>, et::OpGreater)
00219 CML_VECXPR_VECXPR_ORDER( weak_order, operator>, et::OpGreater)
00220
00221 CML_VEC_VEC_ORDER( total_order, operator<=, et::OpLessEqual)
00222 CML_VECXPR_VEC_ORDER( total_order, operator<=, et::OpLessEqual)
00223 CML_VEC_VECXPR_ORDER( total_order, operator<=, et::OpLessEqual)
00224 CML_VECXPR_VECXPR_ORDER( total_order, operator<=, et::OpLessEqual)
00225
00226 CML_VEC_VEC_ORDER( total_order, operator>=, et::OpGreaterEqual)
00227 CML_VECXPR_VEC_ORDER( total_order, operator>=, et::OpGreaterEqual)
00228 CML_VEC_VECXPR_ORDER( total_order, operator>=, et::OpGreaterEqual)
00229 CML_VECXPR_VECXPR_ORDER( total_order, operator>=, et::OpGreaterEqual)
00230
00231 }
00232
00233 #endif
00234
00235
00236