]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/variant/detail/apply_visitor_unary.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / variant / detail / apply_visitor_unary.hpp
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
7 // Copyright (c) 2014-2019 Antony Polukhin
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>
17 #include <boost/move/utility.hpp>
18
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>
26 #   include <boost/type_traits/copy_cv_ref.hpp>
27 #   include <boost/type_traits/remove_reference.hpp>
28 #   include <boost/variant/detail/has_result_type.hpp>
29 #endif
30
31 namespace 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
43 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
44 template <typename Visitor, typename Visitable>
45 inline typename Visitor::result_type
46 apply_visitor(Visitor& visitor, Visitable&& visitable)
47 {
48     return ::boost::forward<Visitable>(visitable).apply_visitor(visitor);
49 }
50 #else
51 template <typename Visitor, typename Visitable>
52 inline typename Visitor::result_type
53 apply_visitor(Visitor& visitor, Visitable& visitable)
54 {
55     return visitable.apply_visitor(visitor);
56 }
57 #endif
58
59 //
60 // const-visitor version:
61 //
62
63 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
64 template <typename Visitor, typename Visitable>
65 inline typename Visitor::result_type
66 apply_visitor(const Visitor& visitor, Visitable&& visitable)
67 {
68     return ::boost::forward<Visitable>(visitable).apply_visitor(visitor);
69 }
70 #else
71 template <typename Visitor, typename Visitable>
72 inline typename Visitor::result_type
73 apply_visitor(const Visitor& visitor, Visitable& visitable)
74 {
75     return visitable.apply_visitor(visitor);
76 }
77 #endif
78
79
80 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
81 #define BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
82
83 // C++14
84 namespace detail { namespace variant {
85
86 // This class serves only metaprogramming purposes. none of its methods must be called at runtime!
87 template <class Visitor, class Variant>
88 struct result_multideduce1 {
89     typedef typename remove_reference<Variant>::type::types types;
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
95     template <class It, class Dummy = void> // avoid explicit specialization in class scope
96     struct deduce_impl {
97         typedef typename boost::mpl::next<It>::type next_t;
98         typedef typename boost::mpl::deref<It>::type value_t;
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     };
102
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     };
108
109     typedef typename deduce_impl<begin_it>::type type;
110 };
111
112 template <class Visitor, class Variant>
113 struct result_wrapper1
114 {
115     typedef typename result_multideduce1<Visitor, Variant>::type result_type;
116
117     Visitor&& visitor_;
118     explicit result_wrapper1(Visitor&& visitor) BOOST_NOEXCEPT
119         : visitor_(::boost::forward<Visitor>(visitor))
120     {}
121
122     template <class T>
123     result_type operator()(T&& val) const {
124         return visitor_(::boost::forward<T>(val));
125     }
126 };
127
128 }} // namespace detail::variant
129
130 template <typename Visitor, typename Visitable>
131 inline decltype(auto) apply_visitor(Visitor&& visitor, Visitable&& visitable,
132     typename boost::disable_if<
133         boost::detail::variant::has_result_type<Visitor>
134     >::type* = 0)
135 {
136     boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(::boost::forward<Visitor>(visitor));
137     return ::boost::forward<Visitable>(visitable).apply_visitor(cpp14_vis);
138 }
139
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