You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.8 KiB
129 lines
4.8 KiB
/*
|
|
Copyright 2005-2014 Intel Corporation. All Rights Reserved.
|
|
|
|
This file is part of Threading Building Blocks.
|
|
|
|
Threading Building Blocks is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License
|
|
version 2 as published by the Free Software Foundation.
|
|
|
|
Threading Building Blocks is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Threading Building Blocks; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
As a special exception, you may use this file as part of a free software
|
|
library without restriction. Specifically, if other files instantiate
|
|
templates or use macros or inline functions from this file, or you compile
|
|
this file and link it with other files to produce an executable, this
|
|
file does not by itself cause the resulting executable to be covered by
|
|
the GNU General Public License. This exception does not however
|
|
invalidate any other reasons why the executable file might be covered by
|
|
the GNU General Public License.
|
|
*/
|
|
|
|
#ifndef __TBB_blocked_range_H
|
|
#define __TBB_blocked_range_H
|
|
|
|
#include "tbb_stddef.h"
|
|
|
|
namespace tbb {
|
|
|
|
/** \page range_req Requirements on range concept
|
|
Class \c R implementing the concept of range must define:
|
|
- \code R::R( const R& ); \endcode Copy constructor
|
|
- \code R::~R(); \endcode Destructor
|
|
- \code bool R::is_divisible() const; \endcode True if range can be partitioned into two subranges
|
|
- \code bool R::empty() const; \endcode True if range is empty
|
|
- \code R::R( R& r, split ); \endcode Split range \c r into two subranges.
|
|
**/
|
|
|
|
//! A range over which to iterate.
|
|
/** @ingroup algorithms */
|
|
template<typename Value>
|
|
class blocked_range {
|
|
public:
|
|
//! Type of a value
|
|
/** Called a const_iterator for sake of algorithms that need to treat a blocked_range
|
|
as an STL container. */
|
|
typedef Value const_iterator;
|
|
|
|
//! Type for size of a range
|
|
typedef std::size_t size_type;
|
|
|
|
//! Construct range with default-constructed values for begin and end.
|
|
/** Requires that Value have a default constructor. */
|
|
blocked_range() : my_end(), my_begin() {}
|
|
|
|
//! Construct range over half-open interval [begin,end), with the given grainsize.
|
|
blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) :
|
|
my_end(end_), my_begin(begin_), my_grainsize(grainsize_)
|
|
{
|
|
__TBB_ASSERT( my_grainsize>0, "grainsize must be positive" );
|
|
}
|
|
|
|
//! Beginning of range.
|
|
const_iterator begin() const {return my_begin;}
|
|
|
|
//! One past last value in range.
|
|
const_iterator end() const {return my_end;}
|
|
|
|
//! Size of the range
|
|
/** Unspecified if end()<begin(). */
|
|
size_type size() const {
|
|
__TBB_ASSERT( !(end()<begin()), "size() unspecified if end()<begin()" );
|
|
return size_type(my_end-my_begin);
|
|
}
|
|
|
|
//! The grain size for this range.
|
|
size_type grainsize() const {return my_grainsize;}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Methods that implement Range concept
|
|
//------------------------------------------------------------------------
|
|
|
|
//! True if range is empty.
|
|
bool empty() const {return !(my_begin<my_end);}
|
|
|
|
//! True if range is divisible.
|
|
/** Unspecified if end()<begin(). */
|
|
bool is_divisible() const {return my_grainsize<size();}
|
|
|
|
//! Split range.
|
|
/** The new Range *this has the second half, the old range r has the first half.
|
|
Unspecified if end()<begin() or !is_divisible(). */
|
|
blocked_range( blocked_range& r, split ) :
|
|
my_end(r.my_end),
|
|
my_begin(do_split(r)),
|
|
my_grainsize(r.my_grainsize)
|
|
{}
|
|
|
|
private:
|
|
/** NOTE: my_end MUST be declared before my_begin, otherwise the forking constructor will break. */
|
|
Value my_end;
|
|
Value my_begin;
|
|
size_type my_grainsize;
|
|
|
|
//! Auxiliary function used by forking constructor.
|
|
/** Using this function lets us not require that Value support assignment or default construction. */
|
|
static Value do_split( blocked_range& r ) {
|
|
__TBB_ASSERT( r.is_divisible(), "cannot split blocked_range that is not divisible" );
|
|
Value middle = r.my_begin + (r.my_end-r.my_begin)/2u;
|
|
r.my_end = middle;
|
|
return middle;
|
|
}
|
|
|
|
template<typename RowValue, typename ColValue>
|
|
friend class blocked_range2d;
|
|
|
|
template<typename RowValue, typename ColValue, typename PageValue>
|
|
friend class blocked_range3d;
|
|
};
|
|
|
|
} // namespace tbb
|
|
|
|
#endif /* __TBB_blocked_range_H */
|