File indexing completed on 2025-07-11 08:18:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_NUMERIC_ODEINT_UTIL_SPLIT_ADAPTOR_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_UTIL_SPLIT_ADAPTOR_INCLUDED
0021
0022 #include <boost/numeric/odeint/tools/assert.hpp>
0023 #include <boost/range/adaptor/argument_fwd.hpp>
0024 #include <boost/range/size_type.hpp>
0025 #include <boost/range/iterator_range.hpp>
0026 #include <algorithm>
0027
0028 namespace boost {
0029 namespace numeric {
0030 namespace odeint {
0031 namespace detail {
0032
0033
0034 inline std::pair<std::size_t, std::size_t>
0035 split_offsets( std::size_t total_length, std::size_t index, std::size_t parts )
0036 {
0037 BOOST_NUMERIC_ODEINT_ASSERT( parts > 0 );
0038 BOOST_NUMERIC_ODEINT_ASSERT( index < parts );
0039 const std::size_t
0040 slice = total_length / parts,
0041 partial = total_length % parts,
0042 lo = (std::min)(index, partial),
0043 hi = (std::max<std::ptrdiff_t>)(0, index - partial),
0044 begin_offset = lo * (slice + 1) + hi * slice,
0045 length = slice + (index < partial ? 1 : 0),
0046 end_offset = begin_offset + length;
0047 return std::make_pair( begin_offset, end_offset );
0048 }
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 template< class RandomAccessRange >
0060 inline iterator_range< typename range_iterator<RandomAccessRange>::type >
0061 make_split_range( RandomAccessRange& rng, std::size_t index, std::size_t parts )
0062 {
0063 const std::pair<std::size_t, std::size_t> off = split_offsets(boost::size(rng), index, parts);
0064 return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second );
0065 }
0066
0067 template< class RandomAccessRange >
0068 inline iterator_range< typename range_iterator<const RandomAccessRange>::type >
0069 make_split_range( const RandomAccessRange& rng, std::size_t index, std::size_t parts )
0070 {
0071 const std::pair<std::size_t, std::size_t> off = split_offsets(boost::size(rng), index, parts);
0072 return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second );
0073 }
0074
0075
0076 struct split
0077 {
0078 split(std::size_t index, std::size_t parts)
0079 : index(index), parts(parts) {}
0080 std::size_t index, parts;
0081 };
0082
0083 template< class RandomAccessRange >
0084 inline iterator_range< typename range_iterator<RandomAccessRange>::type >
0085 operator|( RandomAccessRange& rng, const split& f )
0086 {
0087 return make_split_range( rng, f.index, f.parts );
0088 }
0089
0090 template< class RandomAccessRange >
0091 inline iterator_range< typename range_iterator<const RandomAccessRange>::type >
0092 operator|( const RandomAccessRange& rng, const split& f )
0093 {
0094 return make_split_range( rng, f.index, f.parts );
0095 }
0096
0097
0098 }
0099 }
0100 }
0101 }
0102
0103 #endif