File indexing completed on 2025-01-18 09:42:58
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/range/adaptor/argument_fwd.hpp>
0023 #include <boost/range/size_type.hpp>
0024 #include <boost/range/iterator_range.hpp>
0025 #include <algorithm>
0026
0027 namespace boost {
0028 namespace numeric {
0029 namespace odeint {
0030 namespace detail {
0031
0032
0033 inline std::pair<std::size_t, std::size_t>
0034 split_offsets( std::size_t total_length, std::size_t index, std::size_t parts )
0035 {
0036 BOOST_ASSERT( parts > 0 );
0037 BOOST_ASSERT( index < parts );
0038 const std::size_t
0039 slice = total_length / parts,
0040 partial = total_length % parts,
0041 lo = (std::min)(index, partial),
0042 hi = (std::max<std::ptrdiff_t>)(0, index - partial),
0043 begin_offset = lo * (slice + 1) + hi * slice,
0044 length = slice + (index < partial ? 1 : 0),
0045 end_offset = begin_offset + length;
0046 return std::make_pair( begin_offset, end_offset );
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template< class RandomAccessRange >
0059 inline iterator_range< typename range_iterator<RandomAccessRange>::type >
0060 make_split_range( RandomAccessRange& rng, std::size_t index, std::size_t parts )
0061 {
0062 const std::pair<std::size_t, std::size_t> off = split_offsets(boost::size(rng), index, parts);
0063 return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second );
0064 }
0065
0066 template< class RandomAccessRange >
0067 inline iterator_range< typename range_iterator<const RandomAccessRange>::type >
0068 make_split_range( const RandomAccessRange& rng, std::size_t index, std::size_t parts )
0069 {
0070 const std::pair<std::size_t, std::size_t> off = split_offsets(boost::size(rng), index, parts);
0071 return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second );
0072 }
0073
0074
0075 struct split
0076 {
0077 split(std::size_t index, std::size_t parts)
0078 : index(index), parts(parts) {}
0079 std::size_t index, parts;
0080 };
0081
0082 template< class RandomAccessRange >
0083 inline iterator_range< typename range_iterator<RandomAccessRange>::type >
0084 operator|( RandomAccessRange& rng, const split& f )
0085 {
0086 return make_split_range( rng, f.index, f.parts );
0087 }
0088
0089 template< class RandomAccessRange >
0090 inline iterator_range< typename range_iterator<const RandomAccessRange>::type >
0091 operator|( const RandomAccessRange& rng, const split& f )
0092 {
0093 return make_split_range( rng, f.index, f.parts );
0094 }
0095
0096
0097 }
0098 }
0099 }
0100 }
0101
0102 #endif