123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- /*
- [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/numeric/odeint/tools/assert.hpp>
- #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_NUMERIC_ODEINT_ASSERT( parts > 0 );
- BOOST_NUMERIC_ODEINT_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
|