summaryrefslogtreecommitdiff
path: root/boost/poly_collection/detail/iterator_impl.hpp
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:24:46 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:25:39 +0900
commit4fadd968fa12130524c8380f33fcfe25d4de79e5 (patch)
treefd26a490cd15388d42fc6652b3c5c13012e7f93e /boost/poly_collection/detail/iterator_impl.hpp
parentb5c87084afaef42b2d058f68091be31988a6a874 (diff)
downloadboost-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.hpp242
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