Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:58

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/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 /** \brief Returns the begin and end offset for a sub-range */
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 /** \brief Return the sub-range `index` from a range which is split into `parts`.
0050  *
0051  * For example, splitting a range into three about equal-sized sub-ranges:
0052  * \code
0053  * sub0 = make_split_range(rng, 0, 3);
0054  * sub1 = rng | split(1, 3);
0055  * sub2 = rng | split(2, 3);
0056  * \endcode
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