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