Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / variant / test / recursive_variant_test.cpp
index 85cad38..8b64348 100644 (file)
@@ -3,14 +3,43 @@
 // See http://www.boost.org for updates, documentation, and revision history.
 //-----------------------------------------------------------------------------
 //
-// Copyright (c) 2003
-// Eric Friedman, Itay Maman
+// Copyright (c) 2003 Eric Friedman, Itay Maman
+// Copyright (c) 2013 Antony Polukhin
 //
 // Distributed under 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 "boost/test/minimal.hpp"
+
+// This file is used in two test cases:
+//
+// 1) recursive_variant_test.cpp that tests recursive usage of variant
+//
+// 2) variant_noexcept_test that tests Boost.Variant ability to compile 
+// and work with disabled exceptions
+
+#ifdef BOOST_NO_EXCEPTIONS
+// `boost/test/minimal.hpp` cannot work with exceptions disabled,
+// so we need the following workarounds for that case:
+namespace boost {
+    int exit_success = 0;
+}
+
+int test_main(int , char* []);
+
+int main( int argc, char* argv[] )
+{
+    return test_main(argc, argv);
+}
+
+#include <stdlib.h>
+#define BOOST_CHECK(exp) if (!(exp)) exit(EXIT_FAILURE)
+
+#else // BOOST_NO_EXCEPTIONS
+#   include "boost/test/minimal.hpp"
+#endif // BOOST_NO_EXCEPTIONS
+
+
 #include "boost/variant.hpp"
 #include "boost/mpl/vector.hpp"
 #include "boost/mpl/copy.hpp"
 #include <sstream>
 #include <vector>
 #include <map>
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+#include <tuple>
+#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
 
-struct vector_printer
+struct printer
     : boost::static_visitor<std::string>
 {
+    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+    std::string operator()(
+            const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &var) const
+    {
+        return boost::apply_visitor( printer(), var );
+    }
+
     template <typename T>
     std::string operator()(const std::vector<T>& vec) const
     {
@@ -32,13 +71,36 @@ struct vector_printer
 
         typename std::vector<T>::const_iterator it = vec.begin();
         for (; it != vec.end(); ++it)
-            ost << boost::apply_visitor( vector_printer(), *it );
+            ost << printer()( *it );
 
         ost << ") ";
 
         return ost.str();
     }
 
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+    template <int...> struct indices {};
+    template <typename... Ts, int... Is>
+    std::string operator()(const std::tuple<Ts...>& tup, indices<Is...>)
+    {
+        std::ostringstream ost;
+        ost << "( ";
+        (void) (int []){0, (ost << printer()( std::get<Is>(tup) ), 0)... };
+        ost << ") ";
+        return ost.str();
+    }
+
+    template <int N, int... Is>
+        struct make_indices : make_indices<N-1, N-1, Is...> {};
+    template <int... Is>
+        struct make_indices<0, Is...> : indices<Is...> {};
+    template <typename... Ts>
+    std::string operator()(const std::tuple<Ts...>& tup) const
+    {
+        return printer()(tup, make_indices<sizeof...(Ts)>());
+    }
+#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+
     template <typename T>
     std::string operator()(const T& operand) const
     {
@@ -62,7 +124,7 @@ void test_recursive_variant()
     vec1.push_back(7);
 
     var1_t var1(vec1);
-    std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
+    std::string result1( printer()(var1) );
 
     std::cout << "result1: " << result1 << '\n';
     BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
@@ -79,7 +141,7 @@ void test_recursive_variant()
     vec2.push_back(boost::variant<int, double>(7));
 
     var2_t var2(vec2);
-    std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
+    std::string result2( printer()(var2) );
 
     std::cout << "result2: " << result2 << '\n';
     BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
@@ -106,7 +168,7 @@ void test_recursive_variant()
     vec3.push_back(7);
 
     var4_t var4(vec3);
-    std::string result3( boost::apply_visitor( vector_printer(), var4 ) );
+    std::string result3( printer()(var4) );
 
     std::cout << "result2: " << result3 << '\n';
     BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
@@ -121,7 +183,7 @@ void test_recursive_variant()
     vec5.push_back(vec1);
     vec5.push_back(17.25);
 
-    std::string result5( vector_printer()(vec5) );
+    std::string result5( printer()(vec5) );
 
     std::cout << "result5: " << result5 << '\n';
     BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
@@ -131,6 +193,21 @@ void test_recursive_variant()
           std::map<int, boost::recursive_variant_>
         >::type var6_t;
     var6_t var6;
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+    typedef boost::make_recursive_variant<
+          int,
+          std::tuple<int, boost::recursive_variant_>
+        >::type var7_t;
+    var7_t var7 = 0;
+    var7 = std::tuple<int, var7_t>(1, var7);
+    var7 = std::tuple<int, var7_t>(2, var7);
+
+    std::string result7( printer()(var7) );
+
+    std::cout << "result7: " << result7 << '\n';
+    BOOST_CHECK(result7 == "( 2 ( 1 0 ) ) ");
+#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
 }
 
 void test_recursive_variant_over()
@@ -149,7 +226,7 @@ void test_recursive_variant_over()
     vec1.push_back(7);
 
     var1_t var1(vec1);
-    std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
+    std::string result1( printer()(var1) );
 
     std::cout << "result1: " << result1 << '\n';
     BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
@@ -168,7 +245,7 @@ void test_recursive_variant_over()
     vec2.push_back(boost::variant<int, double>(7));
 
     var2_t var2(vec2);
-    std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
+    std::string result2( printer()(var2) );
 
     std::cout << "result2: " << result2 << '\n';
     BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
@@ -206,7 +283,7 @@ void test_recursive_variant_over()
     vec3.push_back(7);
 
     var4_t var3(vec3);
-    std::string result3( boost::apply_visitor( vector_printer(), var3 ) );
+    std::string result3( printer()(var3) );
 
     std::cout << "result2: " << result3 << '\n';
     BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
@@ -223,7 +300,7 @@ void test_recursive_variant_over()
     vec5.push_back(vec1);
     vec5.push_back(17.25);
 
-    std::string result5( vector_printer()(vec5) );
+    std::string result5( printer()(vec5) );
 
     std::cout << "result5: " << result5 << '\n';
     BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");