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