comparison DEPENDENCIES/generic/include/boost/variant/get.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 //-----------------------------------------------------------------------------
2 // boost variant/get.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2003
7 // Eric Friedman, Itay Maman
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_GET_HPP
14 #define BOOST_VARIANT_GET_HPP
15
16 #include <exception>
17
18 #include "boost/config.hpp"
19 #include "boost/detail/workaround.hpp"
20 #include "boost/throw_exception.hpp"
21 #include "boost/utility/addressof.hpp"
22 #include "boost/variant/variant_fwd.hpp"
23
24 #include "boost/type_traits/add_reference.hpp"
25 #include "boost/type_traits/add_pointer.hpp"
26
27 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
28 # include "boost/mpl/bool.hpp"
29 # include "boost/mpl/or.hpp"
30 # include "boost/type_traits/is_same.hpp"
31 #endif
32
33 namespace boost {
34
35 //////////////////////////////////////////////////////////////////////////
36 // class bad_get
37 //
38 // The exception thrown in the event of a failed get of a value.
39 //
40 class bad_get
41 : public std::exception
42 {
43 public: // std::exception implementation
44
45 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
46 {
47 return "boost::bad_get: "
48 "failed value get using boost::get";
49 }
50
51 };
52
53 //////////////////////////////////////////////////////////////////////////
54 // function template get<T>
55 //
56 // Retrieves content of given variant object if content is of type T.
57 // Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
58 //
59
60 namespace detail { namespace variant {
61
62 // (detail) class template get_visitor
63 //
64 // Generic static visitor that: if the value is of the specified type,
65 // returns a pointer to the value it visits; else a null pointer.
66 //
67 template <typename T>
68 struct get_visitor
69 {
70 private: // private typedefs
71
72 typedef typename add_pointer<T>::type pointer;
73 typedef typename add_reference<T>::type reference;
74
75 public: // visitor typedefs
76
77 typedef pointer result_type;
78
79 public: // visitor interfaces
80
81 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
82
83 pointer operator()(reference operand) const
84 {
85 return boost::addressof(operand);
86 }
87
88 template <typename U>
89 pointer operator()(const U&) const
90 {
91 return static_cast<pointer>(0);
92 }
93
94 #else // MSVC6
95
96 private: // helpers, for visitor interfaces (below)
97
98 pointer execute_impl(reference operand, mpl::true_) const
99 {
100 return boost::addressof(operand);
101 }
102
103 template <typename U>
104 pointer execute_impl(const U& operand, mpl::false_) const
105 {
106 return static_cast<pointer>(0);
107 }
108
109 public: // visitor interfaces
110
111 template <typename U>
112 pointer operator()(U& operand) const
113 {
114 // MSVC6 finds normal implementation (above) ambiguous,
115 // so we must explicitly disambiguate
116
117 typedef typename mpl::or_<
118 is_same<U, T>
119 , is_same<const U, T>
120 >::type U_is_T;
121
122 return execute_impl(operand, U_is_T());
123 }
124
125 #endif // MSVC6 workaround
126
127 };
128
129 }} // namespace detail::variant
130
131 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
132 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
133 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
134 #else
135 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
136 , t* = 0
137 #endif
138
139 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
140 inline
141 typename add_pointer<U>::type
142 get(
143 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
144 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
145 )
146 {
147 typedef typename add_pointer<U>::type U_ptr;
148 if (!operand) return static_cast<U_ptr>(0);
149
150 detail::variant::get_visitor<U> v;
151 return operand->apply_visitor(v);
152 }
153
154 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
155 inline
156 typename add_pointer<const U>::type
157 get(
158 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
159 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
160 )
161 {
162 typedef typename add_pointer<const U>::type U_ptr;
163 if (!operand) return static_cast<U_ptr>(0);
164
165 detail::variant::get_visitor<const U> v;
166 return operand->apply_visitor(v);
167 }
168
169 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
170 inline
171 typename add_reference<U>::type
172 get(
173 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
174 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
175 )
176 {
177 typedef typename add_pointer<U>::type U_ptr;
178 U_ptr result = get<U>(&operand);
179
180 if (!result)
181 boost::throw_exception(bad_get());
182 return *result;
183 }
184
185 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
186 inline
187 typename add_reference<const U>::type
188 get(
189 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
190 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
191 )
192 {
193 typedef typename add_pointer<const U>::type U_ptr;
194 U_ptr result = get<const U>(&operand);
195
196 if (!result)
197 boost::throw_exception(bad_get());
198 return *result;
199 }
200
201 } // namespace boost
202
203 #endif // BOOST_VARIANT_GET_HPP