Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:17

0001 // Boost.Range library
0002 //
0003 //  Copyright Neil Groves 2010. Use, modification and
0004 //  distribution is subject to the Boost Software License, Version
0005 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006 //  http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 //
0009 // For more information, see http://www.boost.org/libs/range/
0010 //
0011 #ifndef BOOST_RANGE_IRANGE_HPP_INCLUDED
0012 #define BOOST_RANGE_IRANGE_HPP_INCLUDED
0013 
0014 #include <boost/assert.hpp>
0015 #include <boost/iterator/iterator_facade.hpp>
0016 #include <boost/range/iterator_range.hpp>
0017 
0018 namespace boost
0019 {
0020     namespace range_detail
0021     {
0022         // integer_iterator is an iterator over an integer sequence that
0023         // is bounded only by the limits of the underlying integer
0024         // representation.
0025         //
0026         // This is useful for implementing the irange(first, last)
0027         // function.
0028         //
0029         // Note:
0030         // This use of this iterator and irange is appreciably less
0031         // performant than the corresponding hand-written integer
0032         // loop on many compilers.
0033         template<typename Integer>
0034         class integer_iterator
0035             : public boost::iterator_facade<
0036                         integer_iterator<Integer>,
0037                         Integer,
0038                         boost::random_access_traversal_tag,
0039                         Integer,
0040                         std::ptrdiff_t
0041                     >
0042         {
0043             typedef boost::iterator_facade<
0044                         integer_iterator<Integer>,
0045                         Integer,
0046                         boost::random_access_traversal_tag,
0047                         Integer,
0048                         std::ptrdiff_t
0049                     > base_t;
0050         public:
0051             typedef typename base_t::value_type value_type;
0052             typedef typename base_t::difference_type difference_type;
0053             typedef typename base_t::reference reference;
0054             typedef std::random_access_iterator_tag iterator_category;
0055 
0056             integer_iterator() : m_value() {}
0057             explicit integer_iterator(value_type x) : m_value(x) {}
0058 
0059         private:
0060             void increment()
0061             {
0062                 ++m_value;
0063             }
0064 
0065             void decrement()
0066             {
0067                 --m_value;
0068             }
0069 
0070             void advance(difference_type offset)
0071             {
0072                 m_value += offset;
0073             }
0074 
0075             difference_type distance_to(const integer_iterator& other) const
0076             {
0077                 return is_signed<value_type>::value
0078                     ? (other.m_value - m_value)
0079                     : (other.m_value >= m_value)
0080                         ? static_cast<difference_type>(other.m_value - m_value)
0081                         : -static_cast<difference_type>(m_value - other.m_value);
0082             }
0083 
0084             bool equal(const integer_iterator& other) const
0085             {
0086                 return m_value == other.m_value;
0087             }
0088 
0089             reference dereference() const
0090             {
0091                 return m_value;
0092             }
0093 
0094             friend class ::boost::iterator_core_access;
0095             value_type m_value;
0096         };
0097 
0098         // integer_iterator_with_step is similar in nature to the
0099         // integer_iterator but provides the ability to 'move' in
0100         // a number of steps specified at construction time.
0101         //
0102         // The three variable implementation provides the best guarantees
0103         // of loop termination upon various combinations of input.
0104         //
0105         // While this design is less performant than some less
0106         // safe alternatives, the use of ranges and iterators to
0107         // perform counting will never be optimal anyhow, hence
0108         // if optimal performance is desired a hand-coded loop
0109         // is the solution.
0110         template<typename Integer>
0111         class integer_iterator_with_step
0112             : public boost::iterator_facade<
0113                         integer_iterator_with_step<Integer>,
0114                         Integer,
0115                         boost::random_access_traversal_tag,
0116                         Integer,
0117                         std::ptrdiff_t
0118                     >
0119         {
0120             typedef boost::iterator_facade<
0121                         integer_iterator_with_step<Integer>,
0122                         Integer,
0123                         boost::random_access_traversal_tag,
0124                         Integer,
0125                         std::ptrdiff_t
0126                     > base_t;
0127         public:
0128             typedef typename base_t::value_type value_type;
0129             typedef typename base_t::difference_type difference_type;
0130             typedef typename base_t::reference reference;
0131             typedef std::random_access_iterator_tag iterator_category;
0132 
0133             integer_iterator_with_step(value_type first, difference_type step, value_type step_size)
0134                 : m_first(first)
0135                 , m_step(step)
0136                 , m_step_size(step_size)
0137             {
0138             }
0139 
0140         private:
0141             void increment()
0142             {
0143                 ++m_step;
0144             }
0145 
0146             void decrement()
0147             {
0148                 --m_step;
0149             }
0150 
0151             void advance(difference_type offset)
0152             {
0153                 m_step += offset;
0154             }
0155 
0156             difference_type distance_to(const integer_iterator_with_step& other) const
0157             {
0158                 return other.m_step - m_step;
0159             }
0160 
0161             bool equal(const integer_iterator_with_step& other) const
0162             {
0163                 return m_step == other.m_step;
0164             }
0165 
0166             reference dereference() const
0167             {
0168                 return m_first + (m_step * m_step_size);
0169             }
0170 
0171             friend class ::boost::iterator_core_access;
0172             value_type m_first;
0173             difference_type m_step;
0174             difference_type m_step_size;
0175         };
0176 
0177     } // namespace range_detail
0178 
0179     template<typename Integer>
0180     class integer_range
0181         : public iterator_range< range_detail::integer_iterator<Integer> >
0182     {
0183         typedef range_detail::integer_iterator<Integer> iterator_t;
0184         typedef iterator_range<iterator_t> base_t;
0185     public:
0186         integer_range(Integer first, Integer last)
0187             : base_t(iterator_t(first), iterator_t(last))
0188         {
0189         }
0190     };
0191 
0192     template<typename Integer>
0193     class strided_integer_range
0194     : public iterator_range< range_detail::integer_iterator_with_step<Integer> >
0195     {
0196         typedef range_detail::integer_iterator_with_step<Integer> iterator_t;
0197         typedef iterator_range<iterator_t> base_t;
0198     public:
0199         template<typename Iterator>
0200         strided_integer_range(Iterator first, Iterator last)
0201             : base_t(first, last)
0202         {
0203         }
0204     };
0205 
0206     template<typename Integer>
0207     integer_range<Integer>
0208     irange(Integer first, Integer last)
0209     {
0210         BOOST_ASSERT( first <= last );
0211         return integer_range<Integer>(first, last);
0212     }
0213 
0214     template<typename Integer, typename StepSize>
0215     strided_integer_range<Integer>
0216         irange(Integer first, Integer last, StepSize step_size)
0217     {
0218         BOOST_ASSERT( step_size != 0 );
0219         BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) );
0220 
0221         typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t;
0222 
0223         const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size);
0224         const Integer l = step_size >= 0 ? last : first;
0225         const Integer f = step_size >= 0 ? first : last;
0226         const std::ptrdiff_t num_steps = (l - f) / sz + ((l - f) % sz ? 1 : 0);
0227         BOOST_ASSERT(num_steps >= 0);
0228 
0229         return strided_integer_range<Integer>(
0230             iterator_t(first, 0, step_size),
0231             iterator_t(first, num_steps, step_size));
0232     }
0233 
0234     template<typename Integer>
0235     integer_range<Integer>
0236     irange(Integer last)
0237     {
0238         return integer_range<Integer>(static_cast<Integer>(0), last);
0239     }
0240 
0241 } // namespace boost
0242 
0243 #endif // include guard