compress_variant.hpp 3.0 KB

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