Chris@102
|
1 /*
|
Chris@102
|
2 [auto_generated]
|
Chris@102
|
3 boost/numeric/odeint/util/split_adaptor.hpp
|
Chris@102
|
4
|
Chris@102
|
5 [begin_description]
|
Chris@102
|
6 A range adaptor which returns even-sized slices.
|
Chris@102
|
7 [end_description]
|
Chris@102
|
8
|
Chris@102
|
9 Copyright 2013 Karsten Ahnert
|
Chris@102
|
10 Copyright 2013 Mario Mulansky
|
Chris@102
|
11 Copyright 2013 Pascal Germroth
|
Chris@102
|
12
|
Chris@102
|
13 Distributed under the Boost Software License, Version 1.0.
|
Chris@102
|
14 (See accompanying file LICENSE_1_0.txt or
|
Chris@102
|
15 copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
16 */
|
Chris@102
|
17
|
Chris@102
|
18
|
Chris@102
|
19 #ifndef BOOST_NUMERIC_ODEINT_UTIL_SPLIT_ADAPTOR_INCLUDED
|
Chris@102
|
20 #define BOOST_NUMERIC_ODEINT_UTIL_SPLIT_ADAPTOR_INCLUDED
|
Chris@102
|
21
|
Chris@102
|
22 #include <boost/range/adaptor/argument_fwd.hpp>
|
Chris@102
|
23 #include <boost/range/size_type.hpp>
|
Chris@102
|
24 #include <boost/range/iterator_range.hpp>
|
Chris@102
|
25 #include <algorithm>
|
Chris@102
|
26
|
Chris@102
|
27 namespace boost {
|
Chris@102
|
28 namespace numeric {
|
Chris@102
|
29 namespace odeint {
|
Chris@102
|
30 namespace detail {
|
Chris@102
|
31
|
Chris@102
|
32 /** \brief Returns the begin and end offset for a sub-range */
|
Chris@102
|
33 inline std::pair<std::size_t, std::size_t>
|
Chris@102
|
34 split_offsets( std::size_t total_length, std::size_t index, std::size_t parts )
|
Chris@102
|
35 {
|
Chris@102
|
36 BOOST_ASSERT( parts > 0 );
|
Chris@102
|
37 BOOST_ASSERT( index < parts );
|
Chris@102
|
38 const std::size_t
|
Chris@102
|
39 slice = total_length / parts,
|
Chris@102
|
40 partial = total_length % parts,
|
Chris@102
|
41 lo = (std::min)(index, partial),
|
Chris@102
|
42 hi = (std::max<std::ptrdiff_t>)(0, index - partial),
|
Chris@102
|
43 begin_offset = lo * (slice + 1) + hi * slice,
|
Chris@102
|
44 length = slice + (index < partial ? 1 : 0),
|
Chris@102
|
45 end_offset = begin_offset + length;
|
Chris@102
|
46 return std::make_pair( begin_offset, end_offset );
|
Chris@102
|
47 }
|
Chris@102
|
48
|
Chris@102
|
49 /** \brief Return the sub-range `index` from a range which is split into `parts`.
|
Chris@102
|
50 *
|
Chris@102
|
51 * For example, splitting a range into three about equal-sized sub-ranges:
|
Chris@102
|
52 * \code
|
Chris@102
|
53 * sub0 = make_split_range(rng, 0, 3);
|
Chris@102
|
54 * sub1 = rng | split(1, 3);
|
Chris@102
|
55 * sub2 = rng | split(2, 3);
|
Chris@102
|
56 * \endcode
|
Chris@102
|
57 */
|
Chris@102
|
58 template< class RandomAccessRange >
|
Chris@102
|
59 inline iterator_range< typename range_iterator<RandomAccessRange>::type >
|
Chris@102
|
60 make_split_range( RandomAccessRange& rng, std::size_t index, std::size_t parts )
|
Chris@102
|
61 {
|
Chris@102
|
62 const std::pair<std::size_t, std::size_t> off = split_offsets(boost::size(rng), index, parts);
|
Chris@102
|
63 return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second );
|
Chris@102
|
64 }
|
Chris@102
|
65
|
Chris@102
|
66 template< class RandomAccessRange >
|
Chris@102
|
67 inline iterator_range< typename range_iterator<const RandomAccessRange>::type >
|
Chris@102
|
68 make_split_range( const RandomAccessRange& rng, std::size_t index, std::size_t parts )
|
Chris@102
|
69 {
|
Chris@102
|
70 const std::pair<std::size_t, std::size_t> off = split_offsets(boost::size(rng), index, parts);
|
Chris@102
|
71 return make_iterator_range( boost::begin(rng) + off.first, boost::begin(rng) + off.second );
|
Chris@102
|
72 }
|
Chris@102
|
73
|
Chris@102
|
74
|
Chris@102
|
75 struct split
|
Chris@102
|
76 {
|
Chris@102
|
77 split(std::size_t index, std::size_t parts)
|
Chris@102
|
78 : index(index), parts(parts) {}
|
Chris@102
|
79 std::size_t index, parts;
|
Chris@102
|
80 };
|
Chris@102
|
81
|
Chris@102
|
82 template< class RandomAccessRange >
|
Chris@102
|
83 inline iterator_range< typename range_iterator<RandomAccessRange>::type >
|
Chris@102
|
84 operator|( RandomAccessRange& rng, const split& f )
|
Chris@102
|
85 {
|
Chris@102
|
86 return make_split_range( rng, f.index, f.parts );
|
Chris@102
|
87 }
|
Chris@102
|
88
|
Chris@102
|
89 template< class RandomAccessRange >
|
Chris@102
|
90 inline iterator_range< typename range_iterator<const RandomAccessRange>::type >
|
Chris@102
|
91 operator|( const RandomAccessRange& rng, const split& f )
|
Chris@102
|
92 {
|
Chris@102
|
93 return make_split_range( rng, f.index, f.parts );
|
Chris@102
|
94 }
|
Chris@102
|
95
|
Chris@102
|
96
|
Chris@102
|
97 }
|
Chris@102
|
98 }
|
Chris@102
|
99 }
|
Chris@102
|
100 }
|
Chris@102
|
101
|
Chris@102
|
102 #endif
|