Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:48:26

0001 /* Copyright 2016-2019 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See http://www.boost.org/libs/poly_collection for library home page.
0007  */
0008 
0009 #ifndef BOOST_POLY_COLLECTION_DETAIL_STRIDE_ITERATOR_HPP
0010 #define BOOST_POLY_COLLECTION_DETAIL_STRIDE_ITERATOR_HPP
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include <boost/config.hpp>
0017 #include <boost/detail/workaround.hpp>
0018 #include <boost/iterator/iterator_facade.hpp>
0019 #include <type_traits>
0020 
0021 namespace boost{
0022 
0023 namespace poly_collection{
0024 
0025 namespace detail{
0026 
0027 /* random-access iterator to Value elements laid out stride *chars* apart */
0028 
0029 template<typename Value>
0030 class stride_iterator:
0031   public boost::iterator_facade<
0032     stride_iterator<Value>,
0033     Value,
0034     boost::random_access_traversal_tag
0035   >
0036 {
0037 public:
0038   stride_iterator()=default;
0039   stride_iterator(Value* p,std::size_t stride)noexcept:p{p},stride_{stride}{}
0040   stride_iterator(const stride_iterator&)=default;
0041   stride_iterator& operator=(const stride_iterator&)=default;
0042 
0043   template<
0044     typename NonConstValue,
0045     typename std::enable_if<
0046       std::is_same<Value,const NonConstValue>::value>::type* =nullptr
0047   >
0048   stride_iterator(const stride_iterator<NonConstValue>& x)noexcept:
0049     p{x.p},stride_{x.stride_}{}
0050 
0051   template<
0052     typename NonConstValue,
0053     typename std::enable_if<
0054       std::is_same<Value,const NonConstValue>::value>::type* =nullptr
0055   >
0056   stride_iterator& operator=(const stride_iterator<NonConstValue>& x)noexcept
0057   {
0058     p=x.p;stride_=x.stride_;
0059     return *this;
0060   }
0061 
0062   /* interoperability with [Derived]Value* */
0063 
0064   stride_iterator& operator=(Value* p_)noexcept{p=p_;return *this;}
0065   operator Value*()const noexcept{return p;}
0066 
0067 #include <boost/poly_collection/detail/begin_no_sanitize.hpp>
0068 
0069   template<
0070     typename DerivedValue,
0071     typename std::enable_if<
0072       std::is_base_of<Value,DerivedValue>::value&&
0073       (!std::is_const<Value>::value||std::is_const<DerivedValue>::value)
0074     >::type* =nullptr
0075   >
0076   BOOST_POLY_COLLECTION_NO_SANITIZE
0077   explicit operator DerivedValue*()const noexcept
0078   {return static_cast<DerivedValue*>(p);}
0079 
0080 #include <boost/poly_collection/detail/end_no_sanitize.hpp>
0081 
0082   std::size_t stride()const noexcept{return stride_;}
0083 
0084 private:
0085   template<typename>
0086   friend class stride_iterator;
0087 
0088   using char_pointer=typename std::conditional<
0089     std::is_const<Value>::value,
0090     const char*,
0091     char*
0092   >::type;
0093 
0094   static char_pointer char_ptr(Value* p)noexcept
0095     {return reinterpret_cast<char_pointer>(p);}
0096   static Value*       value_ptr(char_pointer p)noexcept
0097     {return reinterpret_cast<Value*>(p);}
0098 
0099   friend class boost::iterator_core_access;
0100 
0101   Value& dereference()const noexcept{return *p;}
0102   bool equal(const stride_iterator& x)const noexcept{return p==x.p;}
0103   void increment()noexcept{p=value_ptr(char_ptr(p)+stride_);}
0104   void decrement()noexcept{p=value_ptr(char_ptr(p)-stride_);}
0105   template<typename Integral>
0106   void advance(Integral n)noexcept
0107     {p=value_ptr(char_ptr(p)+n*(std::ptrdiff_t)stride_);}
0108   std::ptrdiff_t distance_to(const stride_iterator& x)const noexcept
0109     {return (char_ptr(x.p)-char_ptr(p))/(std::ptrdiff_t)stride_;}          
0110 
0111   Value*      p;
0112   std::size_t stride_;
0113 };
0114 
0115 } /* namespace poly_collection::detail */
0116 
0117 } /* namespace poly_collection */
0118 
0119 } /* namespace boost */
0120 
0121 #endif