mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-10 23:42:12 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into feature/disjoint
This commit is contained in:
@@ -29,8 +29,6 @@
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
@@ -40,6 +41,15 @@
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
|
||||
#include <boost/geometry/util/compress_variant.hpp>
|
||||
#include <boost/geometry/util/transform_variant.hpp>
|
||||
#include <boost/geometry/util/combine_if.hpp>
|
||||
//#include <boost/geometry/util/is_implemented.hpp>
|
||||
|
||||
#include <boost/mpl/always.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -89,6 +99,324 @@ struct distance
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
struct distance
|
||||
: strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type<Geometry1>::type,
|
||||
typename point_type<Geometry2>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct distance<Geometry1, Geometry2, default_strategy>
|
||||
: default_distance_result
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>
|
||||
{};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
|
||||
struct distance
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline typename result_of::distance<Geometry1, Geometry2, Strategy>::type
|
||||
apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
return dispatch::distance<Geometry1, Geometry2, Strategy>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline typename result_of::distance<Geometry1, Geometry2, default_strategy>::type
|
||||
apply(Geometry1 const& geometry1, Geometry2 const& geometry2, default_strategy)
|
||||
{
|
||||
typedef typename detail::distance::default_strategy
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::distance<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
struct distance
|
||||
: resolve_strategy::result_of::distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy>
|
||||
struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy>
|
||||
{
|
||||
// A set of all variant type combinations that are compatible and implemented
|
||||
typedef typename util::combine_if<
|
||||
typename mpl::vector1<Geometry1>,
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
// Here we want should remove most of the combinations that are not valid
|
||||
// mostly to limit the size of the resulting MPL set.
|
||||
// But is_implementedn is not ready for prime time
|
||||
//
|
||||
// util::is_implemented2<mpl::_1, mpl::_2, dispatch::distance<mpl::_1, mpl::_2> >
|
||||
mpl::always<mpl::true_>
|
||||
>::type possible_input_types;
|
||||
|
||||
// The (possibly variant) result type resulting from these combinations
|
||||
typedef typename compress_variant<
|
||||
typename transform_variant<
|
||||
possible_input_types,
|
||||
resolve_strategy::result_of::distance<
|
||||
point_type<mpl::first<mpl::_> >,
|
||||
point_type<mpl::second<mpl::_> >,
|
||||
Strategy
|
||||
>,
|
||||
mpl::back_inserter<mpl::vector0<> >
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
// Distance arguments are commutative
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2, typename Strategy>
|
||||
struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2, Strategy>
|
||||
: public distance<Geometry2, variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Strategy>
|
||||
struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy>
|
||||
{
|
||||
// A set of all variant type combinations that are compatible and implemented
|
||||
typedef typename util::combine_if
|
||||
<
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
// Here we want to try to remove most of the combinations that are not valid
|
||||
// mostly to limit the size of the resulting MPL vector.
|
||||
// But is_implementedn is not ready for prime time
|
||||
//
|
||||
// util::is_implemented2<mpl::_1, mpl::_2, dispatch::distance<mpl::_1, mpl::_2> >
|
||||
mpl::always<mpl::true_>
|
||||
>::type possible_input_types;
|
||||
|
||||
// The (possibly variant) result type resulting from these combinations
|
||||
typedef typename compress_variant<
|
||||
typename transform_variant<
|
||||
possible_input_types,
|
||||
resolve_strategy::result_of::distance<
|
||||
point_type<mpl::first<mpl::_> >,
|
||||
point_type<mpl::second<mpl::_> >,
|
||||
Strategy
|
||||
>,
|
||||
mpl::back_inserter<mpl::vector0<> >
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct distance
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename result_of::distance<Geometry1, Geometry2, Strategy>::type
|
||||
apply(
|
||||
const Geometry1& geometry1,
|
||||
const Geometry2& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_strategy::distance::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Geometry2, typename Strategy>
|
||||
struct visitor: static_visitor
|
||||
<
|
||||
typename result_of::distance
|
||||
<
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::type
|
||||
>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
: m_geometry2(geometry2),
|
||||
m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
result_type operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply
|
||||
<
|
||||
Strategy
|
||||
>(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename result_of::distance
|
||||
<
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::type
|
||||
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return apply_visitor(visitor<Geometry2, Strategy>(geometry2, strategy), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Geometry1, typename Strategy>
|
||||
struct visitor: static_visitor
|
||||
<
|
||||
typename result_of::distance
|
||||
<
|
||||
Geometry1,
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Strategy
|
||||
>::type
|
||||
>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1,
|
||||
Strategy const& strategy)
|
||||
: m_geometry1(geometry1),
|
||||
m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
result_type operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply
|
||||
<
|
||||
Strategy
|
||||
>(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename result_of::distance
|
||||
<
|
||||
Geometry1,
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Strategy
|
||||
>::type
|
||||
apply(
|
||||
Geometry1 const& geometry1,
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return apply_visitor(visitor<Geometry1, Strategy>(geometry1, strategy), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)>
|
||||
struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor
|
||||
<
|
||||
typename result_of::distance
|
||||
<
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(B)>,
|
||||
Strategy
|
||||
>
|
||||
::type
|
||||
>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
result_type operator()(
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply
|
||||
<
|
||||
Strategy
|
||||
>(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename result_of::distance
|
||||
<
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(B)>,
|
||||
Strategy
|
||||
>
|
||||
::type
|
||||
apply(
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1,
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(B)>& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{distance} \brief_strategy
|
||||
\ingroup distance
|
||||
@@ -126,12 +454,12 @@ for distance, it is probably so that there is no specialization
|
||||
for return_type<...> for your strategy.
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type<Geometry1>::type,
|
||||
typename point_type<Geometry2>::type
|
||||
>::type
|
||||
inline typename resolve_variant::result_of::distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::type
|
||||
distance(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
@@ -142,11 +470,10 @@ distance(Geometry1 const& geometry1,
|
||||
detail::throw_on_empty_input(geometry1);
|
||||
detail::throw_on_empty_input(geometry2);
|
||||
|
||||
return dispatch::distance
|
||||
return resolve_variant::distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
@@ -164,18 +491,19 @@ distance(Geometry1 const& geometry1,
|
||||
\qbk{[include reference/algorithms/distance.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline typename default_distance_result<Geometry1, Geometry2>::type distance(
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
inline typename resolve_variant::result_of::distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
default_strategy
|
||||
>::type
|
||||
distance(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename detail::distance::default_strategy
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type default_strategy_type;
|
||||
|
||||
return distance(geometry1, geometry2, default_strategy_type());
|
||||
return distance(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
@@ -175,7 +175,7 @@ struct create_node<
|
||||
return create_static_node<
|
||||
typename Allocators::node_pointer,
|
||||
static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
|
||||
>::template apply(allocators.node_allocator());
|
||||
>::apply(allocators.node_allocator());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -191,7 +191,7 @@ struct create_node<
|
||||
return create_static_node<
|
||||
typename Allocators::node_pointer,
|
||||
static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
|
||||
>::template apply(allocators.node_allocator());
|
||||
>::apply(allocators.node_allocator());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ struct options_type< index::linear<MaxElements, MinElements> >
|
||||
choose_by_content_diff_tag,
|
||||
split_default_tag,
|
||||
linear_tag,
|
||||
node_d_mem_static_tag
|
||||
node_s_mem_static_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
@@ -79,7 +79,7 @@ struct options_type< index::quadratic<MaxElements, MinElements> >
|
||||
choose_by_content_diff_tag,
|
||||
split_default_tag,
|
||||
quadratic_tag,
|
||||
node_d_mem_static_tag
|
||||
node_s_mem_static_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
@@ -92,7 +92,7 @@ struct options_type< index::rstar<MaxElements, MinElements, OverlapCostThreshold
|
||||
choose_by_overlap_diff_tag,
|
||||
split_default_tag,
|
||||
rstar_tag,
|
||||
node_d_mem_static_tag
|
||||
node_s_mem_static_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
@@ -105,7 +105,7 @@ struct options_type< index::rstar<MaxElements, MinElements, OverlapCostThreshold
|
||||
// choose_by_content_diff_tag, // change it?
|
||||
// split_kmeans_tag,
|
||||
// int, // dummy tag - not used for now
|
||||
// node_d_mem_static_tag
|
||||
// node_s_mem_static_tag
|
||||
// > type;
|
||||
//};
|
||||
|
||||
@@ -118,7 +118,7 @@ struct options_type< index::dynamic_linear >
|
||||
choose_by_content_diff_tag,
|
||||
split_default_tag,
|
||||
linear_tag,
|
||||
node_d_mem_dynamic_tag
|
||||
node_s_mem_dynamic_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
@@ -131,7 +131,7 @@ struct options_type< index::dynamic_quadratic >
|
||||
choose_by_content_diff_tag,
|
||||
split_default_tag,
|
||||
quadratic_tag,
|
||||
node_d_mem_dynamic_tag
|
||||
node_s_mem_dynamic_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
@@ -144,7 +144,7 @@ struct options_type< index::dynamic_rstar >
|
||||
choose_by_overlap_diff_tag,
|
||||
split_default_tag,
|
||||
rstar_tag,
|
||||
node_d_mem_dynamic_tag
|
||||
node_s_mem_dynamic_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
78
include/boost/geometry/util/combine_if.hpp
Normal file
78
include/boost/geometry/util/combine_if.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
||||
|
||||
// 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_UTIL_COMBINE_IF_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
|
||||
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bind.hpp>
|
||||
#include <boost/mpl/set.hpp>
|
||||
#include <boost/mpl/insert.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function to generate all the combination of pairs of types
|
||||
from a given sequence Sequence except those that does not satisfy the
|
||||
predicate Pred
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
typedef mpl::vector<mpl::int_<0>, mpl::int_<1> > types;
|
||||
typedef combine_if<types, types, always<true_> >::type combinations;
|
||||
typedef mpl::vector<
|
||||
pair<mpl::int_<1>, mpl::int_<1> >,
|
||||
pair<mpl::int_<1>, mpl::int_<0> >,
|
||||
pair<mpl::int_<0>, mpl::int_<1> >,
|
||||
pair<mpl::int_<0>, mpl::int_<0> >
|
||||
> result_types;
|
||||
|
||||
BOOST_MPL_ASSERT(( mpl::equal<combinations, result_types> ));
|
||||
\endcode
|
||||
*/
|
||||
template <typename Sequence1, typename Sequence2, typename Pred>
|
||||
struct combine_if
|
||||
{
|
||||
struct combine
|
||||
{
|
||||
template <typename Result, typename T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::fold<Sequence2, Result,
|
||||
mpl::if_
|
||||
<
|
||||
mpl::bind<typename mpl::lambda<Pred>::type, T, mpl::_2>,
|
||||
mpl::insert<mpl::_1, mpl::pair<T, mpl::_2> >,
|
||||
mpl::_1
|
||||
>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
typedef typename mpl::fold<Sequence1, mpl::set0<>, combine>::type type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace util
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
|
||||
@@ -23,10 +23,36 @@ namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function that takes a Sequence type, an MPL lambda
|
||||
expression and an optional Inserter and returns a variant type over
|
||||
the same types as the initial variant type, each transformed using
|
||||
the lambda expression.
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
typedef mpl::vector<int, float, long> types;
|
||||
typedef transform_variant<types, add_pointer<_> > transformed;
|
||||
typedef variant<int*, float*, long*> result;
|
||||
BOOST_MPL_ASSERT(( equal<result, transformed> ));
|
||||
\endcode
|
||||
*/
|
||||
template <typename Sequence, typename Op, typename In = boost::mpl::na>
|
||||
struct transform_variant:
|
||||
make_variant_over<
|
||||
typename mpl::transform<
|
||||
Sequence,
|
||||
Op,
|
||||
In
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Meta-function that takes a boost::variant type and an MPL lambda
|
||||
expression and returns a variant type over the same types as the
|
||||
initial variant type, each trasnformed using the lambda expression.
|
||||
initial variant type, each transformed using the lambda expression.
|
||||
\ingroup utility
|
||||
\par Example
|
||||
\code
|
||||
@@ -36,12 +62,11 @@ namespace boost { namespace geometry
|
||||
BOOST_MPL_ASSERT(( equal<result, transformed> ));
|
||||
\endcode
|
||||
*/
|
||||
|
||||
template <typename Variant, typename Op>
|
||||
struct transform_variant:
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Op>
|
||||
struct transform_variant<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Op, boost::mpl::na> :
|
||||
make_variant_over<
|
||||
typename mpl::transform<
|
||||
typename Variant::types,
|
||||
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
|
||||
Op
|
||||
>::type
|
||||
>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
|
||||
#include <boost/geometry/multi/io/wkt/read.hpp>
|
||||
|
||||
#include <boost/variant/variant.hpp>
|
||||
|
||||
BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
|
||||
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
|
||||
@@ -361,7 +362,6 @@ void test_all()
|
||||
test_geometry<P, test::wrapped_boost_array<P, 2> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
|
||||
|
||||
test_distance_linear<P, bg::model::linestring<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
|
||||
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
@@ -432,6 +432,53 @@ void test_large_integers()
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_variant()
|
||||
{
|
||||
typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
|
||||
typedef bg::model::segment<point_type> segment_type;
|
||||
typedef bg::model::box<point_type> box_type;
|
||||
typedef boost::variant<point_type, segment_type, box_type> variant_type;
|
||||
|
||||
point_type point;
|
||||
std::string const point_li = "POINT(1 3)";
|
||||
bg::read_wkt(point_li, point);
|
||||
|
||||
segment_type seg;
|
||||
std::string const seg_li = "LINESTRING(1 1,4 4)";
|
||||
bg::read_wkt(seg_li, seg);
|
||||
|
||||
variant_type v1, v2;
|
||||
|
||||
BOOST_MPL_ASSERT((
|
||||
boost::is_same
|
||||
<
|
||||
bg::resolve_variant::result_of::distance<variant_type, variant_type, bg::default_strategy>::type,
|
||||
double
|
||||
>
|
||||
));
|
||||
|
||||
// Default strategy
|
||||
v1 = point;
|
||||
v2 = point;
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, point), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, point), bg::distance(point, point), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, point), 0.0001);
|
||||
v1 = point;
|
||||
v2 = seg;
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, seg), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(v1, seg), bg::distance(point, seg), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, seg), 0.0001);
|
||||
|
||||
// User defined strategy
|
||||
v1 = point;
|
||||
v2 = point;
|
||||
bg::strategy::distance::haversine<double> s;
|
||||
//BOOST_CHECK_CLOSE(bg::distance(v1, v2, s), bg::distance(point, point, s), 0.0001);
|
||||
//BOOST_CHECK_CLOSE(bg::distance(v1, point, s), bg::distance(point, point, s), 0.0001);
|
||||
//BOOST_CHECK_CLOSE(bg::distance(point, v2, s), bg::distance(point, point, s), 0.0001);
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
#ifdef TEST_ARRAY
|
||||
@@ -472,5 +519,8 @@ int test_main(int, char* [])
|
||||
|
||||
test_empty_input<bg::model::d2::point_xy<int> >();
|
||||
|
||||
test_variant<double>();
|
||||
test_variant<int>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
test-suite boost-geometry-policies
|
||||
:
|
||||
[ run compare.cpp ]
|
||||
[ run rescale_policy.cpp ]
|
||||
# [ run rescale_policy.cpp ]
|
||||
;
|
||||
|
||||
88
test/util/is_implemented.cpp
Normal file
88
test/util/is_implemented.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
||||
|
||||
// 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)
|
||||
|
||||
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/strategies/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/util/is_implemented.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace services
|
||||
{
|
||||
|
||||
|
||||
template <typename Strategy> struct tag
|
||||
{
|
||||
|
||||
typedef not_implemented type;
|
||||
|
||||
};
|
||||
|
||||
}} // namespace strategy::services
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Strategy,
|
||||
typename Tag1 = typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename Tag2 = typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
||||
typename StrategyTag = typename strategy::services::tag<Strategy>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct algorithm_archetype
|
||||
: not_implemented<>
|
||||
{};
|
||||
|
||||
|
||||
struct strategy_archetype
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static void apply(Geometry1, Geometry2) {}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
typedef bg::model::d2::point_xy<double> point_type;
|
||||
|
||||
BOOST_MPL_ASSERT((
|
||||
boost::is_same<
|
||||
bg::util::is_implemented2
|
||||
<
|
||||
point_type, point_type,
|
||||
bg::algorithm_archetype<point_type, point_type, bg::strategy_archetype>
|
||||
>::type,
|
||||
boost::mpl::false_
|
||||
>
|
||||
));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -39,12 +39,30 @@ void check(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>)
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
typedef typename boost::geometry::transform_variant<
|
||||
// Transform Variant to Variant
|
||||
typedef boost::geometry::transform_variant<
|
||||
boost::variant<int, float, long>,
|
||||
boost::add_pointer<_>
|
||||
>::type transformed;
|
||||
>::type transformed1;
|
||||
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed());
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed1());
|
||||
|
||||
// Transform Sequence to Variant (without inserter)
|
||||
typedef boost::geometry::transform_variant<
|
||||
boost::mpl::vector<int, float, long>,
|
||||
boost::add_pointer<_>
|
||||
>::type transformed2;
|
||||
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed2());
|
||||
|
||||
// Transform Sequence to Variant (with inserter)
|
||||
typedef boost::geometry::transform_variant<
|
||||
boost::mpl::vector<int, float, long>,
|
||||
boost::add_pointer<_>,
|
||||
boost::mpl::back_inserter<boost::mpl::vector0<> >
|
||||
>::type transformed3;
|
||||
|
||||
check<boost::mpl::vector<int*, float*, long*> >(transformed3());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user