Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:45:56

0001 /* Copyright 2024 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_FIXED_VARIANT_ITERATOR_HPP
0010 #define BOOST_POLY_COLLECTION_DETAIL_FIXED_VARIANT_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 <boost/poly_collection/detail/fixed_variant.hpp>
0020 #include <type_traits>
0021 
0022 namespace boost{
0023 
0024 namespace poly_collection{
0025 
0026 namespace detail{
0027 
0028 /* Iterator over the sequence of T subojects within a range of
0029  * fixed_variant_closure<T,fixed_variant<...>>s.
0030  */
0031 
0032 template<typename Variant,typename T>
0033 class fixed_variant_alternative_iterator:
0034   public boost::iterator_facade<
0035     fixed_variant_alternative_iterator<Variant,T>,
0036     T,
0037     boost::random_access_traversal_tag
0038   >
0039 {
0040   static constexpr std::size_t Stride=sizeof(
0041     fixed_variant_impl::fixed_variant_closure<
0042       typename std::remove_const<T>::type,Variant>);
0043 
0044 public:
0045   fixed_variant_alternative_iterator()=default;
0046   fixed_variant_alternative_iterator(T* p)noexcept:p{p}{}
0047   fixed_variant_alternative_iterator(
0048     const fixed_variant_alternative_iterator&)=default;
0049   fixed_variant_alternative_iterator& operator=(
0050     const fixed_variant_alternative_iterator&)=default;
0051 
0052   template<
0053     typename NonConstT,
0054     typename std::enable_if<
0055       std::is_same<T,const NonConstT>::value>::type* =nullptr
0056   >
0057   fixed_variant_alternative_iterator(
0058     const fixed_variant_alternative_iterator<Variant,NonConstT>& x)noexcept:
0059     p{x.p}{}
0060 
0061   template<
0062     typename NonConstT,
0063     typename std::enable_if<
0064       std::is_same<T,const NonConstT>::value>::type* =nullptr
0065   >
0066   fixed_variant_alternative_iterator& operator=(
0067     const fixed_variant_alternative_iterator<Variant,NonConstT>& x)noexcept
0068   {
0069     p=x.p;
0070     return *this;
0071   }
0072 
0073   /* interoperability with T* */
0074 
0075   fixed_variant_alternative_iterator& operator=(T* p_)noexcept
0076     {p=p_;return *this;}
0077   operator T*()const noexcept{return p;}
0078 
0079   std::size_t stride()const noexcept{return Stride;}
0080 
0081 private:
0082   template<typename,typename>
0083   friend class fixed_variant_alternative_iterator;
0084 
0085   using char_pointer=typename std::conditional<
0086     std::is_const<T>::value,
0087     const char*,
0088     char*
0089   >::type;
0090 
0091   static char_pointer char_ptr(T* p)noexcept
0092     {return reinterpret_cast<char_pointer>(p);}
0093   static T*           value_ptr(char_pointer p)noexcept
0094     {return reinterpret_cast<T*>(p);}
0095 
0096   friend class boost::iterator_core_access;
0097 
0098   T& dereference()const noexcept{return *p;}
0099   bool equal(const fixed_variant_alternative_iterator& x)const noexcept
0100     {return p==x.p;}
0101   void increment()noexcept{p=value_ptr(char_ptr(p)+Stride);}
0102   void decrement()noexcept{p=value_ptr(char_ptr(p)-Stride);}
0103   template<typename Integral>
0104   void advance(Integral n)noexcept
0105     {p=value_ptr(char_ptr(p)+n*(std::ptrdiff_t)Stride);}
0106   std::ptrdiff_t distance_to(
0107     const fixed_variant_alternative_iterator& x)const noexcept
0108     {return (char_ptr(x.p)-char_ptr(p))/(std::ptrdiff_t)Stride;}          
0109 
0110   T* p;
0111 };
0112 
0113 /* Iterator over the sequence of fixed_variant base objects within a range of
0114  * fixed_variant_closure<T,fixed_variant<...>>s. As T is not part of the
0115  * iterator definition, the stride between values is a run-time value.
0116  */
0117 
0118 template<typename Variant>
0119 class fixed_variant_iterator:
0120   public boost::iterator_facade<
0121     fixed_variant_iterator<Variant>,
0122     Variant,
0123     boost::random_access_traversal_tag
0124   >
0125 {
0126 public:
0127   fixed_variant_iterator()=default;
0128   fixed_variant_iterator(Variant* p,std::size_t stride)noexcept:
0129     p{p},stride_{stride}{}
0130   fixed_variant_iterator(const fixed_variant_iterator&)=default;
0131   fixed_variant_iterator& operator=(const fixed_variant_iterator&)=default;
0132 
0133   template<
0134     typename NonConstVariant,
0135     typename std::enable_if<
0136       std::is_same<Variant,const NonConstVariant>::value>::type* =nullptr
0137   >
0138   fixed_variant_iterator(
0139     const fixed_variant_iterator<NonConstVariant>& x)noexcept:
0140     p{x.p},stride_{x.stride_}{}
0141 
0142   template<
0143     typename NonConstVariant,
0144     typename std::enable_if<
0145       std::is_same<Variant,const NonConstVariant>::value>::type* =nullptr
0146   >
0147   fixed_variant_iterator& operator=(
0148     const fixed_variant_iterator<NonConstVariant>& x)noexcept
0149   {
0150     p=x.p;stride_=x.stride_;
0151     return *this;
0152   }
0153 
0154   /* interoperability with Variant* */
0155 
0156   fixed_variant_iterator& operator=(Variant* p_)noexcept{p=p_;return *this;}
0157   operator Variant*()const noexcept{return p;}
0158 
0159   /* interoperability with fixed_variant_alternative_iterator<Variant,T> */
0160 
0161 #include <boost/poly_collection/detail/begin_no_sanitize.hpp>
0162 
0163   template<
0164     typename T,
0165     typename NonConstT=typename std::remove_const<T>::type,
0166     typename NonConstVariant=typename std::remove_const<Variant>::type,
0167     typename std::enable_if<
0168       mp11::mp_contains<NonConstVariant,NonConstT>::value&&
0169       (!std::is_const<Variant>::value||std::is_const<T>::value)
0170     >::type* =nullptr
0171   >
0172   BOOST_POLY_COLLECTION_NO_SANITIZE explicit operator
0173     fixed_variant_alternative_iterator<NonConstVariant,T>()const noexcept
0174   {
0175     return p?std::addressof(unsafe_get<NonConstT>(*p)):nullptr;
0176   }
0177 
0178 #include <boost/poly_collection/detail/end_no_sanitize.hpp>
0179 
0180   std::size_t stride()const noexcept{return stride_;}
0181 
0182 private:
0183   template<typename>
0184   friend class fixed_variant_iterator;
0185 
0186   using char_pointer=typename std::conditional<
0187     std::is_const<Variant>::value,
0188     const char*,
0189     char*
0190   >::type;
0191 
0192   static char_pointer char_ptr(Variant* p)noexcept
0193     {return reinterpret_cast<char_pointer>(p);}
0194   static Variant*       value_ptr(char_pointer p)noexcept
0195     {return reinterpret_cast<Variant*>(p);}
0196 
0197   friend class boost::iterator_core_access;
0198 
0199   Variant& dereference()const noexcept{return *p;}
0200   bool equal(const fixed_variant_iterator& x)const noexcept{return p==x.p;}
0201   void increment()noexcept{p=value_ptr(char_ptr(p)+stride_);}
0202   void decrement()noexcept{p=value_ptr(char_ptr(p)-stride_);}
0203   template<typename Integral>
0204   void advance(Integral n)noexcept
0205     {p=value_ptr(char_ptr(p)+n*(std::ptrdiff_t)stride_);}
0206   std::ptrdiff_t distance_to(const fixed_variant_iterator& x)const noexcept
0207     {return (char_ptr(x.p)-char_ptr(p))/(std::ptrdiff_t)stride_;}          
0208 
0209   Variant*    p;
0210   std::size_t stride_;
0211 };
0212 
0213 } /* namespace poly_collection::detail */
0214 
0215 } /* namespace poly_collection */
0216 
0217 } /* namespace boost */
0218 
0219 #endif