summaryrefslogtreecommitdiff
path: root/libs/fusion/test/sequence/move.hpp
blob: febbc2bbaf3441215c76e5587f0bf624418bc810 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*=============================================================================
    Copyright (c) 2012 Joel de Guzman

    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/config.hpp>

#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#error "Valid only on compilers that support rvalues"
#endif

#include <boost/detail/lightweight_test.hpp>
#include <boost/static_assert.hpp>
#include <boost/assert.hpp>
#include <vector>


namespace test_detail
{
    int copies = 0;

    void incr_copy()
    {
        copies++;
    }

    struct x
    {
        int i;
        x() : i(123) {}

        x(x&& rhs) : i(rhs.i) {}

        x& operator=(x&& rhs)
        {
            i = rhs.i;
            return *this;
        }

        x(x const& rhs)
        {
            incr_copy();
        }

        x& operator=(x const& rhs)
        {
            incr_copy();
            return *this;
        }
    };

    typedef std::vector<x> vector_type;
    extern bool disable_rvo; // to disable RVO

    vector_type
    generate_vec()
    {
        vector_type v;
        v.push_back(x());
        if (disable_rvo)
            return v;
        return vector_type();
   }


    template <typename T>
    T move_me(T && val)
    {
        T r(std::move(val));
        if (disable_rvo)
            return r;
        return T();
    }

    typedef FUSION_SEQUENCE return_type;

    return_type
    generate()
    {
        return_type r(generate_vec());
        if (disable_rvo)
            return r;
        return return_type();
    }

    typedef FUSION_SEQUENCE2 return_type2;

    return_type2
    generate2()
    {
        return_type2 r(generate_vec(), x());
        if (disable_rvo)
            return r;
        return return_type2();
    }
}

void test()
{
    using namespace boost::fusion;
    using namespace test_detail;

    return_type v = move_me(generate());
    BOOST_TEST(copies == 0);

    return_type2 v2 = move_me(generate2());
    BOOST_TEST(copies == 0);

    v2 = move_me(generate2());
    BOOST_TEST(copies == 0);

    std::cout << "Copies: " << copies << std::endl;
}

namespace test_detail
{
   bool disable_rvo = true;
}