Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62753 - in trunk: boost/variant libs/variant/test
From: steven_at_[hidden]
Date: 2010-06-10 14:16:20


Author: steven_watanabe
Date: 2010-06-10 14:16:19 EDT (Thu, 10 Jun 2010)
New Revision: 62753
URL: http://svn.boost.org/trac/boost/changeset/62753

Log:
Make sure that recursive_variant_ substitution works in all cases. Fixes #1654
Text files modified:
   trunk/boost/variant/recursive_variant.hpp | 63 ++++++++-----
   trunk/libs/variant/test/recursive_variant_test.cpp | 185 +++++++++++++++++++++++++++++++++++++--
   2 files changed, 211 insertions(+), 37 deletions(-)

Modified: trunk/boost/variant/recursive_variant.hpp
==============================================================================
--- trunk/boost/variant/recursive_variant.hpp (original)
+++ trunk/boost/variant/recursive_variant.hpp 2010-06-10 14:16:19 EDT (Thu, 10 Jun 2010)
@@ -21,15 +21,15 @@
 
 #include "boost/mpl/aux_/lambda_arity_param.hpp"
 
-#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
-# include "boost/mpl/eval_if.hpp"
-# include "boost/mpl/identity.hpp"
-# include "boost/mpl/protect.hpp"
-# include "boost/mpl/transform.hpp"
-#else
-# include "boost/preprocessor/cat.hpp"
-# include "boost/preprocessor/repeat.hpp"
-#endif
+#include "boost/mpl/equal.hpp"
+#include "boost/mpl/eval_if.hpp"
+#include "boost/mpl/identity.hpp"
+#include "boost/mpl/if.hpp"
+#include "boost/mpl/protect.hpp"
+#include "boost/mpl/transform.hpp"
+#include "boost/type_traits/is_same.hpp"
+#include "boost/preprocessor/cat.hpp"
+#include "boost/preprocessor/repeat.hpp"
 
 #include "boost/mpl/bool.hpp"
 #include "boost/mpl/is_sequence.hpp"
@@ -74,34 +74,48 @@
       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
>
 struct substitute<
- ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
+ ::boost::variant<
+ ::boost::detail::variant::over_sequence< T0 >
+ , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
+ >
     , RecursiveVariant
     , ::boost::recursive_variant_
       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
>
 {
+private:
 
-#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
-
-private: // helpers, for metafunction result (below)
-
- typedef typename mpl::eval_if<
- ::boost::detail::variant::is_over_sequence<T0>
- , mpl::identity< T0 >
- , make_variant_list< BOOST_VARIANT_ENUM_PARAMS(T) >
- >::type initial_types;
+ typedef T0 initial_types;
 
     typedef typename mpl::transform<
           initial_types
         , mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
>::type types;
 
-public: // metafunction result
-
- typedef ::boost::variant< types > type;
+public:
 
-#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
+ typedef typename mpl::if_<
+ mpl::equal<initial_types, types, ::boost::is_same<mpl::_1, mpl::_2> >
+ , ::boost::variant<
+ ::boost::detail::variant::over_sequence< T0 >
+ , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
+ >
+ , ::boost::variant< over_sequence<types> >
+ >::type type;
+};
 
+template <
+ BOOST_VARIANT_ENUM_PARAMS(typename T)
+ , typename RecursiveVariant
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
+ >
+struct substitute<
+ ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
+ , RecursiveVariant
+ , ::boost::recursive_variant_
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
+ >
+{
 private: // helpers, for metafunction result (below)
 
     #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
@@ -123,9 +137,6 @@
 public: // metafunction result
 
     typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
-
-#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
-
 };
 
 #else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)

Modified: trunk/libs/variant/test/recursive_variant_test.cpp
==============================================================================
--- trunk/libs/variant/test/recursive_variant_test.cpp (original)
+++ trunk/libs/variant/test/recursive_variant_test.cpp 2010-06-10 14:16:19 EDT (Thu, 10 Jun 2010)
@@ -12,6 +12,8 @@
 
 #include "boost/test/minimal.hpp"
 #include "boost/variant.hpp"
+#include "boost/mpl/vector.hpp"
+#include "boost/mpl/copy.hpp"
 
 #include <iostream>
 #include <sstream>
@@ -45,24 +47,185 @@
     }
 };
 
-int test_main(int , char* [])
+void test_recursive_variant()
 {
     typedef boost::make_recursive_variant<
           int
         , std::vector<boost::recursive_variant_>
- >::type var_t;
+ >::type var1_t;
+
+ std::vector<var1_t> vec1;
+ vec1.push_back(3);
+ vec1.push_back(5);
+ vec1.push_back(vec1);
+ vec1.push_back(7);
+
+ var1_t var1(vec1);
+ std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
+
+ std::cout << "result1: " << result1 << '\n';
+ BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
+
+ typedef boost::make_recursive_variant<
+ boost::variant<int, double>
+ , std::vector<boost::recursive_variant_>
+ >::type var2_t;
+
+ std::vector<var2_t> vec2;
+ vec2.push_back(boost::variant<int, double>(3));
+ vec2.push_back(boost::variant<int, double>(3.5));
+ vec2.push_back(vec2);
+ vec2.push_back(boost::variant<int, double>(7));
+
+ var2_t var2(vec2);
+ std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
+
+ std::cout << "result2: " << result2 << '\n';
+ BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
+
+ typedef boost::make_recursive_variant<
+ int
+ , std::vector<
+ boost::variant<
+ double
+ , std::vector<boost::recursive_variant_>
+ >
+ >
+ >::type var3_t;
+
+ typedef boost::variant<double, std::vector<var3_t> > var4_t;
+
+ std::vector<var3_t> vec3;
+ vec3.push_back(3);
+ vec3.push_back(5);
+ std::vector<var4_t> vec4;
+ vec4.push_back(3.5);
+ vec4.push_back(vec3);
+ vec3.push_back(vec4);
+ vec3.push_back(7);
+
+ var4_t var4(vec3);
+ std::string result3( boost::apply_visitor( vector_printer(), var4 ) );
 
- std::vector<var_t> vec;
- vec.push_back(3);
- vec.push_back(5);
- vec.push_back(vec);
- vec.push_back(7);
+ std::cout << "result2: " << result3 << '\n';
+ BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
 
- var_t var(vec);
- std::string result( boost::apply_visitor( vector_printer(), var ) );
+ typedef boost::make_recursive_variant<
+ double,
+ std::vector<var1_t>
+ >::type var5_t;
+
+ std::vector<var5_t> vec5;
+ vec5.push_back(3.5);
+ vec5.push_back(vec1);
+ vec5.push_back(17.25);
+
+ std::string result5( vector_printer()(vec5) );
+
+ std::cout << "result5: " << result5 << '\n';
+ BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
+}
+
+void test_recursive_variant_over()
+{
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ int
+ , std::vector<boost::recursive_variant_>
+ >
+ >::type var1_t;
+
+ std::vector<var1_t> vec1;
+ vec1.push_back(3);
+ vec1.push_back(5);
+ vec1.push_back(vec1);
+ vec1.push_back(7);
+
+ var1_t var1(vec1);
+ std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
+
+ std::cout << "result1: " << result1 << '\n';
+ BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
+
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ boost::make_variant_over<boost::mpl::vector<int, double> >::type
+ , std::vector<boost::recursive_variant_>
+ >
+ >::type var2_t;
+
+ std::vector<var2_t> vec2;
+ vec2.push_back(boost::variant<int, double>(3));
+ vec2.push_back(boost::variant<int, double>(3.5));
+ vec2.push_back(vec2);
+ vec2.push_back(boost::variant<int, double>(7));
+
+ var2_t var2(vec2);
+ std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
+
+ std::cout << "result2: " << result2 << '\n';
+ BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
+
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ int
+ , std::vector<
+ boost::make_variant_over<
+ boost::mpl::vector<
+ double
+ , std::vector<boost::recursive_variant_>
+ >
+ >::type
+ >
+ >
+ >::type var3_t;
+
+ typedef boost::make_variant_over<
+ boost::mpl::copy<
+ boost::mpl::vector<
+ double
+ , std::vector<var3_t>
+ >
+ >::type
+ >::type var4_t;
+
+ std::vector<var3_t> vec3;
+ vec3.push_back(3);
+ vec3.push_back(5);
+ std::vector<var4_t> vec4;
+ vec4.push_back(3.5);
+ vec4.push_back(vec3);
+ vec3.push_back(vec4);
+ vec3.push_back(7);
+
+ var4_t var3(vec3);
+ std::string result3( boost::apply_visitor( vector_printer(), var3 ) );
+
+ std::cout << "result2: " << result3 << '\n';
+ BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
+
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ double
+ , std::vector<var1_t>
+ >
+ >::type var5_t;
+
+ std::vector<var5_t> vec5;
+ vec5.push_back(3.5);
+ vec5.push_back(vec1);
+ vec5.push_back(17.25);
 
- std::cout << "result: " << result << '\n';
- BOOST_CHECK(result == "( 3 5 ( 3 5 ) 7 ) ");
+ std::string result5( vector_printer()(vec5) );
+
+ std::cout << "result5: " << result5 << '\n';
+ BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
+}
+
+int test_main(int , char* [])
+{
+ test_recursive_variant();
+ test_recursive_variant_over();
 
     return boost::exit_success;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk