diff --git a/include/boost/iterator_adaptors.hpp b/include/boost/iterator_adaptors.hpp index d2c334e..b472bd8 100644 --- a/include/boost/iterator_adaptors.hpp +++ b/include/boost/iterator_adaptors.hpp @@ -409,7 +409,7 @@ namespace detail { { BOOST_STATIC_CONSTANT(bool, is_ptr = boost::is_pointer::value); - typedef iterator_defaults_select::template traits traits; + typedef typename iterator_defaults_select::template traits traits; typedef typename traits::pointer pointer; typedef typename traits::reference reference; }; @@ -438,25 +438,45 @@ namespace detail { //=========================================================================== // Specify the defaults for iterator_adaptor's template parameters - + + struct default_argument { }; + // This class template is a workaround for MSVC. + struct dummy_default_gen { + template + struct select { typedef default_argument type; }; + }; + // This class template is a workaround for MSVC. + template struct default_generator { + typedef dummy_default_gen type; + }; + struct default_value_type { template struct select { typedef typename boost::detail::iterator_traits::value_type type; }; }; + template <> struct default_generator + { typedef default_value_type type; }; // VC++ workaround + struct default_difference_type { template struct select { typedef typename boost::detail::iterator_traits::difference_type type; }; }; + template <> struct default_generator + { typedef default_difference_type type; }; // VC++ workaround + struct default_iterator_category { template struct select { typedef typename boost::detail::iterator_traits::iterator_category type; }; }; + template <> struct default_generator + { typedef default_iterator_category type; }; // VC++ workaround + struct default_pointer { template struct select { @@ -465,6 +485,9 @@ namespace detail { type; }; }; + template <> struct default_generator + { typedef default_pointer type; }; // VC++ workaround + struct default_reference { template struct select { @@ -473,6 +496,8 @@ namespace detail { type; }; }; + template <> struct default_generator + { typedef default_reference type; }; // VC++ workaround } // namespace detail @@ -488,55 +513,66 @@ namespace detail { struct pointer_tag { }; struct difference_type_tag { }; struct iterator_category_tag { }; -} + + // avoid using std::pair because A or B might be a reference type, and g++ + // complains about forming references to references inside std::pair + template + struct cons_type { + typedef A first_type; + typedef B second_type; + }; + +} // namespace detail + template struct value_type_is : public named_template_param_base { - typedef std::pair type; + typedef detail::cons_type type; }; template struct reference_is : public named_template_param_base { - typedef std::pair type; + typedef detail::cons_type type; }; template struct pointer_is : public named_template_param_base { - typedef std::pair type; + typedef detail::cons_type type; }; template struct difference_type_is : public named_template_param_base { - typedef std::pair type; + typedef detail::cons_type type; }; template struct iterator_category_is : public named_template_param_base { - typedef std::pair type; + typedef detail::cons_type type; }; namespace detail { - struct default_argument { }; - struct end_of_list { }; // Given an associative list, find the value with the matching key. // An associative list is a list of key-value pairs. The list is - // built out of std::pair's and is terminated by end_of_list. + // built out of cons_type's and is terminated by end_of_list. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct find_param; + struct find_param_continue { template struct bind { - typedef typename AssocList::first_argument Head; - typedef typename Head::first_argument Key1; - typedef typename Head::second_argument Value; + typedef typename AssocList::first_type Head; + typedef typename Head::first_type Key1; + typedef typename Head::second_type Value; typedef typename ct_if::value, Value, - typename find_param::type + typename find_param::type >::type type; }; }; struct find_param_end { template - struct bind { typedef default_argument type; }; + struct bind { typedef detail::default_argument type; }; }; template struct find_param_helper1 { typedef find_param_continue type; }; @@ -556,13 +592,13 @@ namespace detail { // Found a matching Key, return the associated Value template - struct find_param, Rest>, Key> { + struct find_param, Rest>, Key> { typedef Value type; }; // Non-matching keys, continue the search template - struct find_param, Rest>, Key2> { + struct find_param, Rest>, Key2> { typedef typename find_param::type type; }; #endif @@ -573,7 +609,7 @@ namespace detail { }; struct make_key_value { template - struct bind { typedef std::pair type; }; + struct bind { typedef detail::cons_type type; }; }; template @@ -591,13 +627,16 @@ namespace detail { struct choose_default { template - struct select { - typedef typename DefaultGen::template select::type type; + struct bind { +#if 1 + typedef typename default_generator::type Gen; + typedef typename Gen::template select::type type; +#endif }; }; struct choose_arg { template - struct select { + struct bind { typedef Arg type; }; }; @@ -614,7 +653,7 @@ namespace detail { Selector; public: typedef typename Selector - ::template select::type type; + ::template bind::type type; }; template ::type, - std::pair::type, - std::pair::type, - std::pair::type, - std::pair::type, + typedef detail::cons_type< typename make_arg::type, + detail::cons_type::type, + detail::cons_type::type, + detail::cons_type::type, + detail::cons_type::type, end_of_list> > > > > ArgList; // Search the list for particular parameters @@ -646,6 +685,7 @@ namespace detail { // Compute the defaults if necessary typedef typename resolve_default::type value_type; + // if getting default value type from iterator_traits, then it won't be const typedef typename resolve_default::type difference_type; typedef typename resolve_default::type reference; + public: typedef boost::iterator::type,