Chris@102: /* Chris@102: [auto_generated] Chris@102: boost/numeric/odeint/util/split_adaptor.hpp Chris@102: Chris@102: [begin_description] Chris@102: A range adaptor which returns even-sized slices. Chris@102: [end_description] Chris@102: Chris@102: Copyright 2013 Karsten Ahnert Chris@102: Copyright 2013 Mario Mulansky Chris@102: Copyright 2013 Pascal Germroth Chris@102: Chris@102: Distributed under the Boost Software License, Version 1.0. Chris@102: (See accompanying file LICENSE_1_0.txt or Chris@102: copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: */ Chris@102: Chris@102: Chris@102: #ifndef BOOST_NUMERIC_ODEINT_UTIL_SPLIT_ADAPTOR_INCLUDED Chris@102: #define BOOST_NUMERIC_ODEINT_UTIL_SPLIT_ADAPTOR_INCLUDED Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: namespace boost { Chris@102: namespace numeric { Chris@102: namespace odeint { Chris@102: namespace detail { Chris@102: Chris@102: /** \brief Returns the begin and end offset for a sub-range */ Chris@102: inline std::pair Chris@102: split_offsets( std::size_t total_length, std::size_t index, std::size_t parts ) Chris@102: { Chris@102: BOOST_ASSERT( parts > 0 ); Chris@102: BOOST_ASSERT( index < parts ); Chris@102: const std::size_t Chris@102: slice = total_length / parts, Chris@102: partial = total_length % parts, Chris@102: lo = (std::min)(index, partial), Chris@102: hi = (std::max)(0, index - partial), Chris@102: begin_offset = lo * (slice + 1) + hi * slice, Chris@102: length = slice + (index < partial ? 1 : 0), Chris@102: end_offset = begin_offset + length; Chris@102: return std::make_pair( begin_offset, end_offset ); Chris@102: } Chris@102: Chris@102: /** \brief Return the sub-range `index` from a range which is split into `parts`. Chris@102: * Chris@102: * For example, splitting a range into three about equal-sized sub-ranges: Chris@102: * \code Chris@102: * sub0 = make_split_range(rng, 0, 3); Chris@102: * sub1 = rng | split(1, 3); Chris@102: * sub2 = rng | split(2, 3); Chris@102: * \endcode Chris@102: */ Chris@102: template< class RandomAccessRange > Chris@102: inline iterator_range< typename range_iterator::type > Chris@102: make_split_range( RandomAccessRange& rng, std::size_t index, std::size_t parts ) Chris@102: { Chris@102: const std::pair off = split_offsets(boost::size(rng), index, parts); Chris@102: return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second ); Chris@102: } Chris@102: Chris@102: template< class RandomAccessRange > Chris@102: inline iterator_range< typename range_iterator::type > Chris@102: make_split_range( const RandomAccessRange& rng, std::size_t index, std::size_t parts ) Chris@102: { Chris@102: const std::pair off = split_offsets(boost::size(rng), index, parts); Chris@102: return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second ); Chris@102: } Chris@102: Chris@102: Chris@102: struct split Chris@102: { Chris@102: split(std::size_t index, std::size_t parts) Chris@102: : index(index), parts(parts) {} Chris@102: std::size_t index, parts; Chris@102: }; Chris@102: Chris@102: template< class RandomAccessRange > Chris@102: inline iterator_range< typename range_iterator::type > Chris@102: operator|( RandomAccessRange& rng, const split& f ) Chris@102: { Chris@102: return make_split_range( rng, f.index, f.parts ); Chris@102: } Chris@102: Chris@102: template< class RandomAccessRange > Chris@102: inline iterator_range< typename range_iterator::type > Chris@102: operator|( const RandomAccessRange& rng, const split& f ) Chris@102: { Chris@102: return make_split_range( rng, f.index, f.parts ); Chris@102: } Chris@102: Chris@102: Chris@102: } Chris@102: } Chris@102: } Chris@102: } Chris@102: Chris@102: #endif