• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 1999-2003 Jaakko Jarvi
3     Copyright (c) 2001-2011 Joel de Guzman
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/fusion/sequence/intrinsic/at.hpp>
10 #include <boost/fusion/sequence/intrinsic/value_at.hpp>
11 #include <boost/static_assert.hpp>
12 #include <iostream>
13 
14 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
15 #include <functional>
16 #endif
17 
18 #if !defined(FUSION_AT)
19 #define FUSION_AT at_c
20 #endif
21 
22 #if !defined(FUSION_VALUE_AT)
23 #define FUSION_VALUE_AT(S, N) boost::fusion::result_of::value_at_c<S, N>
24 #endif
25 
26 namespace test_detail
27 {
28     // something to prevent warnings for unused variables
dummy(const T &)29     template<class T> void dummy(const T&) {}
30 
31     class A {};
32 }
33 
34 void
test()35 test()
36 {
37     using namespace boost::fusion;
38     using namespace test_detail;
39 
40     double d = 2.7;
41     A a;
42 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
43     // Note: C++11 will pickup the rvalue overload for the d argument
44     // since we do not have all permutations (expensive!) for all const&
45     // and && arguments. We either have all && or all const& arguments only.
46     // For that matter, use std::ref to disambiguate the call.
47 
48     FUSION_SEQUENCE<int, double&, const A&, int> t(1, std::ref(d), a, 2);
49 #else
50     FUSION_SEQUENCE<int, double&, const A&, int> t(1, d, a, 2);
51 #endif
52     const FUSION_SEQUENCE<int, double&, const A, int> ct(t);
53 
54     int i  = FUSION_AT<0>(t);
55     int i2 = FUSION_AT<3>(t);
56 
57     BOOST_TEST(i == 1 && i2 == 2);
58 
59     int j  = FUSION_AT<0>(ct);
60     BOOST_TEST(j == 1);
61 
62     FUSION_AT<0>(t) = 5;
63     BOOST_TEST(FUSION_AT<0>(t) == 5);
64 
65 #if defined(FUSION_TEST_FAIL)
66     FUSION_AT<0>(ct) = 5; // can't assign to const
67 #endif
68 
69     double e = FUSION_AT<1>(t);
70     BOOST_TEST(e > 2.69 && e < 2.71);
71 
72     FUSION_AT<1>(t) = 3.14+i;
73     BOOST_TEST(FUSION_AT<1>(t) > 4.13 && FUSION_AT<1>(t) < 4.15);
74 
75 #if defined(FUSION_TEST_FAIL)
76     FUSION_AT<4>(t) = A(); // can't assign to const
77     dummy(FUSION_AT<5>(ct)); // illegal index
78 #endif
79 
80     ++FUSION_AT<0>(t);
81     BOOST_TEST(FUSION_AT<0>(t) == 6);
82 
83     typedef FUSION_SEQUENCE<int, float> seq_type;
84 
85     BOOST_STATIC_ASSERT(!(
86         boost::is_const<FUSION_VALUE_AT(seq_type, 0)::type>::value));
87 
88     // constness should not affect
89     BOOST_STATIC_ASSERT(!(
90         boost::is_const<FUSION_VALUE_AT(const seq_type, 0)::type>::value));
91 
92     BOOST_STATIC_ASSERT(!(
93         boost::is_const<FUSION_VALUE_AT(seq_type, 1)::type>::value));
94 
95     // constness should not affect
96     BOOST_STATIC_ASSERT(!(
97         boost::is_const<FUSION_VALUE_AT(const seq_type, 1)::type>::value));
98 
99     dummy(i); dummy(i2); dummy(j); dummy(e); // avoid warns for unused variables
100 }
101