189 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
// Copyright 2002 The Trustees of Indiana University.
 | 
						|
 | 
						|
// Use, modification and distribution is subject to 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)
 | 
						|
 | 
						|
//  Boost.MultiArray Library
 | 
						|
//  Authors: Ronald Garcia
 | 
						|
//           Jeremy Siek
 | 
						|
//           Andrew Lumsdaine
 | 
						|
//  See http://www.boost.org/libs/multi_array for documentation.
 | 
						|
 | 
						|
#ifndef BOOST_INDEX_RANGE_RG071801_HPP
 | 
						|
#define BOOST_INDEX_RANGE_RG071801_HPP
 | 
						|
 | 
						|
#include <boost/config.hpp>
 | 
						|
#include <utility>
 | 
						|
#include <boost/limits.hpp>
 | 
						|
 | 
						|
// For representing intervals, also with stride.
 | 
						|
// A degenerate range is a range with one element.
 | 
						|
 | 
						|
// Thanks to Doug Gregor for the really cool idea of using the
 | 
						|
// comparison operators to express various interval types!
 | 
						|
 | 
						|
// Internally, we represent the interval as half-open.
 | 
						|
 | 
						|
namespace boost {
 | 
						|
namespace detail {
 | 
						|
namespace multi_array {
 | 
						|
 | 
						|
  template <typename Index,typename SizeType>
 | 
						|
  class index_range {
 | 
						|
  public:
 | 
						|
    typedef Index index;
 | 
						|
    typedef SizeType size_type;
 | 
						|
 | 
						|
  private:
 | 
						|
    static index from_start()
 | 
						|
      { return (std::numeric_limits<index>::min)(); }
 | 
						|
 | 
						|
    static index to_end()
 | 
						|
      { return (std::numeric_limits<index>::max)(); }
 | 
						|
 | 
						|
  public:
 | 
						|
 | 
						|
    index_range()
 | 
						|
    {
 | 
						|
      start_ = from_start();
 | 
						|
      finish_ = to_end();
 | 
						|
      stride_ = 1;
 | 
						|
      degenerate_ = false;
 | 
						|
    }
 | 
						|
 | 
						|
    explicit index_range(index pos)
 | 
						|
    {
 | 
						|
      start_ = pos;
 | 
						|
      finish_ = pos+1;
 | 
						|
      stride_ = 1;
 | 
						|
      degenerate_ = true;
 | 
						|
    }
 | 
						|
 | 
						|
    explicit index_range(index start, index finish, index stride=1)
 | 
						|
      : start_(start), finish_(finish), stride_(stride),
 | 
						|
        degenerate_(false)
 | 
						|
    { }
 | 
						|
 | 
						|
 | 
						|
    // These are for chaining assignments to an index_range
 | 
						|
    index_range& start(index s) {
 | 
						|
      start_ = s;
 | 
						|
      degenerate_ = false;
 | 
						|
      return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    index_range& finish(index f) {
 | 
						|
      finish_ = f;
 | 
						|
      degenerate_ = false;
 | 
						|
      return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    index_range& stride(index s) { stride_ = s; return *this; }
 | 
						|
 | 
						|
    index start() const
 | 
						|
    { 
 | 
						|
      return start_; 
 | 
						|
    }
 | 
						|
 | 
						|
    index get_start(index low_index_range = index_range::from_start()) const
 | 
						|
    { 
 | 
						|
      if (start_ == from_start())
 | 
						|
        return low_index_range;
 | 
						|
      return start_; 
 | 
						|
    }
 | 
						|
 | 
						|
    index finish() const
 | 
						|
    {
 | 
						|
      return finish_;
 | 
						|
    }
 | 
						|
 | 
						|
    index get_finish(index high_index_range = index_range::to_end()) const
 | 
						|
    {
 | 
						|
      if (finish_ == to_end())
 | 
						|
        return high_index_range;
 | 
						|
      return finish_;
 | 
						|
    }
 | 
						|
 | 
						|
    index stride() const { return stride_; }
 | 
						|
 | 
						|
    void set_index_range(index start, index finish, index stride=1)
 | 
						|
    {
 | 
						|
      start_ = start;
 | 
						|
      finish_ = finish;
 | 
						|
      stride_ = stride;
 | 
						|
    }
 | 
						|
 | 
						|
    static index_range all() 
 | 
						|
    { return index_range(from_start(), to_end(), 1); }
 | 
						|
 | 
						|
    bool is_degenerate() const { return degenerate_; }
 | 
						|
 | 
						|
    index_range operator-(index shift) const
 | 
						|
    { 
 | 
						|
      return index_range(start_ - shift, finish_ - shift, stride_); 
 | 
						|
    }
 | 
						|
 | 
						|
    index_range operator+(index shift) const
 | 
						|
    { 
 | 
						|
      return index_range(start_ + shift, finish_ + shift, stride_); 
 | 
						|
    }
 | 
						|
 | 
						|
    index operator[](unsigned i) const
 | 
						|
    {
 | 
						|
      return start_ + i * stride_;
 | 
						|
    }
 | 
						|
 | 
						|
    index operator()(unsigned i) const
 | 
						|
    {
 | 
						|
      return start_ + i * stride_;
 | 
						|
    }
 | 
						|
 | 
						|
    // add conversion to std::slice?
 | 
						|
 | 
						|
  public:
 | 
						|
    index start_, finish_, stride_;
 | 
						|
    bool degenerate_;
 | 
						|
  };
 | 
						|
 | 
						|
  // Express open and closed interval end-points using the comparison
 | 
						|
  // operators.
 | 
						|
 | 
						|
  // left closed
 | 
						|
  template <typename Index, typename SizeType>
 | 
						|
  inline index_range<Index,SizeType>
 | 
						|
  operator<=(Index s, const index_range<Index,SizeType>& r)
 | 
						|
  {
 | 
						|
    return index_range<Index,SizeType>(s, r.finish(), r.stride());
 | 
						|
  }
 | 
						|
 | 
						|
  // left open
 | 
						|
  template <typename Index, typename SizeType>
 | 
						|
  inline index_range<Index,SizeType>
 | 
						|
  operator<(Index s, const index_range<Index,SizeType>& r)
 | 
						|
  {
 | 
						|
    return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
 | 
						|
  }
 | 
						|
 | 
						|
  // right open
 | 
						|
  template <typename Index, typename SizeType>
 | 
						|
  inline index_range<Index,SizeType>
 | 
						|
  operator<(const index_range<Index,SizeType>& r, Index f)
 | 
						|
  {
 | 
						|
    return index_range<Index,SizeType>(r.start(), f, r.stride());
 | 
						|
  }
 | 
						|
 | 
						|
  // right closed
 | 
						|
  template <typename Index, typename SizeType>
 | 
						|
  inline index_range<Index,SizeType>
 | 
						|
  operator<=(const index_range<Index,SizeType>& r, Index f)
 | 
						|
  {
 | 
						|
    return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
 | 
						|
  }
 | 
						|
 | 
						|
} // namespace multi_array
 | 
						|
} // namespace detail  
 | 
						|
} // namespace boost
 | 
						|
 | 
						|
#endif // BOOST_INDEX_RANGE_RG071801_HPP
 |