| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 | // Boost.Geometry (aka GGL, Generic Geometry Library)// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.// This file was modified by Oracle on 2014.// Modifications copyright (c) 2014, Oracle and/or its affiliates.// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.// Use, modification and distribution is subject to the Boost Software License,// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)#ifndef BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP#define BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP#include <boost/range/metafunctions.hpp>#include <boost/variant/apply_visitor.hpp>#include <boost/variant/static_visitor.hpp>#include <boost/variant/variant_fwd.hpp>#include <boost/geometry/algorithms/length.hpp>#include <boost/geometry/algorithms/detail/calculate_null.hpp>#include <boost/geometry/algorithms/detail/calculate_sum.hpp>#include <boost/geometry/algorithms/detail/multi_sum.hpp>// #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>#include <boost/geometry/core/cs.hpp>#include <boost/geometry/core/closure.hpp>#include <boost/geometry/core/tags.hpp>#include <boost/geometry/geometries/concepts/check.hpp>#include <boost/geometry/strategies/default_length_result.hpp>#include <boost/geometry/strategies/default_strategy.hpp>namespace boost { namespace geometry{#ifndef DOXYGEN_NO_DISPATCHnamespace dispatch{// Default perimeter is 0.0, specializations implement calculated valuestemplate <typename Geometry, typename Tag = typename tag<Geometry>::type>struct perimeter : detail::calculate_null{    typedef typename default_length_result<Geometry>::type return_type;    template <typename Strategy>    static inline return_type apply(Geometry const& geometry, Strategy const& strategy)    {        return calculate_null::apply<return_type>(geometry, strategy);    }};template <typename Geometry>struct perimeter<Geometry, ring_tag>    : detail::length::range_length        <            Geometry,            closure<Geometry>::value        >{};template <typename Polygon>struct perimeter<Polygon, polygon_tag> : detail::calculate_polygon_sum{    typedef typename default_length_result<Polygon>::type return_type;    typedef detail::length::range_length                <                    typename ring_type<Polygon>::type,                    closure<Polygon>::value                > policy;    template <typename Strategy>    static inline return_type apply(Polygon const& polygon, Strategy const& strategy)    {        return calculate_polygon_sum::apply<return_type, policy>(polygon, strategy);    }};template <typename MultiPolygon>struct perimeter<MultiPolygon, multi_polygon_tag> : detail::multi_sum{    typedef typename default_length_result<MultiPolygon>::type return_type;    template <typename Strategy>    static inline return_type apply(MultiPolygon const& multi, Strategy const& strategy)    {        return multi_sum::apply               <                   return_type,                   perimeter<typename boost::range_value<MultiPolygon>::type>               >(multi, strategy);    }};// box,n-sphere: to be implemented} // namespace dispatch#endif // DOXYGEN_NO_DISPATCHnamespace resolve_strategy {struct perimeter{    template <typename Geometry, typename Strategy>    static inline typename default_length_result<Geometry>::type    apply(Geometry const& geometry, Strategy const& strategy)    {        return dispatch::perimeter<Geometry>::apply(geometry, strategy);    }    template <typename Geometry>    static inline typename default_length_result<Geometry>::type    apply(Geometry const& geometry, default_strategy)    {        typedef typename strategy::distance::services::default_strategy            <                point_tag, point_tag, typename point_type<Geometry>::type            >::type strategy_type;        return dispatch::perimeter<Geometry>::apply(geometry, strategy_type());    }};} // namespace resolve_strategynamespace resolve_variant {template <typename Geometry>struct perimeter{    template <typename Strategy>    static inline typename default_length_result<Geometry>::type    apply(Geometry const& geometry, Strategy const& strategy)    {        concepts::check<Geometry const>();        return resolve_strategy::perimeter::apply(geometry, strategy);    }};template <BOOST_VARIANT_ENUM_PARAMS(typename T)>struct perimeter<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >{    typedef typename default_length_result        <            boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>        >::type result_type;    template <typename Strategy>    struct visitor: boost::static_visitor<result_type>    {        Strategy const& m_strategy;        visitor(Strategy const& strategy): m_strategy(strategy) {}        template <typename Geometry>        typename default_length_result<Geometry>::type        operator()(Geometry const& geometry) const        {            return perimeter<Geometry>::apply(geometry, m_strategy);        }    };    template <typename Strategy>    static inline result_type    apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,          Strategy const& strategy)    {        return boost::apply_visitor(visitor<Strategy>(strategy), geometry);    }};} // namespace resolve_variant/*!\brief \brief_calc{perimeter}\ingroup perimeter\details The function perimeter returns the perimeter of a geometry,    using the default distance-calculation-strategy\tparam Geometry \tparam_geometry\param geometry \param_geometry\return \return_calc{perimeter}\qbk{[include reference/algorithms/perimeter.qbk]}\qbk{[heading Example][perimeter][perimeter_output]} */template<typename Geometry>inline typename default_length_result<Geometry>::type perimeter(        Geometry const& geometry){    // detail::throw_on_empty_input(geometry);    return resolve_variant::perimeter<Geometry>::apply(geometry, default_strategy());}/*!\brief \brief_calc{perimeter} \brief_strategy\ingroup perimeter\details The function perimeter returns the perimeter of a geometry,    using specified strategy\tparam Geometry \tparam_geometry\tparam Strategy \tparam_strategy{distance}\param geometry \param_geometry\param strategy strategy to be used for distance calculations.\return \return_calc{perimeter}\qbk{distinguish,with strategy}\qbk{[include reference/algorithms/perimeter.qbk]} */template<typename Geometry, typename Strategy>inline typename default_length_result<Geometry>::type perimeter(        Geometry const& geometry, Strategy const& strategy){    // detail::throw_on_empty_input(geometry);    return resolve_variant::perimeter<Geometry>::apply(geometry, strategy);}}} // namespace boost::geometry#endif // BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
 |