summaryrefslogtreecommitdiff
path: root/boost/geometry/util/compress_variant.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/util/compress_variant.hpp')
-rw-r--r--boost/geometry/util/compress_variant.hpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/boost/geometry/util/compress_variant.hpp b/boost/geometry/util/compress_variant.hpp
new file mode 100644
index 0000000000..a94cf28894
--- /dev/null
+++ b/boost/geometry/util/compress_variant.hpp
@@ -0,0 +1,98 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// 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:
+ mpl::fold<
+ typename mpl::reverse_fold<
+ typename Variant::types,
+ mpl::set<>,
+ mpl::insert<
+ mpl::placeholders::_1,
+ mpl::placeholders::_2
+ >
+ >::type,
+ mpl::vector<>,
+ mpl::push_back<mpl::placeholders::_1, mpl::placeholders::_2>
+ >
+{};
+
+template <typename Types>
+struct variant_or_single:
+ mpl::if_<
+ mpl::equal_to<
+ mpl::size<Types>,
+ mpl::int_<1>
+ >,
+ typename 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 mpl::vector<int, float, long> result_types;
+ BOOST_MPL_ASSERT(( 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