1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. 6 7 // This file was modified by Oracle on 2014-2020. 8 // Modifications copyright (c) 2014-2020, Oracle and/or its affiliates. 9 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 11 12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 14 15 // Use, modification and distribution is subject to the Boost Software License, 16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 17 // http://www.boost.org/LICENSE_1_0.txt) 18 19 20 #ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP 21 #define BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP 22 23 #include <cstddef> 24 25 #include <boost/range/size.hpp> 26 27 #include <boost/variant/apply_visitor.hpp> 28 #include <boost/variant/static_visitor.hpp> 29 #include <boost/variant/variant_fwd.hpp> 30 31 #include <boost/geometry/algorithms/not_implemented.hpp> 32 33 #include <boost/geometry/core/tag.hpp> 34 #include <boost/geometry/core/tags.hpp> 35 #include <boost/geometry/core/tag_cast.hpp> 36 37 #include <boost/geometry/geometries/concepts/check.hpp> 38 39 #include <boost/geometry/algorithms/detail/counting.hpp> 40 41 42 namespace boost { namespace geometry 43 { 44 45 46 #ifndef DOXYGEN_NO_DISPATCH 47 namespace dispatch 48 { 49 50 51 template 52 < 53 typename Geometry, 54 typename Tag = typename tag_cast 55 < 56 typename tag<Geometry>::type, 57 single_tag, 58 multi_tag 59 >::type 60 > 61 struct num_geometries: not_implemented<Tag> 62 {}; 63 64 65 template <typename Geometry> 66 struct num_geometries<Geometry, single_tag> 67 : detail::counting::other_count<1> 68 {}; 69 70 71 template <typename MultiGeometry> 72 struct num_geometries<MultiGeometry, multi_tag> 73 { 74 static inline std::size_t apply(MultiGeometry const& multi_geometry) 75 { 76 return boost::size(multi_geometry); 77 } 78 }; 79 80 81 } // namespace dispatch 82 #endif // DOXYGEN_NO_DISPATCH 83 84 85 namespace resolve_variant 86 { 87 88 template <typename Geometry> 89 struct num_geometries 90 { 91 static inline std::size_t apply(Geometry const& geometry) 92 { 93 concepts::check<Geometry const>(); 94 95 return dispatch::num_geometries<Geometry>::apply(geometry); 96 } 97 }; 98 99 template <BOOST_VARIANT_ENUM_PARAMS(typename T)> 100 struct num_geometries<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > 101 { 102 struct visitor: boost::static_visitor<std::size_t> 103 { 104 template <typename Geometry> 105 inline std::size_t operator()(Geometry const& geometry) const 106 { 107 return num_geometries<Geometry>::apply(geometry); 108 } 109 }; 110 111 static inline std::size_t 112 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry) 113 { 114 return boost::apply_visitor(visitor(), geometry); 115 } 116 }; 117 118 } // namespace resolve_variant 119 120 121 /*! 122 \brief \brief_calc{number of geometries} 123 \ingroup num_geometries 124 \details \details_calc{num_geometries, number of geometries}. 125 \tparam Geometry \tparam_geometry 126 \param geometry \param_geometry 127 \return \return_calc{number of geometries} 128 129 \qbk{[include reference/algorithms/num_geometries.qbk]} 130 */ 131 template <typename Geometry> 132 inline std::size_t num_geometries(Geometry const& geometry) 133 { 134 return resolve_variant::num_geometries<Geometry>::apply(geometry); 135 } 136 137 138 }} // namespace boost::geometry 139 140 141 #endif // BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP 142