• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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