Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:06

0001 // Copyright 2002 The Trustees of Indiana University.
0002 
0003 // Use, modification and distribution is subject to the Boost Software 
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 //  Boost.MultiArray Library
0008 //  Authors: Ronald Garcia
0009 //           Jeremy Siek
0010 //           Andrew Lumsdaine
0011 //  See http://www.boost.org/libs/multi_array for documentation.
0012 
0013 #ifndef BOOST_MULTI_ARRAY_INDEX_RANGE_HPP
0014 #define BOOST_MULTI_ARRAY_INDEX_RANGE_HPP
0015 
0016 #include <boost/config.hpp>
0017 #include <utility>
0018 #include <boost/limits.hpp>
0019 
0020 // For representing intervals, also with stride.
0021 // A degenerate range is a range with one element.
0022 
0023 // Thanks to Doug Gregor for the really cool idea of using the
0024 // comparison operators to express various interval types!
0025 
0026 // Internally, we represent the interval as half-open.
0027 
0028 namespace boost {
0029 namespace detail {
0030 namespace multi_array {
0031 
0032   template <typename Index,typename SizeType>
0033   class index_range {
0034   public:
0035     typedef Index index;
0036     typedef SizeType size_type;
0037 
0038   private:
0039     static index from_start()
0040       { return (std::numeric_limits<index>::min)(); }
0041 
0042     static index to_end()
0043       { return (std::numeric_limits<index>::max)(); }
0044 
0045   public:
0046 
0047     index_range()
0048     {
0049       start_ = from_start();
0050       finish_ = to_end();
0051       stride_ = 1;
0052       degenerate_ = false;
0053     }
0054 
0055     explicit index_range(index pos)
0056     {
0057       start_ = pos;
0058       finish_ = pos+1;
0059       stride_ = 1;
0060       degenerate_ = true;
0061     }
0062 
0063     explicit index_range(index start, index finish, index stride=1)
0064       : start_(start), finish_(finish), stride_(stride),
0065         degenerate_(false)
0066     { }
0067 
0068 
0069     // These are for chaining assignments to an index_range
0070     index_range& start(index s) {
0071       start_ = s;
0072       degenerate_ = false;
0073       return *this;
0074     }
0075 
0076     index_range& finish(index f) {
0077       finish_ = f;
0078       degenerate_ = false;
0079       return *this;
0080     }
0081 
0082     index_range& stride(index s) { stride_ = s; return *this; }
0083 
0084     index start() const
0085     { 
0086       return start_; 
0087     }
0088 
0089     index get_start(index low_index_range = index_range::from_start()) const
0090     { 
0091       if (start_ == from_start())
0092         return low_index_range;
0093       return start_; 
0094     }
0095 
0096     index finish() const
0097     {
0098       return finish_;
0099     }
0100 
0101     index get_finish(index high_index_range = index_range::to_end()) const
0102     {
0103       if (finish_ == to_end())
0104         return high_index_range;
0105       return finish_;
0106     }
0107 
0108     index stride() const { return stride_; }
0109 
0110     size_type size(index idx) const
0111     {
0112       return (start_ == from_start() || finish_ == to_end())
0113         ? idx : ((finish_ - start_) / stride_);
0114     }
0115 
0116     void set_index_range(index start, index finish, index stride=1)
0117     {
0118       start_ = start;
0119       finish_ = finish;
0120       stride_ = stride;
0121     }
0122 
0123     static index_range all() 
0124     { return index_range(from_start(), to_end(), 1); }
0125 
0126     bool is_degenerate() const { return degenerate_; }
0127 
0128     index_range operator-(index shift) const
0129     { 
0130       return index_range(start_ - shift, finish_ - shift, stride_); 
0131     }
0132 
0133     index_range operator+(index shift) const
0134     { 
0135       return index_range(start_ + shift, finish_ + shift, stride_); 
0136     }
0137 
0138     index operator[](unsigned i) const
0139     {
0140       return start_ + i * stride_;
0141     }
0142 
0143     index operator()(unsigned i) const
0144     {
0145       return start_ + i * stride_;
0146     }
0147 
0148     // add conversion to std::slice?
0149 
0150   public:
0151     index start_, finish_, stride_;
0152     bool degenerate_;
0153   };
0154 
0155   // Express open and closed interval end-points using the comparison
0156   // operators.
0157 
0158   // left closed
0159   template <typename Index, typename SizeType>
0160   inline index_range<Index,SizeType>
0161   operator<=(Index s, const index_range<Index,SizeType>& r)
0162   {
0163     return index_range<Index,SizeType>(s, r.finish(), r.stride());
0164   }
0165 
0166   // left open
0167   template <typename Index, typename SizeType>
0168   inline index_range<Index,SizeType>
0169   operator<(Index s, const index_range<Index,SizeType>& r)
0170   {
0171     return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
0172   }
0173 
0174   // right open
0175   template <typename Index, typename SizeType>
0176   inline index_range<Index,SizeType>
0177   operator<(const index_range<Index,SizeType>& r, Index f)
0178   {
0179     return index_range<Index,SizeType>(r.start(), f, r.stride());
0180   }
0181 
0182   // right closed
0183   template <typename Index, typename SizeType>
0184   inline index_range<Index,SizeType>
0185   operator<=(const index_range<Index,SizeType>& r, Index f)
0186   {
0187     return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
0188   }
0189 
0190 } // namespace multi_array
0191 } // namespace detail  
0192 } // namespace boost
0193 
0194 #endif