1 /* Copyright 2016-2017 Joaquin M Lopez Munoz. 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 * 6 * See http://www.boost.org/libs/poly_collection for library home page. 7 */ 8 9 #ifndef BOOST_POLY_COLLECTION_DETAIL_ITERATOR_TRAITS_HPP 10 #define BOOST_POLY_COLLECTION_DETAIL_ITERATOR_TRAITS_HPP 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 #include <iterator> 17 #include <type_traits> 18 19 namespace boost{ 20 21 namespace poly_collection{ 22 23 namespace common_impl{ 24 25 template<typename Model,typename Allocator> 26 class poly_collection; 27 28 } 29 30 namespace detail{ 31 32 /* (Internal) bunch of traits-grouped functions for const-preserving 33 * interoperatibility between iterators and local iterators of a 34 * poly_collection. 35 */ 36 37 template<typename Iterator> 38 struct poly_collection_of /* to be specialized for iterator impls */ 39 { 40 using type=void; 41 }; 42 43 template<typename PolyCollection> 44 struct model_of; 45 46 template<typename Model,typename Allocator> 47 struct model_of<common_impl::poly_collection<Model,Allocator>> 48 { 49 using type=Model; 50 }; 51 52 template<typename Iterator> 53 struct iterator_traits 54 { 55 using container_type=typename poly_collection_of<Iterator>::type; 56 using is_const_iterator=typename std::is_const< 57 typename std::remove_reference< 58 typename std::iterator_traits<Iterator>::reference 59 >::type 60 >::type; 61 using iterator=typename std::conditional< 62 is_const_iterator::value, 63 typename container_type::const_iterator, 64 typename container_type::iterator 65 >::type; 66 using base_segment_info_iterator=typename std::conditional< 67 is_const_iterator::value, 68 typename container_type::const_base_segment_info_iterator, 69 typename container_type::base_segment_info_iterator 70 >::type; 71 using local_base_iterator=typename std::conditional< 72 is_const_iterator::value, 73 typename container_type::const_local_base_iterator, 74 typename container_type::local_base_iterator 75 >::type; 76 template<typename T> 77 using local_iterator=typename std::conditional< 78 is_const_iterator::value, 79 typename container_type::template const_local_iterator<T>, 80 typename container_type::template local_iterator<T> 81 >::type; 82 83 static base_segment_info_iterator base_segment_info_iterator_fromboost::poly_collection::detail::iterator_traits84 base_segment_info_iterator_from(iterator it)noexcept{return it.mapit;} 85 86 static base_segment_info_iterator base_segment_info_iterator_fromboost::poly_collection::detail::iterator_traits87 base_segment_info_iterator_from(local_base_iterator it)noexcept 88 {return it.mapit;} 89 90 static base_segment_info_iterator end_base_segment_info_iterator_fromboost::poly_collection::detail::iterator_traits91 end_base_segment_info_iterator_from(iterator it)noexcept{return it.mapend;} 92 93 static local_base_iterator local_base_iterator_fromboost::poly_collection::detail::iterator_traits94 local_base_iterator_from(iterator it)noexcept 95 { 96 return { 97 it.mapit, 98 model_of<container_type>::type::nonconst_iterator(it.segpos) 99 }; 100 } 101 102 static iterator iterator_fromboost::poly_collection::detail::iterator_traits103 iterator_from( 104 local_base_iterator lbit,base_segment_info_iterator mapend)noexcept 105 { 106 return {lbit.mapit,mapend.base(),lbit.base()}; 107 } 108 }; 109 110 } /* namespace poly_collection::detail */ 111 112 } /* namespace poly_collection */ 113 114 } /* namespace boost */ 115 116 #endif 117