diff --git a/ChangeLog b/ChangeLog index 442cc66d..a6413883 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-04-26 Tatsuhiro Tsujikawa + + Rewritten expr + * src/array_fun.h + * test/array_funTest.cc + 2009-04-26 Tatsuhiro Tsujikawa Added forEachMemFunSH(). Use it in BitTorrent event dispatch. diff --git a/src/array_fun.h b/src/array_fun.h index 479e24b0..a8990b9d 100644 --- a/src/array_fun.h +++ b/src/array_fun.h @@ -118,114 +118,77 @@ public: namespace expr { -template -struct Expr { - Expr(const T& expOp):_expOp(expOp) {} +template +struct BinExpr { + BinExpr(const L& l, const R& r):_l(l), _r(r) {} - typename T::returnType operator[](size_t index) const + typedef typename OpTag::returnType returnType; + + returnType operator[](size_t index) const { - return _expOp(index); + return OpTag::apply(_l[index], _r[index]); } - const T& _expOp; + const L& _l; + const R& _r; +}; + +template +struct UnExpr { + UnExpr(const A& a):_a(a) {} + + typedef typename OpTag::returnType returnType; + + returnType operator[](size_t index) const + { + return OpTag::apply(_a[index]); + } + + const A& _a; }; template struct And { typedef T returnType; - static inline T apply(T lhs, T rhs) { return lhs&rhs; } -}; - -template -struct Noop -{ - typedef T returnType; - static inline T apply(T arg) { return arg; } + static inline returnType apply(T lhs, T rhs) { return lhs&rhs; } }; template struct Negate { typedef T returnType; - static inline T apply(T arg) { return ~arg; } + static inline returnType apply(T a) { return ~a; } }; -template -struct ExpBinOp -{ - typedef typename BinOp::returnType returnType; - - ExpBinOp(const T1& lhs, const T2& rhs):_lhs(lhs), _rhs(rhs) {} - - returnType operator()(size_t index) const - { - return BinOp::apply(_lhs[index], _rhs[index]); - } - - const T1& _lhs; - const T2& _rhs; -}; - -template -struct ExpUnOp -{ - typedef typename UnOp::returnType returnType; - - ExpUnOp(const T& arg):_arg(arg) {} - - returnType operator()(size_t index) const - { - return UnOp::apply(_arg[index]); - } - - const T& _arg; -}; - -// Partial specialization for pointers -template -struct ExpUnOp -{ - typedef typename UnOp::returnType returnType; - - ExpUnOp(const T* arg):_arg(arg) {} - - returnType operator()(size_t index) const - { - return UnOp::apply(_arg[index]); - } - - const T* _arg; -}; - -template -Expr > > arrayRef(T (&t)[N]) -{ - typedef ExpUnOp > ExpUnOpT; - return Expr(ExpUnOpT(t)); -} - template -Expr > > array(T* a) +struct Array { - typedef ExpUnOp > ExpUnOpT; - return Expr(ExpUnOpT(a)); -} + typedef T returnType; + + Array(const T* t):_t(t) {} + + const T* _t; + + returnType operator[](size_t index) const { return _t[index]; } +}; template -Expr, Negate > > -operator~(const Expr& arg) +Array +array(const T* t) { return Array(t); } + +template +BinExpr, R> +operator&(const L& l, const R& r) { - typedef ExpUnOp, Negate > ExpUnOpT; - return Expr(ExpUnOpT(arg)); + return BinExpr, R>(l, r); } -template -Expr, Expr, And > > -operator&(const Expr& lhs, const Expr& rhs) +template +UnExpr, A> +operator~(const A& a) { - typedef ExpBinOp, Expr, And > ExpBinOpT; - return Expr(ExpBinOpT(lhs, rhs)); + return UnExpr, A>(a); } } // namespace expr diff --git a/test/array_funTest.cc b/test/array_funTest.cc index e00f1c8d..3854f325 100644 --- a/test/array_funTest.cc +++ b/test/array_funTest.cc @@ -36,28 +36,28 @@ CPPUNIT_TEST_SUITE_REGISTRATION(array_funTest); void array_funTest::testArray_negate() { unsigned char a[] = { 0xaa, 0x55 }; - CPPUNIT_ASSERT_EQUAL((unsigned char)0x55, (~arrayRef(a))[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x55, (~array(a))[0]); CPPUNIT_ASSERT_EQUAL((unsigned char)0xaa, (~array((unsigned char*)a))[1]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0xaa, (~~arrayRef(a))[0]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0x55, (~~arrayRef(a))[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0xaa, (~~array(a))[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x55, (~~array(a))[1]); } void array_funTest::testArray_and() { unsigned char a1[] = { 0xaa, 0x55 }; unsigned char a2[] = { 0x1a, 0x25 }; - CPPUNIT_ASSERT_EQUAL((unsigned char)0x0a, (arrayRef(a1)&arrayRef(a2))[0]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0x05, (arrayRef(a1)&arrayRef(a2))[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x0a, (array(a1)&array(a2))[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x05, (array(a1)&array(a2))[1]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0xa0, (arrayRef(a1)&~arrayRef(a2))[0]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0x50, (arrayRef(a1)&~arrayRef(a2))[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0xa0, (array(a1)&~array(a2))[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x50, (array(a1)&~array(a2))[1]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0xa0, (~arrayRef(a2)&arrayRef(a1))[0]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0x50, (~arrayRef(a2)&arrayRef(a1))[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0xa0, (~array(a2)&array(a1))[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x50, (~array(a2)&array(a1))[1]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0x45, (~arrayRef(a1)&~arrayRef(a2))[0]); - CPPUNIT_ASSERT_EQUAL((unsigned char)0x8a, (~arrayRef(a1)&~arrayRef(a2))[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x45, (~array(a1)&~array(a2))[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0x8a, (~array(a1)&~array(a2))[1]); } void array_funTest::testArrayLength()