difference_type_of.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2008-2009: Joachim Faulhaber
  3. +------------------------------------------------------------------------------+
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENCE.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. +-----------------------------------------------------------------------------*/
  8. #ifndef BOOST_ICL_TYPE_TRAITS_DIFFERENCE_TYPE_OF_HPP_JOFA_080911
  9. #define BOOST_ICL_TYPE_TRAITS_DIFFERENCE_TYPE_OF_HPP_JOFA_080911
  10. #include <boost/config.hpp> // For macro BOOST_STATIC_CONSTANT
  11. #include <boost/type_traits/is_pointer.hpp>
  12. #include <boost/mpl/has_xxx.hpp>
  13. #include <boost/mpl/or.hpp>
  14. #include <boost/mpl/and.hpp>
  15. #include <boost/mpl/not.hpp>
  16. #include <boost/icl/type_traits/no_type.hpp>
  17. #include <boost/icl/type_traits/is_numeric.hpp>
  18. #include <boost/icl/type_traits/rep_type_of.hpp>
  19. namespace boost{ namespace icl
  20. {
  21. namespace detail
  22. {
  23. BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type)
  24. }
  25. //--------------------------------------------------------------------------
  26. template <class Type>
  27. struct has_difference_type
  28. : mpl::bool_<detail::has_difference_type<Type>::value>
  29. {};
  30. //--------------------------------------------------------------------------
  31. template<class Type> // type_of(T-T)==T
  32. struct is_subtraction_closed
  33. {
  34. typedef is_subtraction_closed type;
  35. BOOST_STATIC_CONSTANT(bool,
  36. value = (mpl::or_< is_numeric<Type>
  37. , mpl::and_< has_rep_type<Type>
  38. , mpl::not_<has_difference_type<Type> >
  39. >
  40. >::value)
  41. );
  42. };
  43. //--------------------------------------------------------------------------
  44. template<class Type>
  45. struct has_difference
  46. {
  47. typedef has_difference type;
  48. BOOST_STATIC_CONSTANT(bool,
  49. value = (mpl::or_< is_subtraction_closed<Type>
  50. , is_pointer<Type>
  51. , has_difference_type<Type> >::value)
  52. );
  53. };
  54. //--------------------------------------------------------------------------
  55. template <class Type, bool has_difference, bool has_diff_type>
  56. struct get_difference_type;
  57. template <class Type>
  58. struct get_difference_type<Type, false, false>
  59. {
  60. typedef no_type type;
  61. };
  62. template <class Type>
  63. struct get_difference_type<Type*, true, false>
  64. {
  65. typedef std::ptrdiff_t type;
  66. };
  67. template <class Type>
  68. struct get_difference_type<Type, true, false>
  69. {
  70. typedef Type type;
  71. };
  72. template <class Type>
  73. struct get_difference_type<Type, true, true>
  74. {
  75. typedef typename Type::difference_type type;
  76. };
  77. //--------------------------------------------------------------------------
  78. template<class Type>
  79. struct difference_type_of
  80. {
  81. typedef typename
  82. get_difference_type< Type
  83. , has_difference<Type>::value
  84. , has_difference_type<Type>::value
  85. >::type type;
  86. };
  87. }} // namespace boost icl
  88. #endif