$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;
 }