1 /* Copyright 2016 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_ANY_ITERATOR_HPP 10 #define BOOST_POLY_COLLECTION_DETAIL_ANY_ITERATOR_HPP 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 #include <boost/iterator/iterator_adaptor.hpp> 17 #include <boost/type_erasure/any_cast.hpp> 18 #include <type_traits> 19 #include <utility> 20 21 namespace boost{ 22 23 namespace poly_collection{ 24 25 namespace detail{ 26 27 /* type_erasure::any<Concept>* adaptor convertible to pointer to wrapped 28 * entity. 29 */ 30 31 template<typename Any> 32 class any_iterator:public boost::iterator_adaptor<any_iterator<Any>,Any*> 33 { 34 public: 35 any_iterator()=default; any_iterator(Any * p)36 explicit any_iterator(Any* p)noexcept:any_iterator::iterator_adaptor_{p}{} 37 any_iterator(const any_iterator&)=default; 38 any_iterator& operator=(const any_iterator&)=default; 39 40 template< 41 typename NonConstAny, 42 typename std::enable_if< 43 std::is_same<Any,const NonConstAny>::value>::type* =nullptr 44 > any_iterator(const any_iterator<NonConstAny> & x)45 any_iterator(const any_iterator<NonConstAny>& x)noexcept: 46 any_iterator::iterator_adaptor_{x.base()}{} 47 48 template< 49 typename NonConstAny, 50 typename std::enable_if< 51 std::is_same<Any,const NonConstAny>::value>::type* =nullptr 52 > operator =(const any_iterator<NonConstAny> & x)53 any_iterator& operator=(const any_iterator<NonConstAny>& x)noexcept 54 { 55 this->base_reference()=x.base(); 56 return *this; 57 } 58 59 /* interoperability with Any* */ 60 operator =(Any * p)61 any_iterator& operator=(Any* p)noexcept 62 {this->base_reference()=p;return *this;} operator Any*() const63 operator Any*()const noexcept{return this->base();} 64 65 /* interoperability with Concrete* */ 66 67 template< 68 typename Concrete, 69 typename std::enable_if< 70 /* can't compile-time check concept compliance */ 71 !std::is_const<Any>::value||std::is_const<Concrete>::value 72 >::type* =nullptr 73 > operator Concrete*() const74 explicit operator Concrete*()const noexcept 75 { 76 return const_cast<Concrete*>( 77 static_cast<typename std::remove_const<Concrete>::type*>( 78 type_erasure::any_cast<void*>(this->base()))); 79 } 80 81 private: 82 template<typename> 83 friend class any_iterator; 84 }; 85 86 } /* namespace poly_collection::detail */ 87 88 } /* namespace poly_collection */ 89 90 } /* namespace boost */ 91 92 #endif 93