00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_PAIR_HPP
00014 #define __MMX_PAIR_HPP
00015 #include <basix/syntactic.hpp>
00016 #include <basix/operators.hpp>
00017
00019
00020 namespace mmx {
00021 #define TMPL template<typename C1, typename C2>
00022 #define Pair pair<C1,C2>
00023
00024 TMPL
00025 class pair {
00026 MMX_ALLOCATORS;
00027 public:
00028 C1 x1;
00029 C2 x2;
00030 inline pair () {}
00031 inline pair (const format<C1>& fm1, const format<C2>& fm2):
00032 x1 (get_sample (fm1)), x2 (get_sample (fm2)) {}
00033 inline pair (const C1& x1b, const C2& x2b): x1 (x1b), x2 (x2b) {}
00034 };
00035 DEFINE_BINARY_FORMAT_2 (pair)
00036
00037 TMPL inline C1 car (const Pair& p) { return p.x1; }
00038 TMPL inline C2 cdr (const Pair& p) { return p.x2; }
00039 TMPL inline format<C1> CF1 (const Pair& p) { return get_format (p.x1); }
00040 TMPL inline format<C2> CF2 (const Pair& p) { return get_format (p.x2); }
00041
00042 template<typename Op, typename C1, typename C2> nat
00043 unary_hash (const Pair& p) {
00044 nat h= Op::op (p.x1);
00045 return (h<<1) ^ (h<<3) ^ (h<<9) ^ (h>>29) ^ Op::op (p.x2);
00046 }
00047
00048 template<typename Op, typename C1, typename C2> bool
00049 binary_test (const Pair& p1, const Pair& p2) {
00050 return Op::op (p1.x1, p2.x1) && Op::op (p1.x2, p2.x2);
00051 }
00052
00053 TRUE_IDENTITY_OP_SUGAR(TMPL,Pair)
00054 EXACT_IDENTITY_OP_SUGAR(TMPL,Pair)
00055 HARD_IDENTITY_OP_SUGAR(TMPL,Pair)
00056
00057 TMPL inline Pair
00058 operator * (const Pair& p1, const Pair& p2) {
00059 return Pair (p1.x1 * p2.x1, p1.x2 * p2.x2);
00060 }
00061
00062 TMPL inline syntactic
00063 flatten (const Pair& p) {
00064 return apply (GEN_SQTUPLE, flatten (p.x1), flatten (p.x2));
00065 }
00066
00067 TMPL
00068 struct binary_helper<Pair >: public void_binary_helper<Pair > {
00069 static inline string short_type_name () {
00070 return "Pa" * Short_type_name (C1) * Short_type_name (C2); }
00071 static inline generic full_type_name () {
00072 return gen ("Pair", Full_type_name (C1), Full_type_name (C2)); }
00073 static inline nat size (const Pair& v) {
00074 (void) v; return 2; }
00075 static inline generic access (const Pair& v, nat i) {
00076 if (i == 0) return as<generic> (v.x1);
00077 else if (i == 1) return as<generic> (v.x2);
00078 else ERROR ("index out of range"); }
00079 static inline generic disassemble (const Pair& v) {
00080 return gen_vec (as<generic> (v.x1), as<generic> (v.x2)); }
00081 static inline Pair assemble (const generic& v) {
00082 return Pair (as<C1> (vector_access (v, 0)),
00083 as<C2> (vector_access (v, 1))); }
00084 static inline void write (const port& out, const Pair& p) {
00085 binary_write<C1> (out, p.x1);
00086 binary_write<C2> (out, p.x2); }
00087 static inline Pair read (const port& in) {
00088 C1 x1= binary_read<C1> (in);
00089 C2 x2= binary_read<C2> (in);
00090 return Pair (x1, x2); }
00091 };
00092
00093
00094
00095
00096
00097 template<typename C1, typename T1, typename C2, typename T2,
00098 typename Fun1, typename Fun2> pair<C2,T2>
00099 map (const Fun1& funT, const Fun2& funC,
00100 const pair<C1,T1>& p,
00101 const format<C2>& fmC, const format<T2>& fmT)
00102 {
00103 pair<C2,T2> r (fmC, fmT);
00104 set_as (r.x1, p.x1);
00105 set_as (r.x2, p.x2);
00106 return r;
00107 }
00108
00109 #undef TMPL
00110 #undef Pair
00111 }
00112 #endif // __MMX_PAIR_HPP