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 <string>
9 
10 #include <boost/detail/lightweight_test.hpp>
11 #include <boost/fusion/sequence/intrinsic/at.hpp>
12 #include <boost/fusion/mpl.hpp>
13 #include <boost/preprocessor/cat.hpp>
14 #include <boost/mpl/insert_range.hpp>
15 #include <boost/mpl/vector.hpp>
16 #include <boost/mpl/begin.hpp>
17 #include <boost/mpl/equal.hpp>
18 #include <boost/static_assert.hpp>
19 
20 #include "fixture.hpp"
21 
22 #if !defined(FUSION_AT)
23 #define FUSION_AT at_c
24 #endif
25 
26 #if !defined(FUSION_MAKE)
27 #define FUSION_MAKE BOOST_PP_CAT(make_, FUSION_SEQUENCE)
28 #endif
29 
30 #if !defined(FUSION_TIE)
31 #define FUSION_TIE BOOST_PP_CAT(FUSION_SEQUENCE, _tie)
32 #endif
33 
34 namespace test_detail
35 {
36     // classes with different kinds of conversions
37     class AA {};
38     class BB : public AA {};
CCtest_detail::CC39     struct CC { CC() {} CC(const BB&) {} };
operator CCtest_detail::DD40     struct DD { operator CC() const { return CC(); }; };
41 }
42 
test_mpl()43 void test_mpl()
44 {
45     using namespace boost::fusion;
46 
47     typedef FUSION_SEQUENCE<int, char> seq;
48 
49     typedef
50         boost::mpl::insert_range<
51             boost::mpl::vector<>
52           , boost::mpl::end< boost::mpl::vector<> >::type
53           , seq
54         >::type
55     sequence;
56 
57     typedef boost::mpl::equal<sequence, boost::mpl::vector<int, char> > equal;
58     BOOST_STATIC_ASSERT(equal::value);
59 }
60 
61 template <template <typename> class Scenario>
62 void
test()63 test()
64 {
65     using namespace boost::fusion;
66     using namespace test_detail;
67 
68     FUSION_SEQUENCE<int, char> t1(4, 'a');
69     FUSION_SEQUENCE<int, char> t2(5, 'b');
70     t2 = t1;
71     BOOST_TEST(FUSION_AT<0>(t1) == FUSION_AT<0>(t2));
72     BOOST_TEST(FUSION_AT<1>(t1) == FUSION_AT<1>(t2));
73 
74     FUSION_SEQUENCE<long, std::string> t3(2, "a");
75     t3 = t1;
76     BOOST_TEST((double)FUSION_AT<0>(t1) == FUSION_AT<0>(t3));
77     BOOST_TEST(FUSION_AT<1>(t1) == FUSION_AT<1>(t3)[0]);
78 
79     BOOST_TEST(FUSION_AT<0>(t1) == 4);
80     BOOST_TEST(FUSION_AT<1>(t1) == 'a');
81 
82     // testing copy and assignment with implicit conversions
83     // between elements testing tie
84 
85     FUSION_SEQUENCE<char, BB*, BB, DD> t;
86     FUSION_SEQUENCE<int, AA*, CC, CC> a(t);
87     a = t;
88 
89     int i; char c; double d;
90     FUSION_TIE(i, c, d) = FUSION_MAKE(1, 'a', 5.5);
91 
92     BOOST_TEST(i==1);
93     BOOST_TEST(c=='a');
94     BOOST_TEST(d>5.4 && d<5.6);
95 
96     test_mpl();
97 
98 
99     BOOST_TEST((run< Scenario< FUSION_SEQUENCE<> > >(FUSION_SEQUENCE<>())));
100 
101     BOOST_TEST((
102         run< Scenario< FUSION_SEQUENCE<int> > >(FUSION_SEQUENCE<int>(500))
103     ));
104     BOOST_TEST((
105         run< Scenario< FUSION_SEQUENCE<convertible> > >(
106             FUSION_SEQUENCE<int>(500)
107         )
108     ));
109     BOOST_TEST((
110         run< Scenario< FUSION_SEQUENCE<int> > >(
111             FUSION_SEQUENCE<int, int>(500, 100)
112           , FUSION_SEQUENCE<int>(500)
113         )
114     ));
115     BOOST_TEST((
116         run< Scenario< FUSION_SEQUENCE<convertible> > >(
117             FUSION_SEQUENCE<int, int>(500, 100)
118           , FUSION_SEQUENCE<convertible>(500)
119         )
120     ));
121 
122     BOOST_TEST((
123         run< Scenario< FUSION_SEQUENCE<int, int> > >(
124             FUSION_SEQUENCE<int, int>(500, 600)
125         )
126     ));
127     BOOST_TEST((
128         run< Scenario< FUSION_SEQUENCE<convertible, int> > >(
129             FUSION_SEQUENCE<convertible, int>(100, 500)
130         )
131     ));
132     BOOST_TEST((
133         run< Scenario< FUSION_SEQUENCE<int, convertible> > >(
134             FUSION_SEQUENCE<int, convertible>(500, 600)
135         )
136     ));
137     BOOST_TEST((
138         run< Scenario< FUSION_SEQUENCE<convertible, convertible> > >(
139             FUSION_SEQUENCE<int, int>(400, 500)
140         )
141     ));
142     BOOST_TEST((
143         run< Scenario< FUSION_SEQUENCE<int, int> > >(
144             FUSION_SEQUENCE<int, int, int>(500, 100, 323)
145           , FUSION_SEQUENCE<int, int>(500, 100)
146         )
147     ));
148     BOOST_TEST((
149         run< Scenario< FUSION_SEQUENCE<convertible, convertible> > >(
150             FUSION_SEQUENCE<int, int, int>(500, 600, 100)
151           , FUSION_SEQUENCE<convertible, convertible>(500, 600)
152         )
153     ));
154 }
155