1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. 6 7 // This file was modified by Oracle on 2015. 8 // Modifications copyright (c) 2015, Oracle and/or its affiliates. 9 10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 11 12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 14 15 // Use, modification and distribution is subject to the Boost Software License, 16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 17 // http://www.boost.org/LICENSE_1_0.txt) 18 19 #ifndef BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP 20 #define BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP 21 22 23 #include <boost/mpl/equal_to.hpp> 24 #include <boost/mpl/fold.hpp> 25 #include <boost/mpl/front.hpp> 26 #include <boost/mpl/if.hpp> 27 #include <boost/mpl/insert.hpp> 28 #include <boost/mpl/int.hpp> 29 #include <boost/mpl/set.hpp> 30 #include <boost/mpl/size.hpp> 31 #include <boost/mpl/vector.hpp> 32 #include <boost/variant/variant_fwd.hpp> 33 34 35 namespace boost { namespace geometry 36 { 37 38 39 namespace detail 40 { 41 42 template <typename Variant> 43 struct unique_types: 44 boost::mpl::fold< 45 typename boost::mpl::reverse_fold< 46 typename Variant::types, 47 boost::mpl::set<>, 48 boost::mpl::insert< 49 boost::mpl::placeholders::_1, 50 boost::mpl::placeholders::_2 51 > 52 >::type, 53 boost::mpl::vector<>, 54 boost::mpl::push_back 55 < 56 boost::mpl::placeholders::_1, boost::mpl::placeholders::_2 57 > 58 > 59 {}; 60 61 template <typename Types> 62 struct variant_or_single: 63 boost::mpl::if_< 64 boost::mpl::equal_to< 65 boost::mpl::size<Types>, 66 boost::mpl::int_<1> 67 >, 68 typename boost::mpl::front<Types>::type, 69 typename make_variant_over<Types>::type 70 > 71 {}; 72 73 } // namespace detail 74 75 76 /*! 77 \brief Meta-function that takes a boost::variant type and tries to minimize 78 it by doing the following: 79 - if there's any duplicate types, remove them 80 - if the result is a variant of one type, turn it into just that type 81 \ingroup utility 82 \par Example 83 \code 84 typedef variant<int, float, int, long> variant_type; 85 typedef compress_variant<variant_type>::type compressed; 86 typedef boost::mpl::vector<int, float, long> result_types; 87 BOOST_MPL_ASSERT(( boost::mpl::equal<compressed::types, result_types> )); 88 89 typedef variant<int, int, int> one_type_variant_type; 90 typedef compress_variant<one_type_variant_type>::type single_type; 91 BOOST_MPL_ASSERT(( boost::equals<single_type, int> )); 92 \endcode 93 */ 94 95 template <typename Variant> 96 struct compress_variant: 97 detail::variant_or_single< 98 typename detail::unique_types<Variant>::type 99 > 100 {}; 101 102 103 }} // namespace boost::geometry 104 105 106 #endif // BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP 107