Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Improve Variant support (run-time exception, lazy_not_implemented) #290

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 190 additions & 0 deletions include/boost/geometry/algorithms/is_not_implemented.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2015, Oracle and/or its affiliates.

// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle

// 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_IS_NOT_IMPLEMENTED_HPP
#define BOOST_GEOMETRY_ALGORITHMS_IS_NOT_IMPLEMENTED_HPP


#include <boost/mpl/begin.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/next.hpp>
#include <boost/variant/variant_fwd.hpp>

#include <boost/geometry/algorithms/not_implemented.hpp>


namespace boost { namespace geometry {

namespace detail { namespace is_not_implemented {

template
<
typename Seq,
typename MetaPred,
typename PrevState,
typename First = typename boost::mpl::begin<Seq>::type,
typename Last = typename boost::mpl::end<Seq>::type
>
struct for_each
{
typedef typename for_each
<
Seq,
MetaPred,
typename MetaPred::template apply
<
typename boost::mpl::deref<First>::type,
PrevState
>,
typename boost::mpl::next<First>::type,
Last
>::type type;
};

template
<
typename Seq,
typename MetaPred,
typename PrevState,
typename Last
>
struct for_each<Seq, MetaPred, PrevState, Last, Last>
{
typedef PrevState type;
};

template <typename MetaPolicy>
struct reverse
{
template <typename Geometry1, typename Geometry2>
struct apply
: MetaPolicy::template apply<Geometry2, Geometry1>
{};
};

template <typename Geometry, typename MetaPolicy>
struct metapred
{
template <typename SeqEl, typename PrevState>
struct apply
: boost::mpl::bool_
<
PrevState::value &&
MetaPolicy::template apply<Geometry, SeqEl>::value
>
{};
};

template <typename Seq2, typename MetaPolicy>
struct metapred_2
{
template <typename Seq1El, typename PrevState>
struct apply
: boost::mpl::bool_
<
PrevState::value &&
for_each
<
Seq2,
metapred<Seq1El, MetaPolicy>,
boost::mpl::bool_<true>
>::type::value
>
{};
};

}} // namespace detail::is_not_implemented


/*!
A utility for checking if an algorithm is not implemented for some Geometries.
For variants it checks all combinations of Geometries and sets value to false
only if all combinations are not implemented.
*/
template <typename Geometry1, typename Geometry2, typename MetaPolicy>
struct is_not_implemented
: MetaPolicy::template apply<Geometry1, Geometry2>
{};

template
<
typename Geometry1,
BOOST_VARIANT_ENUM_PARAMS(typename T),
typename MetaPolicy
>
struct is_not_implemented
<
Geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
MetaPolicy
>
: detail::is_not_implemented::for_each
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
detail::is_not_implemented::metapred<Geometry1, MetaPolicy>,
boost::mpl::bool_<true>
>::type
{};

template
<
BOOST_VARIANT_ENUM_PARAMS(typename T),
typename Geometry2,
typename MetaPolicy
>
struct is_not_implemented
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
Geometry2,
MetaPolicy
>
: detail::is_not_implemented::for_each
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
detail::is_not_implemented::metapred
<
Geometry2,
detail::is_not_implemented::reverse<MetaPolicy>
>,
boost::mpl::bool_<true>
>::type
{};

template
<
BOOST_VARIANT_ENUM_PARAMS(typename T1),
BOOST_VARIANT_ENUM_PARAMS(typename T2),
typename MetaPolicy
>
struct is_not_implemented
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
MetaPolicy
>
: detail::is_not_implemented::for_each
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>::types,
detail::is_not_implemented::metapred_2
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>::types,
MetaPolicy
>,
boost::mpl::bool_<true>
>::type
{
};

}} // namespace boost::geometry


#endif // BOOST_GEOMETRY_ALGORITHMS_IS_NOT_IMPLEMENTED_HPP
97 changes: 96 additions & 1 deletion include/boost/geometry/algorithms/not_implemented.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// Modifications copyright (c) 2015, Oracle and/or its affiliates.

// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, 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.
Expand All @@ -20,6 +21,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_NOT_IMPLEMENTED_HPP
#define BOOST_GEOMETRY_ALGORITHMS_NOT_IMPLEMENTED_HPP

#include <boost/geometry/core/exception.hpp>

#include <boost/mpl/assert.hpp>
#include <boost/mpl/identity.hpp>
Expand Down Expand Up @@ -96,7 +98,7 @@ template <> struct tag_to_term<geometry_collection_tag> { typedef info::GEOM
template <int D> struct tag_to_term<boost::mpl::int_<D> > { typedef info::DIMENSION<D> type; };


}
} // namespace nyi


template
Expand Down Expand Up @@ -125,6 +127,99 @@ struct not_implemented
{};


template
<
typename Result = void,
typename Term1 = void,
typename Term2 = void,
typename Term3 = void
>
struct lazy_not_implemented
: nyi::not_implemented_tag
{
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
template <typename... T1>
static inline Result apply(T1 const&...)
{
not_implemented<Term1, Term2, Term3>();
return Result();
}
#else
static inline Result apply()
{
not_implemented<Term1, Term2, Term3>();
return Result();
}

template <typename T1, typename T2>
static inline Result apply(T1 const&, T2 const&)
{
not_implemented<Term1, Term2, Term3>();
return Result();
}

template <typename T1, typename T2, typename T3>
static inline Result apply(T1 const&, T2 const&, T3 const&)
{
not_implemented<Term1, Term2, Term3>();
return Result();
}

template <typename T1, typename T2, typename T3, typename T4>
static inline Result apply(T1 const&, T2 const&, T3 const&, T4 const&)
{
not_implemented<Term1, Term2, Term3>();
return Result();
}
#endif
};

template <typename Term1, typename Term2, typename Term3>
struct lazy_not_implemented<void, Term1, Term2, Term3>
: nyi::not_implemented_tag
{
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
template <typename... T1>
static inline void apply(T1 const&...)
{
not_implemented<Term1, Term2, Term3>();
}
#else
static inline void apply()
{
not_implemented<Term1, Term2, Term3>();
}

template <typename T1, typename T2>
static inline void apply(T1 const&, T2 const&)
{
not_implemented<Term1, Term2, Term3>();
}

template <typename T1, typename T2, typename T3>
static inline void apply(T1 const&, T2 const&, T3 const&)
{
not_implemented<Term1, Term2, Term3>();
}

template <typename T1, typename T2, typename T3, typename T4>
static inline void apply(T1 const&, T2 const&, T3 const&, T4 const&)
{
not_implemented<Term1, Term2, Term3>();
}
#endif
};


struct not_implemented_exception
: boost::geometry::exception
{
const char * what() const throw()
{
return "THIS_OPERATION_IS_NOT_OR_NOT_YET_IMPLEMENTED for passed input types";
}
};

}} // namespace boost::geometry


Expand Down
Loading