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_CALLABLE_WRAPPER_ITERATOR_HPP 10 #define BOOST_POLY_COLLECTION_DETAIL_CALLABLE_WRAPPER_ITERATOR_HPP 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 #include <boost/iterator/iterator_adaptor.hpp> 17 #include <type_traits> 18 19 namespace boost{ 20 21 namespace poly_collection{ 22 23 namespace detail{ 24 25 /* callable_wrapper<Sig>* adaptor convertible to pointer to wrapped entity */ 26 27 template<typename CWrapper> 28 class callable_wrapper_iterator:public boost::iterator_adaptor< 29 callable_wrapper_iterator<CWrapper>,CWrapper* 30 > 31 { 32 public: 33 callable_wrapper_iterator()=default; callable_wrapper_iterator(CWrapper * p)34 explicit callable_wrapper_iterator(CWrapper* p)noexcept: 35 callable_wrapper_iterator::iterator_adaptor_{p}{} 36 callable_wrapper_iterator(const callable_wrapper_iterator&)=default; 37 callable_wrapper_iterator& operator=( 38 const callable_wrapper_iterator&)=default; 39 40 template< 41 typename NonConstCWrapper, 42 typename std::enable_if< 43 std::is_same<CWrapper,const NonConstCWrapper>::value>::type* =nullptr 44 > callable_wrapper_iterator(const callable_wrapper_iterator<NonConstCWrapper> & x)45 callable_wrapper_iterator( 46 const callable_wrapper_iterator<NonConstCWrapper>& x)noexcept: 47 callable_wrapper_iterator::iterator_adaptor_{x.base()}{} 48 49 template< 50 typename NonConstCWrapper, 51 typename std::enable_if< 52 std::is_same<CWrapper,const NonConstCWrapper>::value>::type* =nullptr 53 > operator =(const callable_wrapper_iterator<NonConstCWrapper> & x)54 callable_wrapper_iterator& operator=( 55 const callable_wrapper_iterator<NonConstCWrapper>& x)noexcept 56 { 57 this->base_reference()=x.base(); 58 return *this; 59 } 60 61 /* interoperability with CWrapper* */ 62 operator =(CWrapper * p)63 callable_wrapper_iterator& operator=(CWrapper* p)noexcept 64 {this->base_reference()=p;return *this;} operator CWrapper*() const65 operator CWrapper*()const noexcept{return this->base();} 66 67 /* interoperability with Callable* */ 68 69 template< 70 typename Callable, 71 typename std::enable_if< 72 std::is_constructible<CWrapper,Callable&>::value&& 73 (!std::is_const<CWrapper>::value||std::is_const<Callable>::value) 74 >::type* =nullptr 75 > operator Callable*() const76 explicit operator Callable*()const noexcept 77 { 78 return const_cast<Callable*>( 79 static_cast<const Callable*>( 80 const_cast<const void*>( 81 this->base()->data()))); 82 } 83 84 private: 85 template<typename> 86 friend class callable_wrapper_iterator; 87 }; 88 89 } /* namespace poly_collection::detail */ 90 91 } /* namespace poly_collection */ 92 93 } /* namespace boost */ 94 95 #endif 96