#ifndef SPROUT_ITERATOR_TRAITS_HPP #define SPROUT_ITERATOR_TRAITS_HPP #include #include #include #include namespace sprout { namespace detail { // has_iterator_category SPROUT_HAS_XXX_TYPE_DEF_LAZY(iterator_category); } // namespace detail // // is_iterator // template struct is_iterator : sprout::detail::has_iterator_category > {}; // // is_input_iterator_category // template struct is_input_iterator_category : public std::is_convertible {}; // // is_output_iterator_category // template struct is_output_iterator_category : public std::is_convertible {}; // // is_forward_iterator_category // template struct is_forward_iterator_category : public std::is_convertible {}; // // is_bidirectional_iterator_category // template struct is_bidirectional_iterator_category : public std::is_convertible {}; // // is_random_access_iterator_category // template struct is_random_access_iterator_category : public std::is_convertible {}; // // is_input_iterator // template struct is_input_iterator : public sprout::is_input_iterator_category::iterator_category> {}; // // is_output_iterator // template struct is_output_iterator : public sprout::is_output_iterator_category::iterator_category> {}; // // is_forward_iterator // template struct is_forward_iterator : public sprout::is_forward_iterator_category::iterator_category> {}; // // is_bidirectional_iterator // template struct is_bidirectional_iterator : public sprout::is_bidirectional_iterator_category::iterator_category> {}; // // is_random_access_iterator // template struct is_random_access_iterator : public sprout::is_random_access_iterator_category::iterator_category> {}; namespace detail { template struct iterator_category_hierarchy_impl; template struct iterator_category_hierarchy_impl : public std::integral_constant {}; template struct iterator_category_hierarchy_impl : public std::integral_constant {}; template struct iterator_category_hierarchy_impl : public std::integral_constant {}; template struct iterator_category_hierarchy_impl : public std::integral_constant {}; template struct iterator_category_hierarchy : public sprout::detail::iterator_category_hierarchy_impl< Category, sprout::is_random_access_iterator_category::value, sprout::is_bidirectional_iterator_category::value, sprout::is_forward_iterator_category::value, sprout::is_input_iterator_category::value || sprout::is_output_iterator_category::value > {}; template struct iterator_category_less : public std::integral_constant< bool, (sprout::detail::iterator_category_hierarchy::value < sprout::detail::iterator_category_hierarchy::value) > {}; } // namespace detail // // min_iterator_category // template struct min_iterator_category; template struct min_iterator_category : public std::common_type {}; template struct min_iterator_category : public std::conditional< sprout::detail::iterator_category_less::value, Category1, Category2 > {}; template struct min_iterator_category : public sprout::min_iterator_category< Head, typename sprout::min_iterator_category::type > {}; // // common_iterator_category // template struct common_iterator_category : public sprout::min_iterator_category< typename std::iterator_traits::iterator_category... > {}; namespace detail { template struct common_iterator_reference_impl; template struct common_iterator_reference_impl { public: typedef T type; }; template struct common_iterator_reference_impl : public std::conditional< std::is_reference::value && std::is_reference::value, typename std::conditional< std::is_convertible::value && (std::is_same::type, typename std::decay::type>::value || std::is_base_of::type, typename std::decay::type>::value ) , U, typename std::conditional< std::is_convertible::value && (std::is_same::type, typename std::decay::type>::value || std::is_base_of::type, typename std::decay::type>::value ) , T, typename std::common_type::type, typename std::decay::type>::type >::type >::type, typename std::common_type::type, typename std::decay::type>::type > {}; template struct common_iterator_reference_impl : public sprout::detail::common_iterator_reference_impl< typename sprout::detail::common_iterator_reference_impl::type, Tail... > {}; } // namespace detail // // common_iterator_reference // template struct common_iterator_reference : public sprout::detail::common_iterator_reference_impl< typename std::iterator_traits::reference... > {}; // // common_iterator_value_type // template struct common_iterator_value_type : public std::decay< typename sprout::common_iterator_reference::type > {}; // // common_iterator_pointer // template struct common_iterator_pointer : public std::add_pointer< typename std::remove_reference::type>::type > {}; // // common_iterator_difference_type // template struct common_iterator_difference_type : public std::common_type< typename std::iterator_traits::difference_type... > {}; } // namespace sprout #endif // #ifndef SPROUT_ITERATOR_TRAITS_HPP