minimum_category.hpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. # include <boost/static_assert.hpp>
  7. # include <boost/type_traits/is_convertible.hpp>
  8. # include <boost/type_traits/is_same.hpp>
  9. # include <boost/mpl/placeholders.hpp>
  10. # include <boost/mpl/aux_/lambda_support.hpp>
  11. namespace boost {
  12. namespace iterators {
  13. namespace detail {
  14. template <bool GreaterEqual, bool LessEqual>
  15. struct minimum_category_impl;
  16. template <class T1, class T2>
  17. struct error_not_related_by_convertibility;
  18. template <>
  19. struct minimum_category_impl<true,false>
  20. {
  21. template <class T1, class T2> struct apply
  22. {
  23. typedef T2 type;
  24. };
  25. };
  26. template <>
  27. struct minimum_category_impl<false,true>
  28. {
  29. template <class T1, class T2> struct apply
  30. {
  31. typedef T1 type;
  32. };
  33. };
  34. template <>
  35. struct minimum_category_impl<true,true>
  36. {
  37. template <class T1, class T2> struct apply
  38. {
  39. BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
  40. typedef T1 type;
  41. };
  42. };
  43. template <>
  44. struct minimum_category_impl<false,false>
  45. {
  46. template <class T1, class T2> struct apply
  47. : error_not_related_by_convertibility<T1,T2>
  48. {
  49. };
  50. };
  51. } // namespace detail
  52. //
  53. // Returns the minimum category type or fails to compile
  54. // if T1 and T2 are unrelated.
  55. //
  56. template <class T1 = mpl::_1, class T2 = mpl::_2>
  57. struct minimum_category
  58. {
  59. typedef boost::iterators::detail::minimum_category_impl<
  60. ::boost::is_convertible<T1,T2>::value
  61. , ::boost::is_convertible<T2,T1>::value
  62. > outer;
  63. typedef typename outer::template apply<T1,T2> inner;
  64. typedef typename inner::type type;
  65. BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
  66. };
  67. template <>
  68. struct minimum_category<mpl::_1,mpl::_2>
  69. {
  70. template <class T1, class T2>
  71. struct apply : minimum_category<T1,T2>
  72. {};
  73. BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
  74. };
  75. } // namespace iterators
  76. } // namespace boost
  77. #endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_