00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef NTG_CORE_INTERNAL_GLOBAL_OPS_TRAITS_HH
00029 # define NTG_CORE_INTERNAL_GLOBAL_OPS_TRAITS_HH
00030
00031
00032
00033
00034
00035
00036
00037
00038 # include <ntg/core/macros.hh>
00039 # include <ntg/core/type_traits.hh>
00040
00041 # include <mlc/bool.hh>
00042
00043 namespace ntg {
00044
00045 namespace internal {
00046
00047
00048
00049
00050
00051 struct undefined_traits {};
00052
00053 template <class T>
00054 struct meta_undefined_traits
00055 {
00056 typedef undefined_traits ret;
00057 typedef undefined_traits lhs_type;
00058 typedef undefined_traits rhs_type;
00059 typedef undefined_traits traits_lhs_type;
00060 typedef undefined_traits traits_rhs_type;
00061 };
00062
00063 template <class T>
00064 struct is_defined { enum { ret = true }; };
00065 template <>
00066 struct is_defined<undefined_traits> { enum { ret = false }; };
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 template <class T1, class T2>
00077 struct get_order
00078 {
00079 typedef T1 traits_lhs_type;
00080 typedef T2 traits_rhs_type;
00081
00082 typedef T1 lhs_type;
00083 typedef T2 rhs_type;
00084 };
00085
00086 template <class T1, class T2>
00087 struct get_order_inv
00088 {
00089 typedef T2 traits_lhs_type;
00090 typedef T1 traits_rhs_type;
00091
00092 typedef T1 lhs_type;
00093 typedef T2 rhs_type;
00094 };
00095
00096
00097
00098
00100
00127 template <class Op, class T, class U>
00128 struct operator_traits
00129 {
00130 enum { commutative = false };
00131 typedef undefined_traits ret;
00132 typedef undefined_traits impl;
00133 };
00134
00135 struct operator_plus {};
00136 struct operator_minus {};
00137 struct operator_times {};
00138 struct operator_div {};
00139 struct operator_mod {};
00140 struct operator_logical {};
00141 struct operator_cmp {};
00142 struct operator_min {};
00143 struct operator_max {};
00144
00145
00146
00147
00149
00173 template <class Op, class T, class U>
00174 struct deduce_from_traits
00175 {
00176 private:
00177 typedef ntg_type(T) T1;
00178 typedef ntg_type(U) T2;
00179
00180 typedef typename operator_traits<Op, T1, T2>::ret traits;
00181 typedef typename operator_traits<Op, T2, T1>::ret rev_traits;
00182
00183 enum { can_invert = (operator_traits<Op, T2, T1>::commutative
00184 && is_defined<rev_traits>::ret) };
00185
00186 typedef typename
00187 mlc::if_<is_defined<traits>::ret,
00188 get_order<T1, T2>, typename
00189 mlc::if_<can_invert,
00190 get_order_inv<T1, T2>,
00191 meta_undefined_traits<undefined_traits>
00192 >::ret
00193 >::ret deduced_type;
00194
00195 typedef typename deduced_type::traits_lhs_type traits_lhs_type;
00196 typedef typename deduced_type::traits_rhs_type traits_rhs_type;
00197
00198 public:
00199 typedef operator_traits<Op,
00200 traits_lhs_type,
00201 traits_rhs_type> deduced_traits;
00202
00203 typedef typename deduced_type::lhs_type lhs_type;
00204 typedef typename deduced_type::rhs_type rhs_type;
00205 typedef typename deduced_traits::ret ret;
00206 typedef typename deduced_traits::impl impl;
00207 };
00208
00209 }
00210
00211 }
00212
00213 #endif // !NTG_CORE_INTERNAL_GLOBAL_OPS_TRAITS_HH