diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:24:46 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:25:39 +0900 |
commit | 4fadd968fa12130524c8380f33fcfe25d4de79e5 (patch) | |
tree | fd26a490cd15388d42fc6652b3c5c13012e7f93e /boost/poly_collection/detail/iterator_impl.hpp | |
parent | b5c87084afaef42b2d058f68091be31988a6a874 (diff) | |
download | boost-upstream/1.65.0.tar.gz boost-upstream/1.65.0.tar.bz2 boost-upstream/1.65.0.zip |
Imported Upstream version 1.65.0upstream/1.65.0
Change-Id: Icf8400b375482cb11bcf77440a6934ba360d6ba4
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/poly_collection/detail/iterator_impl.hpp')
-rw-r--r-- | boost/poly_collection/detail/iterator_impl.hpp | 242 |
1 files changed, 242 insertions, 0 deletions
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 <boost/iterator/iterator_adaptor.hpp> +#include <boost/iterator/iterator_facade.hpp> +#include <boost/poly_collection/detail/is_constructible.hpp> +#include <boost/poly_collection/detail/iterator_traits.hpp> +#include <type_traits> +#include <typeinfo> + +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<typename PolyCollection,bool Const> +using iterator_impl_value_type=typename std::conditional< + Const, + const typename PolyCollection::value_type, + typename PolyCollection::value_type +>::type; + +template<typename PolyCollection,bool Const> +class iterator_impl: + public boost::iterator_facade< + iterator_impl<PolyCollection,Const>, + iterator_impl_value_type<PolyCollection,Const>, + 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<PolyCollection,Const>; + +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<bool Const2,typename std::enable_if<!Const2>::type* =nullptr> + iterator_impl(const iterator_impl<PolyCollection,Const2>& x): + mapit{x.mapit},mapend{x.mapend},segpos{x.segpos}{} + +private: + template<typename,bool> + friend class iterator_impl; + friend PolyCollection; + friend class boost::iterator_core_access; + template<typename> + friend struct iterator_traits; + + value_type& dereference()const noexcept + {return const_cast<value_type&>(*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<segment_type&>(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<typename PolyCollection,bool Const> +struct poly_collection_of<iterator_impl<PolyCollection,Const>> +{ + using type=PolyCollection; +}; + +template<typename PolyCollection,typename BaseIterator> +class local_iterator_impl: + public boost::iterator_adaptor< + local_iterator_impl<PolyCollection,BaseIterator>, + 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<typename Iterator> + 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<BaseIterator2,BaseIterator>::value + >::type* =nullptr + > + local_iterator_impl( + const local_iterator_impl<PolyCollection,BaseIterator2>& x): + local_iterator_impl::iterator_adaptor_{x.base()}, + mapit{x.mapit}{} + + template< + typename BaseIterator2, + typename std::enable_if< + !std::is_convertible<BaseIterator2,BaseIterator>::value&& + is_constructible<BaseIterator,BaseIterator2>::value + >::type* =nullptr + > + explicit local_iterator_impl( + const local_iterator_impl<PolyCollection,BaseIterator2>& x): + local_iterator_impl::iterator_adaptor_{BaseIterator(x.base())}, + mapit{x.mapit}{} + + template< + typename BaseIterator2, + typename std::enable_if< + !is_constructible<BaseIterator,BaseIterator2>::value&& + is_constructible<BaseIterator,segment_base_iterator>::value&& + is_constructible<BaseIterator2,segment_base_iterator>::value + >::type* =nullptr + > + explicit local_iterator_impl( + const local_iterator_impl<PolyCollection,BaseIterator2>& 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 DifferenceType> + typename std::iterator_traits<BaseIterator>::reference + operator[](DifferenceType n)const{return *(*this+n);} + +private: + template<typename,typename> + friend class local_iterator_impl; + friend PolyCollection; + template<typename> + friend struct iterator_traits; + + template<typename BaseIterator2> + static BaseIterator base_iterator_from( + const segment_type& s,BaseIterator2 it) + { + segment_base_iterator bit=s.begin(); + return BaseIterator{bit+(it-static_cast<BaseIterator2>(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<segment_type&>(mapit->second);} + const segment_type& segment()const noexcept{return mapit->second;} + + const_segment_map_iterator mapit; +}; + +template<typename PolyCollection,typename BaseIterator> +struct poly_collection_of<local_iterator_impl<PolyCollection,BaseIterator>> +{ + using type=PolyCollection; +}; + + +} /* namespace poly_collection::detail */ + +} /* namespace poly_collection */ + +} /* namespace boost */ + +#endif |