array_fun.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2006 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #ifndef _D_ARRAY_FUN_H_
  36. #define _D_ARRAY_FUN_H_
  37. #include <cstdlib>
  38. #include <functional>
  39. namespace aria2 {
  40. // calculate length of array
  41. template<typename T, size_t N>
  42. char (&char_array_ref(T (&)[N]))[N];
  43. template<typename T, size_t N>
  44. size_t arrayLength(T (&a)[N])
  45. {
  46. return sizeof(char_array_ref(a));
  47. }
  48. template<typename T>
  49. size_t arrayLength(T (&a)[0u])
  50. {
  51. return 0;
  52. }
  53. template<typename T>
  54. class array_ptr {
  55. private:
  56. T* _array;
  57. // Copies are not allowed. Let's make them private.
  58. array_ptr(const array_ptr& s);
  59. array_ptr& operator=(const array_ptr& s);
  60. template<typename S>
  61. array_ptr& operator=(const array_ptr<S>& s);
  62. public:
  63. array_ptr():_array(0) {}
  64. explicit array_ptr(T* array):_array(array) {}
  65. ~array_ptr()
  66. {
  67. delete [] _array;
  68. }
  69. operator T*()
  70. {
  71. return _array;
  72. }
  73. operator const T*() const
  74. {
  75. return _array;
  76. }
  77. };
  78. template<typename T, size_t N>
  79. class array_wrapper {
  80. private:
  81. T _array[N];
  82. public:
  83. array_wrapper() {}
  84. operator T*()
  85. {
  86. return _array;
  87. }
  88. operator const T*() const
  89. {
  90. return _array;
  91. }
  92. size_t size() const
  93. {
  94. return N;
  95. }
  96. };
  97. // Expression Template for array
  98. namespace expr {
  99. template<typename L, typename OpTag, typename R>
  100. struct BinExpr {
  101. BinExpr(const L& l, const R& r):_l(l), _r(r) {}
  102. typedef typename OpTag::returnType returnType;
  103. returnType operator[](size_t index) const
  104. {
  105. return OpTag::apply(_l[index], _r[index]);
  106. }
  107. const L& _l;
  108. const R& _r;
  109. };
  110. template<typename OpTag, typename A>
  111. struct UnExpr {
  112. UnExpr(const A& a):_a(a) {}
  113. typedef typename OpTag::returnType returnType;
  114. returnType operator[](size_t index) const
  115. {
  116. return OpTag::apply(_a[index]);
  117. }
  118. const A& _a;
  119. };
  120. template<typename T>
  121. struct And
  122. {
  123. typedef T returnType;
  124. static inline returnType apply(T lhs, T rhs) { return lhs&rhs; }
  125. };
  126. template<typename T>
  127. struct Or
  128. {
  129. typedef T returnType;
  130. static inline returnType apply(T lhs, T rhs) { return lhs|rhs; }
  131. };
  132. template<typename T>
  133. struct Negate
  134. {
  135. typedef T returnType;
  136. static inline returnType apply(T a) { return ~a; }
  137. };
  138. template<typename T>
  139. struct Array
  140. {
  141. typedef T returnType;
  142. Array(const T* t):_t(t) {}
  143. const T* _t;
  144. returnType operator[](size_t index) const { return _t[index]; }
  145. };
  146. template<typename T>
  147. Array<T>
  148. array(const T* t) { return Array<T>(t); }
  149. template<typename L, typename R>
  150. BinExpr<L, And<typename L::returnType>, R>
  151. operator&(const L& l, const R& r)
  152. {
  153. return BinExpr<L, And<typename L::returnType>, R>(l, r);
  154. }
  155. template<typename L, typename R>
  156. BinExpr<L, Or<typename L::returnType>, R>
  157. operator|(const L& l, const R& r)
  158. {
  159. return BinExpr<L, Or<typename L::returnType>, R>(l, r);
  160. }
  161. template<typename A>
  162. UnExpr<Negate<typename A::returnType>, A>
  163. operator~(const A& a)
  164. {
  165. return UnExpr<Negate<typename A::returnType>, A>(a);
  166. }
  167. } // namespace expr
  168. } // namespace aria2
  169. #endif // _D_ARRAY_FUN_H_