tag_cast.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_CORE_TAG_CAST_HPP
  11. #define BOOST_GEOMETRY_CORE_TAG_CAST_HPP
  12. #include <boost/mpl/if.hpp>
  13. #include <boost/type_traits/is_base_of.hpp>
  14. namespace boost { namespace geometry
  15. {
  16. /*!
  17. \brief Metafunction defining a type being either the specified tag, or one
  18. of the specified basetags if the type inherits from them.
  19. \details Tags can inherit each other. A multi_point inherits, for example,
  20. both the multi_tag and the pointlike_tag. Often behaviour can be shared
  21. between different geometry types. A tag, found by the metafunction tag,
  22. can be casted to a more basic tag, and then dispatched by that tag.
  23. \ingroup core
  24. \tparam Tag The tag to be casted to one of the base tags
  25. \tparam BaseTag First base tag
  26. \tparam BaseTag2 Optional second base tag
  27. \tparam BaseTag3 Optional third base tag
  28. \tparam BaseTag4 Optional fourth base tag
  29. \tparam BaseTag5 Optional fifth base tag
  30. \tparam BaseTag6 Optional sixth base tag
  31. \tparam BaseTag7 Optional seventh base tag
  32. \qbk{[include reference/core/tag_cast.qbk]}
  33. */
  34. template
  35. <
  36. typename Tag,
  37. typename BaseTag,
  38. typename BaseTag2 = void,
  39. typename BaseTag3 = void,
  40. typename BaseTag4 = void,
  41. typename BaseTag5 = void,
  42. typename BaseTag6 = void,
  43. typename BaseTag7 = void
  44. >
  45. struct tag_cast
  46. {
  47. typedef typename boost::mpl::if_
  48. <
  49. typename boost::is_base_of<BaseTag, Tag>::type,
  50. BaseTag,
  51. // Try next one in line:
  52. typename tag_cast
  53. <
  54. Tag, BaseTag2, BaseTag3, BaseTag4,
  55. BaseTag5, BaseTag6, BaseTag7, void
  56. >::type
  57. >::type type;
  58. };
  59. #ifndef DOXYGEN_NO_SPECIALIZATIONS
  60. // Specialization for last one
  61. template <typename Tag>
  62. struct tag_cast<Tag, void, void, void, void, void, void, void>
  63. {
  64. // If not found, take specified tag, so do not cast
  65. typedef Tag type;
  66. };
  67. #endif // DOXYGEN_NO_SPECIALIZATIONS
  68. }} // namespace boost::geometry
  69. #endif // BOOST_GEOMETRY_CORE_TAG_CAST_HPP