array_fun.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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_fun(T (&)[N]))[N];
  43. // For 0 length array
  44. template<typename T>
  45. char (&char_array_ref_fun(T (&)[0u]))[0u];
  46. // To calculate size of array at compile time, we use macro here.
  47. #define A2_ARRAY_LEN(X) sizeof(char_array_ref_fun(X))
  48. template<typename T, size_t N>
  49. T* vbegin(T (&a)[N])
  50. {
  51. return a;
  52. }
  53. template<typename T, size_t N>
  54. T* vend(T (&a)[N])
  55. {
  56. return a+N;
  57. }
  58. template<typename T>
  59. class array_ptr {
  60. private:
  61. T* _array;
  62. // Copies are not allowed. Let's make them private.
  63. array_ptr(const array_ptr& s);
  64. array_ptr& operator=(const array_ptr& s);
  65. template<typename S>
  66. array_ptr& operator=(const array_ptr<S>& s);
  67. public:
  68. array_ptr():_array(0) {}
  69. explicit array_ptr(T* array):_array(array) {}
  70. ~array_ptr()
  71. {
  72. delete [] _array;
  73. }
  74. operator T*()
  75. {
  76. return _array;
  77. }
  78. operator const T*() const
  79. {
  80. return _array;
  81. }
  82. };
  83. template<typename T, size_t N>
  84. class array_wrapper {
  85. private:
  86. T _array[N];
  87. public:
  88. array_wrapper() {}
  89. operator T*()
  90. {
  91. return _array;
  92. }
  93. operator const T*() const
  94. {
  95. return _array;
  96. }
  97. size_t size() const
  98. {
  99. return N;
  100. }
  101. };
  102. // Expression Template for array
  103. namespace expr {
  104. template<typename L, typename OpTag, typename R>
  105. struct BinExpr {
  106. BinExpr(const L& l, const R& r):_l(l), _r(r) {}
  107. typedef typename OpTag::returnType returnType;
  108. returnType operator[](size_t index) const
  109. {
  110. return OpTag::apply(_l[index], _r[index]);
  111. }
  112. const L& _l;
  113. const R& _r;
  114. };
  115. template<typename OpTag, typename A>
  116. struct UnExpr {
  117. UnExpr(const A& a):_a(a) {}
  118. typedef typename OpTag::returnType returnType;
  119. returnType operator[](size_t index) const
  120. {
  121. return OpTag::apply(_a[index]);
  122. }
  123. const A& _a;
  124. };
  125. template<typename T>
  126. struct And
  127. {
  128. typedef T returnType;
  129. static inline returnType apply(T lhs, T rhs) { return lhs&rhs; }
  130. };
  131. template<typename T>
  132. struct Or
  133. {
  134. typedef T returnType;
  135. static inline returnType apply(T lhs, T rhs) { return lhs|rhs; }
  136. };
  137. template<typename T>
  138. struct Negate
  139. {
  140. typedef T returnType;
  141. static inline returnType apply(T a) { return ~a; }
  142. };
  143. template<typename T>
  144. struct Array
  145. {
  146. typedef T returnType;
  147. Array(const T* t):_t(t) {}
  148. const T* _t;
  149. returnType operator[](size_t index) const { return _t[index]; }
  150. };
  151. template<typename T>
  152. Array<T>
  153. array(const T* t) { return Array<T>(t); }
  154. template<typename L, typename R>
  155. BinExpr<L, And<typename L::returnType>, R>
  156. operator&(const L& l, const R& r)
  157. {
  158. return BinExpr<L, And<typename L::returnType>, R>(l, r);
  159. }
  160. template<typename L, typename R>
  161. BinExpr<L, Or<typename L::returnType>, R>
  162. operator|(const L& l, const R& r)
  163. {
  164. return BinExpr<L, Or<typename L::returnType>, R>(l, r);
  165. }
  166. template<typename A>
  167. UnExpr<Negate<typename A::returnType>, A>
  168. operator~(const A& a)
  169. {
  170. return UnExpr<Negate<typename A::returnType>, A>(a);
  171. }
  172. } // namespace expr
  173. } // namespace aria2
  174. #endif // _D_ARRAY_FUN_H_