1 // Copyright David Abrahams 2003. Use, modification and distribution is 2 // subject to the Boost Software License, Version 1.0. (See accompanying 3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 #ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_ 5 # define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_ 6 7 # include <boost/static_assert.hpp> 8 # include <boost/type_traits/is_convertible.hpp> 9 # include <boost/type_traits/is_same.hpp> 10 11 # include <boost/mpl/placeholders.hpp> 12 # include <boost/mpl/aux_/lambda_support.hpp> 13 14 namespace boost { 15 namespace iterators { 16 namespace detail { 17 18 template <bool GreaterEqual, bool LessEqual> 19 struct minimum_category_impl; 20 21 template <class T1, class T2> 22 struct error_not_related_by_convertibility; 23 24 template <> 25 struct minimum_category_impl<true,false> 26 { 27 template <class T1, class T2> struct apply 28 { 29 typedef T2 type; 30 }; 31 }; 32 33 template <> 34 struct minimum_category_impl<false,true> 35 { 36 template <class T1, class T2> struct apply 37 { 38 typedef T1 type; 39 }; 40 }; 41 42 template <> 43 struct minimum_category_impl<true,true> 44 { 45 template <class T1, class T2> struct apply 46 { 47 BOOST_STATIC_ASSERT((is_same<T1,T2>::value)); 48 typedef T1 type; 49 }; 50 }; 51 52 template <> 53 struct minimum_category_impl<false,false> 54 { 55 template <class T1, class T2> struct apply 56 : error_not_related_by_convertibility<T1,T2> 57 { 58 }; 59 }; 60 61 } // namespace detail 62 63 // 64 // Returns the minimum category type or fails to compile 65 // if T1 and T2 are unrelated. 66 // 67 template <class T1 = mpl::_1, class T2 = mpl::_2> 68 struct minimum_category 69 { 70 typedef boost::iterators::detail::minimum_category_impl< 71 ::boost::is_convertible<T1,T2>::value 72 , ::boost::is_convertible<T2,T1>::value 73 > outer; 74 75 typedef typename outer::template apply<T1,T2> inner; 76 typedef typename inner::type type; 77 78 BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2)) 79 }; 80 81 template <> 82 struct minimum_category<mpl::_1,mpl::_2> 83 { 84 template <class T1, class T2> 85 struct apply : minimum_category<T1,T2> 86 {}; 87 88 BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2)) 89 }; 90 91 } // namespace iterators 92 93 } // namespace boost 94 95 #endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_ 96