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