blob: 7d1bb05242c9534c8ffe0c60f017036e25f106ab [file] [log] [blame]
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
#include <algorithm>
#include <vector>
#include <boost/assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/less.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace disjoint
{
template<typename MultiPoint1, typename MultiPoint2>
class multipoint_multipoint
{
private:
template <typename Iterator>
class unary_disjoint_predicate
: detail::relate::less
{
private:
typedef detail::relate::less base_type;
public:
unary_disjoint_predicate(Iterator first, Iterator last)
: base_type(), m_first(first), m_last(last)
{}
template <typename Point>
inline bool apply(Point const& point) const
{
return !std::binary_search(m_first,
m_last,
point,
static_cast<base_type const&>(*this));
}
private:
Iterator m_first, m_last;
};
public:
static inline bool apply(MultiPoint1 const& multipoint1,
MultiPoint2 const& multipoint2)
{
BOOST_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
typedef typename boost::range_value<MultiPoint1>::type point1_type;
std::vector<point1_type> points1(boost::begin(multipoint1),
boost::end(multipoint1));
std::sort(points1.begin(), points1.end(), detail::relate::less());
typedef unary_disjoint_predicate
<
typename std::vector<point1_type>::const_iterator
> predicate_type;
return check_iterator_range
<
predicate_type
>::apply(boost::begin(multipoint2),
boost::end(multipoint2),
predicate_type(points1.begin(), points1.end()));
}
};
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template<typename Point, typename MultiPoint, std::size_t DimensionCount>
struct disjoint
<
Point, MultiPoint, DimensionCount, point_tag, multi_point_tag, false
> : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Point>
{};
template<typename MultiPoint, typename Segment, std::size_t DimensionCount>
struct disjoint
<
MultiPoint, Segment, DimensionCount, multi_point_tag, segment_tag, false
> : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Segment>
{};
template<typename MultiPoint, typename Box, std::size_t DimensionCount>
struct disjoint
<
MultiPoint, Box, DimensionCount, multi_point_tag, box_tag, false
> : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Box>
{};
template<typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount>
struct disjoint
<
MultiPoint1, MultiPoint2, DimensionCount,
multi_point_tag, multi_point_tag, false
>
{
static inline bool apply(MultiPoint1 const& multipoint1,
MultiPoint2 const& multipoint2)
{
if ( boost::size(multipoint2) < boost::size(multipoint1) )
{
return detail::disjoint::multipoint_multipoint
<
MultiPoint2, MultiPoint1
>::apply(multipoint2, multipoint1);
}
return detail::disjoint::multipoint_multipoint
<
MultiPoint1, MultiPoint2
>::apply(multipoint1, multipoint2);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP