// -*-C++-*- #ifndef VEC_MASK_H #define VEC_MASK_H #include namespace vecmathlib { template class mask_t { typedef typename realvec_t::boolvec_t boolvec_t; typedef typename realvec_t::intvec_t intvec_t; static const int size = realvec_t::size; public: std::ptrdiff_t imin, imax; std::ptrdiff_t i; boolvec_t m; bool all_m; public: // Construct a mask from a boolvec mask_t(boolvec_t m_) : m(m_), all_m(all(m)) {} // Construct a mask for a particular location i mask_t(std::ptrdiff_t i_, std::ptrdiff_t imin_, std::ptrdiff_t imax_, std::ptrdiff_t ioff) : imin(imin_), imax(imax_), i(i_) { all_m = i - imin >= 0 && i + size - 1 - imax < 0; if (__builtin_expect(all_m, true)) { m = true; } else { m = (!isignbit(intvec_t(i - imin) + intvec_t::iota()) && isignbit(intvec_t(i + size - 1 - imax) + intvec_t::iota())); } } // Construct a mask for a loop starting at imin, aligned down mask_t(std::ptrdiff_t imin_, std::ptrdiff_t imax_, std::ptrdiff_t ioff) : imin(imin_), imax(imax_), i(imin_ - (ioff + imin_) % size) { all_m = i - imin >= 0 && i + size - 1 - imax < 0; if (__builtin_expect(all_m, true)) { m = true; } else { m = (!isignbit(intvec_t(i - imin) + intvec_t::iota()) && isignbit(intvec_t(i + size - 1 - imax) + intvec_t::iota())); } } // Get current index std::ptrdiff_t index() const { return i; } // Looping condition operator bool() const { return i < imax; } // Loop stepper void operator++() { i += size; all_m = i + size - 1 - imax < 0; if (__builtin_expect(all_m, true)) { m = true; } else { m = isignbit(intvec_t(i + size - 1 - imax) + intvec_t::iota()); } } }; } // namespace vecmathlib #endif // #ifndef VEC_MASK_H