compress_variant.hpp 3.2 KB

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