]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/variant/detail/apply_visitor_unary.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / variant / detail / apply_visitor_unary.hpp
CommitLineData
7c673cae
FG
1//-----------------------------------------------------------------------------
2// boost variant/detail/apply_visitor_unary.hpp header file
3// See http://www.boost.org for updates, documentation, and revision history.
4//-----------------------------------------------------------------------------
5//
6// Copyright (c) 2002-2003 Eric Friedman
92f5a8d4 7// Copyright (c) 2014-2019 Antony Polukhin
7c673cae
FG
8//
9// Distributed under the Boost Software License, Version 1.0. (See
10// accompanying file LICENSE_1_0.txt or copy at
11// http://www.boost.org/LICENSE_1_0.txt)
12
13#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
14#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
15
16#include <boost/config.hpp>
b32b8144 17#include <boost/move/utility.hpp>
7c673cae 18
7c673cae
FG
19#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
20# include <boost/mpl/distance.hpp>
21# include <boost/mpl/advance.hpp>
22# include <boost/mpl/deref.hpp>
23# include <boost/mpl/size.hpp>
24# include <boost/utility/declval.hpp>
25# include <boost/core/enable_if.hpp>
92f5a8d4
TL
26# include <boost/type_traits/copy_cv_ref.hpp>
27# include <boost/type_traits/remove_reference.hpp>
7c673cae
FG
28# include <boost/variant/detail/has_result_type.hpp>
29#endif
30
31namespace boost {
32
33//////////////////////////////////////////////////////////////////////////
34// function template apply_visitor(visitor, visitable)
35//
36// Visits visitable with visitor.
37//
38
39//
40// nonconst-visitor version:
41//
42
b32b8144
FG
43#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
44template <typename Visitor, typename Visitable>
92f5a8d4 45inline typename Visitor::result_type
b32b8144
FG
46apply_visitor(Visitor& visitor, Visitable&& visitable)
47{
48 return ::boost::forward<Visitable>(visitable).apply_visitor(visitor);
49}
50#else
7c673cae 51template <typename Visitor, typename Visitable>
92f5a8d4 52inline typename Visitor::result_type
7c673cae
FG
53apply_visitor(Visitor& visitor, Visitable& visitable)
54{
55 return visitable.apply_visitor(visitor);
56}
b32b8144 57#endif
7c673cae 58
7c673cae
FG
59//
60// const-visitor version:
61//
62
b32b8144
FG
63#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
64template <typename Visitor, typename Visitable>
92f5a8d4 65inline typename Visitor::result_type
b32b8144
FG
66apply_visitor(const Visitor& visitor, Visitable&& visitable)
67{
68 return ::boost::forward<Visitable>(visitable).apply_visitor(visitor);
69}
70#else
7c673cae 71template <typename Visitor, typename Visitable>
92f5a8d4 72inline typename Visitor::result_type
7c673cae
FG
73apply_visitor(const Visitor& visitor, Visitable& visitable)
74{
75 return visitable.apply_visitor(visitor);
76}
b32b8144 77#endif
7c673cae
FG
78
79
80#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
92f5a8d4 81#define BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
7c673cae
FG
82
83// C++14
84namespace detail { namespace variant {
85
86// This class serves only metaprogramming purposes. none of its methods must be called at runtime!
87template <class Visitor, class Variant>
88struct result_multideduce1 {
92f5a8d4 89 typedef typename remove_reference<Variant>::type::types types;
7c673cae
FG
90 typedef typename boost::mpl::begin<types>::type begin_it;
91 typedef typename boost::mpl::advance<
92 begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1>
93 >::type last_it;
94
92f5a8d4
TL
95 template <class It, class Dummy = void> // avoid explicit specialization in class scope
96 struct deduce_impl {
7c673cae
FG
97 typedef typename boost::mpl::next<It>::type next_t;
98 typedef typename boost::mpl::deref<It>::type value_t;
92f5a8d4
TL
99 typedef decltype(true ? boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )
100 : boost::declval< typename deduce_impl<next_t>::type >()) type;
101 };
7c673cae 102
92f5a8d4
TL
103 template <class Dummy>
104 struct deduce_impl<last_it, Dummy> {
105 typedef typename boost::mpl::deref<last_it>::type value_t;
106 typedef decltype(boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )) type;
107 };
7c673cae 108
92f5a8d4 109 typedef typename deduce_impl<begin_it>::type type;
7c673cae
FG
110};
111
112template <class Visitor, class Variant>
113struct result_wrapper1
114{
92f5a8d4 115 typedef typename result_multideduce1<Visitor, Variant>::type result_type;
7c673cae 116
11fdf7f2
TL
117 Visitor&& visitor_;
118 explicit result_wrapper1(Visitor&& visitor) BOOST_NOEXCEPT
119 : visitor_(::boost::forward<Visitor>(visitor))
7c673cae
FG
120 {}
121
122 template <class T>
b32b8144
FG
123 result_type operator()(T&& val) const {
124 return visitor_(::boost::forward<T>(val));
7c673cae
FG
125 }
126};
127
128}} // namespace detail::variant
129
130template <typename Visitor, typename Visitable>
11fdf7f2 131inline decltype(auto) apply_visitor(Visitor&& visitor, Visitable&& visitable,
7c673cae
FG
132 typename boost::disable_if<
133 boost::detail::variant::has_result_type<Visitor>
134 >::type* = 0)
135{
92f5a8d4 136 boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(::boost::forward<Visitor>(visitor));
b32b8144 137 return ::boost::forward<Visitable>(visitable).apply_visitor(cpp14_vis);
7c673cae
FG
138}
139
7c673cae
FG
140#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
141
142} // namespace boost
143
144#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP