1 | //----------------------------------------------------------------------------- |
2 | // boost variant/visitor_ptr.hpp header file |
3 | // See http://www.boost.org for updates, documentation, and revision history. |
4 | //----------------------------------------------------------------------------- |
5 | // |
6 | // Copyright (c) 2002-2003 |
7 | // Eric Friedman |
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_VISITOR_PTR_HPP |
14 | #define BOOST_VARIANT_VISITOR_PTR_HPP |
15 | |
16 | #include "boost/variant/bad_visit.hpp" |
17 | #include "boost/variant/static_visitor.hpp" |
18 | |
19 | #include "boost/mpl/eval_if.hpp" |
20 | #include "boost/mpl/identity.hpp" |
21 | #include "boost/throw_exception.hpp" |
22 | #include "boost/type_traits/add_reference.hpp" |
23 | #include "boost/type_traits/is_reference.hpp" |
24 | #include "boost/type_traits/is_void.hpp" |
25 | |
26 | namespace boost { |
27 | |
28 | ////////////////////////////////////////////////////////////////////////// |
29 | // function template visitor_ptr |
30 | // |
31 | // Adapts a function pointer for use as visitor capable of handling |
32 | // values of a single type. Throws bad_visit if inappropriately applied. |
33 | // |
34 | template <typename T, typename R> |
35 | class visitor_ptr_t |
36 | : public static_visitor<R> |
37 | { |
38 | private: // representation |
39 | |
40 | typedef R (*visitor_t)(T); |
41 | |
42 | visitor_t visitor_; |
43 | |
44 | public: // typedefs |
45 | |
46 | typedef R result_type; |
47 | |
48 | private: // private typedefs |
49 | |
50 | typedef typename mpl::eval_if< |
51 | is_reference<T> |
52 | , mpl::identity<T> |
53 | , add_reference<const T> |
54 | >::type argument_fwd_type; |
55 | |
56 | public: // structors |
57 | |
58 | explicit visitor_ptr_t(visitor_t visitor) BOOST_NOEXCEPT |
59 | : visitor_(visitor) |
60 | { |
61 | } |
62 | |
63 | public: // static visitor interfaces |
64 | |
65 | template <typename U> |
66 | result_type operator()(const U&) const |
67 | { |
68 | boost::throw_exception(e: bad_visit()); |
69 | } |
70 | |
71 | #if !defined(BOOST_NO_VOID_RETURNS) |
72 | |
73 | public: // static visitor interfaces, cont. |
74 | |
75 | result_type operator()(argument_fwd_type operand) const |
76 | { |
77 | return visitor_(operand); |
78 | } |
79 | |
80 | #else // defined(BOOST_NO_VOID_RETURNS) |
81 | |
82 | private: // helpers, for static visitor interfaces (below) |
83 | |
84 | result_type execute_impl(argument_fwd_type operand, mpl::false_) const |
85 | { |
86 | return visitor_(operand); |
87 | } |
88 | |
89 | BOOST_VARIANT_AUX_RETURN_VOID_TYPE |
90 | execute_impl(argument_fwd_type operand, mpl::true_) const |
91 | { |
92 | visitor_(operand); |
93 | BOOST_VARIANT_AUX_RETURN_VOID; |
94 | } |
95 | |
96 | public: // static visitor interfaces, cont. |
97 | |
98 | BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) |
99 | operator()(argument_fwd_type operand) const |
100 | { |
101 | typedef typename is_void<result_type>::type has_void_result; |
102 | return execute_impl(operand, has_void_result()); |
103 | } |
104 | |
105 | #endif // BOOST_NO_VOID_RETURNS workaround |
106 | |
107 | }; |
108 | |
109 | template <typename R, typename T> |
110 | inline visitor_ptr_t<T,R> visitor_ptr(R (*visitor)(T)) |
111 | { |
112 | return visitor_ptr_t<T,R>(visitor); |
113 | } |
114 | |
115 | } // namespace boost |
116 | |
117 | #endif// BOOST_VISITOR_VISITOR_PTR_HPP |
118 | |