/* */ #ifndef D_ARRAY_FUN_H #define D_ARRAY_FUN_H #include #include namespace aria2 { // calculate length of array template char (&char_array_ref_fun(T (&)[N]))[N]; // For 0 length array template char (&char_array_ref_fun(T (&)[0u]))[0u]; // To calculate size of array at compile time, we use macro here. #define A2_ARRAY_LEN(X) sizeof(char_array_ref_fun(X)) template T* vbegin(T (&a)[N]) { return a; } template T* vend(T (&a)[N]) { return a+N; } template class array_ptr { private: T* array_; // Copies are not allowed. Let's make them private. array_ptr(const array_ptr& s); array_ptr& operator=(const array_ptr& s); template array_ptr& operator=(const array_ptr& s); public: array_ptr():array_(0) {} explicit array_ptr(T* array):array_(array) {} ~array_ptr() { delete [] array_; } operator T*() { return array_; } operator const T*() const { return array_; } void reset(T* array) { array_ = array; } }; template class array_wrapper { private: T array_[N]; public: array_wrapper() {} operator T*() { return array_; } operator const T*() const { return array_; } size_t size() const { return N; } }; // Expression Template for array namespace expr { template struct BinExpr { BinExpr(const L& l, const R& r):l_(l), r_(r) {} typedef typename OpTag::returnType returnType; returnType operator[](size_t index) const { return OpTag::apply(l_[index], r_[index]); } 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 returnType apply(T lhs, T rhs) { return lhs&rhs; } }; template struct Or { typedef T returnType; static inline returnType apply(T lhs, T rhs) { return lhs|rhs; } }; template struct Negate { typedef T returnType; static inline returnType apply(T a) { return ~a; } }; template struct Array { typedef T returnType; Array(const T* t):t_(t) {} const T* t_; returnType operator[](size_t index) const { return t_[index]; } }; template Array array(const T* t) { return Array(t); } template BinExpr, R> operator&(const L& l, const R& r) { return BinExpr, R>(l, r); } template BinExpr, R> operator|(const L& l, const R& r) { return BinExpr, R>(l, r); } template UnExpr, A> operator~(const A& a) { return UnExpr, A>(a); } } // namespace expr } // namespace aria2 #endif // D_ARRAY_FUN_H