// (C) Copyright David Abrahams 2002. // (C) Copyright Jeremy Siek 2002. // (C) Copyright Thomas Witt 2002. // Permission to copy, use, modify, // sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP #define BOOST_INDIRECT_ITERATOR_23022003THW_HPP #include #include #include #include #include #include #ifdef BOOST_MPL_NO_AUX_HAS_XXX # include # include # include # include #endif #include // must be last #include namespace boost { template struct indirect_iterator; namespace detail { struct unspecified {}; // // Detection for whether a type has a nested `element_type' // typedef. Used to detect smart pointers. For compilers not // supporting mpl's has_xxx, we supply specializations. However, we // really ought to have a specializable is_pointer template which // can be used instead with something like // boost/python/pointee.hpp to find the value_type. // # ifndef BOOST_MPL_NO_AUX_HAS_XXX namespace aux { BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) } template struct has_element_type : mpl::bool_< mpl::if_< is_class , ::boost::detail::aux::has_element_type , mpl::false_ >::type::value > { }; # else template struct has_element_type : mpl::false_ {}; template struct has_element_type > : mpl::true_ {}; template struct has_element_type > : mpl::true_ {}; template struct has_element_type > : mpl::true_ {}; # endif // Metafunction returning the nested element_type typedef template struct smart_pointer_value : remove_const {}; template struct iterator_is_mutable : mpl::not_< boost::python::detail::is_reference_to_const< typename iterator_reference::type > > { }; template struct not_int_impl { template struct apply { typedef T type; }; }; template <> struct not_int_impl {}; template struct not_int : not_int_impl::template apply {}; // If the Value parameter is unspecified, we use this metafunction // to deduce the default types template struct indirect_base { typedef typename iterator_value::type dereferenceable; typedef mpl::and_< is_class , has_element_type > is_smart_ptr; typedef typename mpl::apply_if< is_smart_ptr , smart_pointer_value , iterator_value >::type value_type; typedef typename mpl::if_< mpl::or_< is_smart_ptr , iterator_is_mutable > , value_type , value_type const >::type cv_value_type; typedef iterator_adaptor< indirect_iterator , Iter , cv_value_type , Category , Reference , Difference > type; }; template <> struct indirect_base {}; } // namespace detail template < class Iterator , class Value = use_default , class Category = use_default , class Reference = use_default , class Difference = use_default > class indirect_iterator : public detail::indirect_base< Iterator, Value, Category, Reference, Difference >::type { typedef typename detail::indirect_base< Iterator, Value, Category, Reference, Difference >::type super_t; friend class iterator_core_access; public: indirect_iterator() {} indirect_iterator(Iterator iter) : super_t(iter) {} template < class Iterator2, class Value2, class Category2 , class Reference2, class Difference2 > indirect_iterator( indirect_iterator< Iterator2, Value2, Category2, Reference2, Difference2 > const& y , typename enable_if_convertible::type* = 0 ) : super_t(y.base()) {} private: typename super_t::reference dereference() const { # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) return const_cast(**this->base()); # else return **this->base(); # endif } }; template inline indirect_iterator make_indirect_iterator(Iter x) { return indirect_iterator(x); } template inline indirect_iterator make_indirect_iterator(Iter x, Traits* = 0) { return indirect_iterator(x); } } // namespace boost #include #endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP