Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:18:11

0001 /*
0002  [auto_generated]
0003  boost/numeric/odeint/util/split_adaptor.hpp
0004 
0005  [begin_description]
0006  A range adaptor which returns even-sized slices.
0007  [end_description]
0008 
0009  Copyright 2013 Karsten Ahnert
0010  Copyright 2013 Mario Mulansky
0011  Copyright 2013 Pascal Germroth
0012 
0013  Distributed under the Boost Software License, Version 1.0.
0014  (See accompanying file LICENSE_1_0.txt or
0015  copy at http://www.boost.org/LICENSE_1_0.txt)
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 /** \brief Returns the begin and end offset for a sub-range */
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 /** \brief Return the sub-range `index` from a range which is split into `parts`.
0051  *
0052  * For example, splitting a range into three about equal-sized sub-ranges:
0053  * \code
0054  * sub0 = make_split_range(rng, 0, 3);
0055  * sub1 = rng | split(1, 3);
0056  * sub2 = rng | split(2, 3);
0057  * \endcode
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