#include "array" #include "boost/array.hpp" #include "boost/coroutine/all.hpp" #include "functional" #include "iostream" namespace detail { template < template class Container_T, class Value_T, size_t Length, size_t Index > class print_impl { public: static void print(const Container_T& current) { print_impl::print(current); std::cout << current[Index] << " "; } }; template < template class Container_T, class Value_T, size_t Length > class print_impl { public: static void print(const Container_T& current) { std::cout << current[0] << " "; } }; } // namespace detail template < template class Container_T, class Value_T, size_t Length > void print(const Container_T& current) { detail::print_impl< Container_T, Value_T, Length, Length - 1 >::print(current); std::cout << std::endl; } namespace detail { //! iterates over values in dimension Index template < template class Container_T, class Value_T, size_t Length, size_t Index > class volume_iterator_impl { public: static void iterate( typename boost::coroutines::coroutine< Container_T >::push_type& sink, Container_T& current, const Container_T& start, const Container_T& end, const Container_T& increment ) { for( current[Index] = start[Index] + increment[Index] / Value_T(2); current[Index] < end[Index]; current[Index] += increment[Index] ) { volume_iterator_impl< Container_T, Value_T, Length, Index - 1 >::iterate( sink, current, start, end, increment ); } } }; //! iterates over values of the last dimension template < template class Container_T, class Value_T, size_t Length > class volume_iterator_impl { public: static void iterate( typename boost::coroutines::coroutine< Container_T >::push_type& sink, Container_T& current, const Container_T& start, const Container_T& end, const Container_T& increment ) { for( current[0] = start[0] + increment[0] / Value_T(2); current[0] < end[0]; current[0] += increment[0] ) { sink(current); } } }; } // namespace detail template < template class Container_T, class Value_T, size_t Length > typename boost::coroutines::coroutine< Container_T >::pull_type volume_iterator( const Container_T& start, const Container_T& end, const size_t samples ) { Container_T increment; for (size_t i = 0; i < Length; i++) { increment[i] = (end[i] - start[i]) / samples; } return typename boost::coroutines::coroutine< Container_T >::pull_type( std::bind( &detail::volume_iterator_impl< Container_T, Value_T, Length, Length - 1 >::iterate, std::placeholders::_1, Container_T(), start, end, increment ) ); } int main() { const size_t samples = 2; std::cout << "Number of samples per dimension: " << samples << std::endl << std::endl; std::cout << "std::array:" << std::endl; { std::array start, end; for (size_t i = 0; i < start.size(); i++) { end[i] = (i + 1); start[i] = -end[i]; } std::cout << "start: "; print(start); std::cout << "end: "; print(end); std::cout << "iteration:" << std::endl; for (const auto& i: volume_iterator(start, end, samples)) { print(i); } std::cout << std::endl; } std::cout << "std::array:" << std::endl; { std::array start, end; for (size_t i = 0; i < start.size(); i++) { end[i] = 2 * (i + 1); start[i] = -end[i]; } std::cout << "start: "; print(start); std::cout << "end: "; print(end); std::cout << "iteration:" << std::endl; for (const auto& i: volume_iterator(start, end, samples)) { print(i); } std::cout << std::endl; } std::cout << "boost::array:" << std::endl; { boost::array start, end; for (size_t i = 0; i < start.size(); i++) { end[i] = (i + 2) * (i + 2); start[i] = -end[i]; } std::cout << "start: "; print(start); std::cout << "end: "; print(end); std::cout << "iteration:" << std::endl; for (const auto& i: volume_iterator(start, end, samples)) { print(i); } std::cout << std::endl; } return 0; }