diff --git a/include/boost/geometry/util/compress_variant.hpp b/include/boost/geometry/util/compress_variant.hpp new file mode 100644 index 000000000..514771298 --- /dev/null +++ b/include/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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace geometry +{ + + +namespace detail +{ + +template +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 + > +{}; + +template +struct variant_or_single: + mpl::if_< + mpl::equal_to< + mpl::size, + mpl::int_<1> + >, + typename mpl::front::type, + typename make_variant_over::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 variant_type; + typedef compress_variant::type compressed; + typedef mpl::vector result_types; + BOOST_MPL_ASSERT(( mpl::equal )); + + tpyedef variant one_type_variant_type; + typedef compress_variant::type single_type; + BOOST_MPL_ASSERT(( boost::equals )); + \endcode +*/ + +template +struct compress_variant: + detail::variant_or_single< + typename detail::unique_types::type + > +{}; + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_UTIL_COMPRESS_VARIANT_HPP diff --git a/include/boost/geometry/util/transform_variant.hpp b/include/boost/geometry/util/transform_variant.hpp new file mode 100644 index 000000000..21ce501f2 --- /dev/null +++ b/include/boost/geometry/util/transform_variant.hpp @@ -0,0 +1,54 @@ +// 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_TRANSFORM_VARIANT_HPP +#define BOOST_GEOMETRY_UTIL_TRANSFORM_VARIANT_HPP + + +#include +#include + + +namespace boost { namespace geometry +{ + + +/*! + \brief Meta-function that takes a boost::variant type and an MPL lambda + expression and returns a variant type over the same types as the + initial variant type, each trasnformed using the lambda expression. + \ingroup utility + \par Example + \code + typedef variant variant_type; + typedef transform_variant > transformed; + typedef variant result; + BOOST_MPL_ASSERT(( equal )); + \endcode +*/ + +template +struct transform_variant: + make_variant_over< + typename mpl::transform< + typename Variant::types, + Op + >::type + > +{}; + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_UTIL_TRANSFORM_VARIANT_HPP diff --git a/test/util/compress_variant.cpp b/test/util/compress_variant.cpp new file mode 100644 index 000000000..ab7a61ca9 --- /dev/null +++ b/test/util/compress_variant.cpp @@ -0,0 +1,77 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// 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) + + +#include +#include +#include +#include +#include +#include +#include + + +template +void check_variant_types(boost::variant) +{ + BOOST_MPL_ASSERT(( + boost::mpl::equal< + typename boost::variant::types, + ExpectedTypes + > + )); +} + +template +void test_variant_result() +{ + check_variant_types(typename boost::geometry::compress_variant::type()); +} + +template +void test_single_type_result() +{ + BOOST_MPL_ASSERT(( + boost::is_same< + typename boost::geometry::compress_variant::type, + ExpectedType + > + )); +} + + +int test_main(int, char* []) +{ + test_variant_result< + boost::variant, + boost::mpl::vector + >(); + + test_variant_result< + boost::variant, + boost::mpl::vector + >(); + + test_single_type_result< + boost::variant, + int + >(); + + test_single_type_result< + boost::variant, + double + >(); + + return 0; +} diff --git a/test/util/transform_variant.cpp b/test/util/transform_variant.cpp new file mode 100644 index 000000000..6157ee353 --- /dev/null +++ b/test/util/transform_variant.cpp @@ -0,0 +1,50 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// 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) + + +#include +#include +#include +#include +#include +#include +#include +#include + +using boost::mpl::placeholders::_; + + +template +void check(boost::variant) +{ + BOOST_MPL_ASSERT(( + boost::mpl::equal< + typename boost::variant::types, + ExpectedTypes + > + )); +} + + +int test_main(int, char* []) +{ + typedef typename boost::geometry::transform_variant< + boost::variant, + boost::add_pointer<_> + >::type transformed; + + check >(transformed()); + + return 0; +}