// (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 #include #include #include #include #ifdef BOOST_MPL_NO_AUX_HAS_XXX # include # include # include # include #endif #include // must be last #include namespace boost { template class indirect_iterator; template struct referent; 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 accessing the nested ::element_type template struct element_type : mpl::identity {}; 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 {}; template struct class_has_element_type : mpl::and_< is_class , has_element_type > {}; // If the Value parameter is unspecified, we use this metafunction // to deduce the default types template struct default_indirect_value { typedef typename remove_cv< typename referent::type >::type referent_t; typedef typename mpl::if_< mpl::or_< class_has_element_type , iterator_is_mutable > , referent_t , referent_t const >::type type; }; template struct indirect_base { typedef typename iterator_traits::value_type dereferenceable; typedef iterator_adaptor< indirect_iterator , Iter , typename ia_dflt_help< Value, default_indirect_value >::type , Category , Reference , Difference > type; }; template <> struct indirect_base {}; } // namespace detail // User-specializable metafunction which returns the referent of a // dereferenceable type. The default implementation returns // Dereferenceable::element_type if such a member exists (thus // handling the boost smart pointers and auto_ptr), and // iterator_traits::value_type otherwise. template struct referent : mpl::apply_if< detail::class_has_element_type , detail::element_type , iterator_value > {}; 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