summaryrefslogtreecommitdiff
path: root/boost/variant/detail/apply_visitor_delayed.hpp
blob: 29f46141d826ff17890bb4504640c95f339db0c5 (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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//-----------------------------------------------------------------------------
// boost variant/detail/apply_visitor_delayed.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2002-2003
// Eric Friedman
//
// 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)

#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP

#include "boost/variant/detail/generic_result_type.hpp"

#include "boost/variant/detail/apply_visitor_unary.hpp"
#include "boost/variant/detail/apply_visitor_binary.hpp"
#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES


#include "boost/variant/detail/has_result_type.hpp"
#include <boost/core/enable_if.hpp>

namespace boost {

//////////////////////////////////////////////////////////////////////////
// function template apply_visitor(visitor)
//
// Returns a function object, overloaded for unary and binary usage, that
// visits its arguments using visitor (or a copy of visitor) via
//  * apply_visitor( visitor, [argument] )
// under unary invocation, or
//  * apply_visitor( visitor, [argument1], [argument2] )
// under binary invocation.
//
// NOTE: Unlike other apply_visitor forms, the visitor object must be
//   non-const; this prevents user from giving temporary, to disastrous
//   effect (i.e., returned function object would have dead reference).
//

template <typename Visitor>
class apply_visitor_delayed_t
{
public: // visitor typedefs

    typedef typename Visitor::result_type
        result_type;

private: // representation

    Visitor& visitor_;

public: // structors

    explicit apply_visitor_delayed_t(Visitor& visitor) BOOST_NOEXCEPT
      : visitor_(visitor)
    {
    }

#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)

public: // N-ary visitor interface
    template <typename... Visitables>
        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
    operator()(Visitables&... visitables) const
    {
        return apply_visitor(visitor_, visitables...);
    }

#else // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)

public: // unary visitor interface

    template <typename Visitable>
        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
    operator()(Visitable& visitable) const
    {
        return apply_visitor(visitor_, visitable);
    }

public: // binary visitor interface

    template <typename Visitable1, typename Visitable2>
        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
    operator()(Visitable1& visitable1, Visitable2& visitable2) const
    {
        return apply_visitor(visitor_, visitable1, visitable2);
    }

#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)

private:
    apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);

};

template <typename Visitor>
inline typename boost::enable_if<
        boost::detail::variant::has_result_type<Visitor>,
        apply_visitor_delayed_t<Visitor>
    >::type apply_visitor(Visitor& visitor)
{
    return apply_visitor_delayed_t<Visitor>(visitor);
}

#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) \
    && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)

template <typename Visitor>
class apply_visitor_delayed_cpp14_t
{
private: // representation
    Visitor& visitor_;

public: // structors

    explicit apply_visitor_delayed_cpp14_t(Visitor& visitor) BOOST_NOEXCEPT
      : visitor_(visitor)
    {
    }

public: // N-ary visitor interface
    template <typename... Visitables>
    decltype(auto) operator()(Visitables&... visitables) const
    {
        return apply_visitor(visitor_, visitables...);
    }

private:
    apply_visitor_delayed_cpp14_t& operator=(const apply_visitor_delayed_cpp14_t&);

};

template <typename Visitor>
inline  typename boost::disable_if<
        boost::detail::variant::has_result_type<Visitor>,
        apply_visitor_delayed_cpp14_t<Visitor>
    >::type apply_visitor(Visitor& visitor)
{
    return apply_visitor_delayed_cpp14_t<Visitor>(visitor);
}

#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
            // && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)


} // namespace boost

#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP