浏览代码

2009-04-26 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Rewritten expr
	* src/array_fun.h
	* test/array_funTest.cc
Tatsuhiro Tsujikawa 16 年之前
父节点
当前提交
1ea7fca02b
共有 3 个文件被更改,包括 57 次插入88 次删除
  1. 6 0
      ChangeLog
  2. 40 77
      src/array_fun.h
  3. 11 11
      test/array_funTest.cc

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+2009-04-26  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Rewritten expr
+	* src/array_fun.h
+	* test/array_funTest.cc
+	
 2009-04-26  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Added forEachMemFunSH(). Use it in BitTorrent event dispatch.

+ 40 - 77
src/array_fun.h

@@ -118,114 +118,77 @@ public:
 
 namespace expr {
 
-template<typename T>
-struct Expr {
-  Expr(const T& expOp):_expOp(expOp) {}
+template<typename L, typename OpTag, typename R>
+struct BinExpr {
+  BinExpr(const L& l, const R& r):_l(l), _r(r) {}
+
+  typedef typename OpTag::returnType returnType;
 
-  typename T::returnType operator[](size_t index) const
+  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<typename T>
-struct And
-{
-  typedef T returnType;
-  static inline T apply(T lhs, T rhs) { return lhs&rhs; }
+template<typename OpTag, typename A>
+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<typename T>
-struct Noop
+struct And
 {
   typedef T returnType;
-  static inline T apply(T arg) { return arg; }
+  static inline returnType apply(T lhs, T rhs) { return lhs&rhs; }
 };
 
 template<typename T>
 struct Negate
 {
   typedef T returnType;
-  static inline T apply(T arg) { return ~arg; }
-};
-
-template<typename T1, typename T2, typename BinOp>
-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;
+  static inline returnType apply(T a) { return ~a; }
 };
 
-template<typename T, typename UnOp>
-struct ExpUnOp
+template<typename T>
+struct Array
 {
-  typedef typename UnOp::returnType returnType;
+  typedef T returnType;
 
-  ExpUnOp(const T& arg):_arg(arg) {}
+  Array(const T* t):_t(t) {}
 
-  returnType operator()(size_t index) const
-  {
-    return UnOp::apply(_arg[index]);
-  }
+  const T* _t;
 
-  const T& _arg;
+  returnType operator[](size_t index) const { return _t[index]; }
 };
 
-// Partial specialization for pointers
-template<typename T, typename UnOp>
-struct ExpUnOp<T*, UnOp>
-{
-  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<typename T, size_t N>
-Expr<ExpUnOp<T(&)[N], Noop<T> > > arrayRef(T (&t)[N])
-{
-  typedef ExpUnOp<T(&)[N], Noop<T> > ExpUnOpT;
-  return Expr<ExpUnOpT>(ExpUnOpT(t));
-}
-
 template<typename T>
-Expr<ExpUnOp<T*, Noop<T> > > array(T* a)
-{
-  typedef ExpUnOp<T*, Noop<T> > ExpUnOpT;
-  return Expr<ExpUnOpT>(ExpUnOpT(a));
-}
+Array<T>
+array(const T* t) { return Array<T>(t); }
 
-template<typename T>
-Expr<ExpUnOp<Expr<T>, Negate<typename T::returnType> > >
-operator~(const Expr<T>& arg)
+template<typename L, typename R>
+BinExpr<L, And<typename L::returnType>, R>
+operator&(const L& l, const R& r)
 {
-  typedef ExpUnOp<Expr<T>, Negate<typename T::returnType> > ExpUnOpT;
-  return Expr<ExpUnOpT>(ExpUnOpT(arg));
+  return BinExpr<L, And<typename L::returnType>, R>(l, r);
 }
 
-template<typename T1, typename T2>
-Expr<ExpBinOp<Expr<T1>, Expr<T2>, And<typename T1::returnType> > >
-operator&(const Expr<T1>& lhs, const Expr<T2>& rhs)
+template<typename A>
+UnExpr<Negate<typename A::returnType>, A>
+operator~(const A& a)
 {
-  typedef ExpBinOp<Expr<T1>, Expr<T2>, And<typename T1::returnType> > ExpBinOpT;
-  return Expr<ExpBinOpT>(ExpBinOpT(lhs, rhs));
+  return UnExpr<Negate<typename A::returnType>, A>(a);
 }
 
 } // namespace expr

+ 11 - 11
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()