From 4fadd968fa12130524c8380f33fcfe25d4de79e5 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Wed, 13 Sep 2017 11:24:46 +0900 Subject: Imported Upstream version 1.65.0 Change-Id: Icf8400b375482cb11bcf77440a6934ba360d6ba4 Signed-off-by: DongHun Kwak --- boost/poly_collection/detail/iterator_impl.hpp | 242 +++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 boost/poly_collection/detail/iterator_impl.hpp (limited to 'boost/poly_collection/detail/iterator_impl.hpp') diff --git a/boost/poly_collection/detail/iterator_impl.hpp b/boost/poly_collection/detail/iterator_impl.hpp new file mode 100644 index 0000000000..e1893527d1 --- /dev/null +++ b/boost/poly_collection/detail/iterator_impl.hpp @@ -0,0 +1,242 @@ +/* Copyright 2016-2017 Joaquin M Lopez Munoz. + * Distributed under 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) + * + * See http://www.boost.org/libs/poly_collection for library home page. + */ + +#ifndef BOOST_POLY_COLLECTION_DETAIL_ITERATOR_IMPL_HPP +#define BOOST_POLY_COLLECTION_DETAIL_ITERATOR_IMPL_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace poly_collection{ + +namespace detail{ + +/* Implementations of poly_collection::[const_][local_[base_]]iterator moved + * out of class to allow for use in deduced contexts. + */ + +template +using iterator_impl_value_type=typename std::conditional< + Const, + const typename PolyCollection::value_type, + typename PolyCollection::value_type +>::type; + +template +class iterator_impl: + public boost::iterator_facade< + iterator_impl, + iterator_impl_value_type, + boost::forward_traversal_tag + > +{ + using segment_type=typename PolyCollection::segment_type; + using const_segment_base_iterator= + typename PolyCollection::const_segment_base_iterator; + using const_segment_base_sentinel= + typename PolyCollection::const_segment_base_sentinel; + using const_segment_map_iterator= + typename PolyCollection::const_segment_map_iterator; + +public: + using value_type=iterator_impl_value_type; + +private: + iterator_impl( + const_segment_map_iterator mapit, + const_segment_map_iterator mapend)noexcept: + mapit{mapit},mapend{mapend} + { + next_segment_position(); + } + + iterator_impl( + const_segment_map_iterator mapit_,const_segment_map_iterator mapend_, + const_segment_base_iterator segpos_)noexcept: + mapit{mapit_},mapend{mapend_},segpos{segpos_} + { + if(mapit!=mapend&&segpos==sentinel()){ + ++mapit; + next_segment_position(); + } + } + +public: + iterator_impl()=default; + iterator_impl(const iterator_impl&)=default; + iterator_impl& operator=(const iterator_impl&)=default; + + template::type* =nullptr> + iterator_impl(const iterator_impl& x): + mapit{x.mapit},mapend{x.mapend},segpos{x.segpos}{} + +private: + template + friend class iterator_impl; + friend PolyCollection; + friend class boost::iterator_core_access; + template + friend struct iterator_traits; + + value_type& dereference()const noexcept + {return const_cast(*segpos);} + bool equal(const iterator_impl& x)const noexcept{return segpos==x.segpos;} + + void increment()noexcept + { + if(++segpos==sentinel()){ + ++mapit; + next_segment_position(); + } + } + + void next_segment_position()noexcept + { + for(;mapit!=mapend;++mapit){ + segpos=segment().begin(); + if(segpos!=sentinel())return; + } + segpos=nullptr; + } + + segment_type& segment()noexcept + {return const_cast(mapit->second);} + const segment_type& segment()const noexcept{return mapit->second;} + + const_segment_base_sentinel sentinel()const noexcept + {return segment().sentinel();} + + const_segment_map_iterator mapit,mapend; + const_segment_base_iterator segpos; +}; + +template +struct poly_collection_of> +{ + using type=PolyCollection; +}; + +template +class local_iterator_impl: + public boost::iterator_adaptor< + local_iterator_impl, + BaseIterator + > +{ + using segment_type=typename PolyCollection::segment_type; + using segment_base_iterator=typename PolyCollection::segment_base_iterator; + using const_segment_map_iterator= + typename PolyCollection::const_segment_map_iterator; + + template + local_iterator_impl( + const_segment_map_iterator mapit, + Iterator it): + local_iterator_impl::iterator_adaptor_{BaseIterator(it)}, + mapit{mapit} + {} + +public: + using base_iterator=BaseIterator; + + local_iterator_impl()=default; + local_iterator_impl(const local_iterator_impl&)=default; + local_iterator_impl& operator=(const local_iterator_impl&)=default; + + template< + typename BaseIterator2, + typename std::enable_if< + std::is_convertible::value + >::type* =nullptr + > + local_iterator_impl( + const local_iterator_impl& x): + local_iterator_impl::iterator_adaptor_{x.base()}, + mapit{x.mapit}{} + + template< + typename BaseIterator2, + typename std::enable_if< + !std::is_convertible::value&& + is_constructible::value + >::type* =nullptr + > + explicit local_iterator_impl( + const local_iterator_impl& x): + local_iterator_impl::iterator_adaptor_{BaseIterator(x.base())}, + mapit{x.mapit}{} + + template< + typename BaseIterator2, + typename std::enable_if< + !is_constructible::value&& + is_constructible::value&& + is_constructible::value + >::type* =nullptr + > + explicit local_iterator_impl( + const local_iterator_impl& x): + local_iterator_impl::iterator_adaptor_{ + base_iterator_from(x.segment(),x.base())}, + mapit{x.mapit}{} + + /* define [] to avoid Boost.Iterator operator_brackets_proxy mess */ + + template + typename std::iterator_traits::reference + operator[](DifferenceType n)const{return *(*this+n);} + +private: + template + friend class local_iterator_impl; + friend PolyCollection; + template + friend struct iterator_traits; + + template + static BaseIterator base_iterator_from( + const segment_type& s,BaseIterator2 it) + { + segment_base_iterator bit=s.begin(); + return BaseIterator{bit+(it-static_cast(bit))}; + } + + base_iterator base()const noexcept + {return local_iterator_impl::iterator_adaptor_::base();} + const std::type_info& type_info()const{return *mapit->first;} + segment_type& segment()noexcept + {return const_cast(mapit->second);} + const segment_type& segment()const noexcept{return mapit->second;} + + const_segment_map_iterator mapit; +}; + +template +struct poly_collection_of> +{ + using type=PolyCollection; +}; + + +} /* namespace poly_collection::detail */ + +} /* namespace poly_collection */ + +} /* namespace boost */ + +#endif -- cgit v1.2.3