| // Boost.Geometry (aka GGL, Generic Geometry Library) |
| |
| // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. |
| // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. |
| // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. |
| |
| // This file was modified by Oracle on 2015. |
| // Modifications copyright (c) 2015, 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_UTIL_COMPRESS_VARIANT_HPP |
| #define BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP |
| |
| |
| #include <boost/mpl/equal_to.hpp> |
| #include <boost/mpl/fold.hpp> |
| #include <boost/mpl/front.hpp> |
| #include <boost/mpl/if.hpp> |
| #include <boost/mpl/insert.hpp> |
| #include <boost/mpl/int.hpp> |
| #include <boost/mpl/set.hpp> |
| #include <boost/mpl/size.hpp> |
| #include <boost/mpl/vector.hpp> |
| #include <boost/variant/variant_fwd.hpp> |
| |
| |
| namespace boost { namespace geometry |
| { |
| |
| |
| namespace detail |
| { |
| |
| template <typename Variant> |
| struct unique_types: |
| boost::mpl::fold< |
| typename boost::mpl::reverse_fold< |
| typename Variant::types, |
| boost::mpl::set<>, |
| boost::mpl::insert< |
| boost::mpl::placeholders::_1, |
| boost::mpl::placeholders::_2 |
| > |
| >::type, |
| boost::mpl::vector<>, |
| boost::mpl::push_back |
| < |
| boost::mpl::placeholders::_1, boost::mpl::placeholders::_2 |
| > |
| > |
| {}; |
| |
| template <typename Types> |
| struct variant_or_single: |
| boost::mpl::if_< |
| boost::mpl::equal_to< |
| boost::mpl::size<Types>, |
| boost::mpl::int_<1> |
| >, |
| typename boost::mpl::front<Types>::type, |
| typename make_variant_over<Types>::type |
| > |
| {}; |
| |
| } // namespace detail |
| |
| |
| /*! |
| \brief Meta-function that takes a boost::variant type and tries to minimize |
| it by doing the following: |
| - if there's any duplicate types, remove them |
| - if the result is a variant of one type, turn it into just that type |
| \ingroup utility |
| \par Example |
| \code |
| typedef variant<int, float, int, long> variant_type; |
| typedef compress_variant<variant_type>::type compressed; |
| typedef boost::mpl::vector<int, float, long> result_types; |
| BOOST_MPL_ASSERT(( boost::mpl::equal<compressed::types, result_types> )); |
| |
| typedef variant<int, int, int> one_type_variant_type; |
| typedef compress_variant<one_type_variant_type>::type single_type; |
| BOOST_MPL_ASSERT(( boost::equals<single_type, int> )); |
| \endcode |
| */ |
| |
| template <typename Variant> |
| struct compress_variant: |
| detail::variant_or_single< |
| typename detail::unique_types<Variant>::type |
| > |
| {}; |
| |
| |
| }} // namespace boost::geometry |
| |
| |
| #endif // BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP |