@@ -35,6 +35,42 @@ template<typename T> bool can_cast_expr(const exprt &base);
35
35
// / validate particular types.
36
36
inline void validate_expr (const exprt &) {}
37
37
38
+ namespace detail
39
+ {
40
+
41
+ // We hide this in a namespace so that only functions that it only
42
+ // participates in overload resolution when explicitly requested.
43
+
44
+ // / \brief Try to cast a reference to a generic exprt to a specific derived
45
+ // / class
46
+ // / \tparam T The reference or const reference type to \a TUnderlying to cast
47
+ // / to
48
+ // / \tparam TUnderlying An exprt-derived class type
49
+ // / \tparam TExpr The original type to cast from, either exprt or const exprt
50
+ // / \param base Reference to a generic \ref exprt
51
+ // / \return Reference to object of type \a TUnderlying
52
+ // / or valueless optional if \a base is not an instance of \a TUnderlying
53
+ template <typename T, typename TConst, typename TUnderlying, typename TExpr>
54
+ optionalt<std::reference_wrapper<TConst>> expr_try_dynamic_cast (TExpr &base)
55
+ {
56
+ static_assert (
57
+ std::is_same<typename std::remove_const<TExpr>::type, exprt>::value,
58
+ " Tried to expr_try_dynamic_cast from something that wasn't an exprt" );
59
+ static_assert (
60
+ std::is_reference<T>::value,
61
+ " Tried to convert exprt & to non-reference type" );
62
+ static_assert (
63
+ std::is_base_of<exprt, TUnderlying>::value,
64
+ " The template argument T must be derived from exprt." );
65
+ if (!can_cast_expr<TUnderlying>(base))
66
+ return optionalt<std::reference_wrapper<TConst>>();
67
+ T value=static_cast <T>(base);
68
+ validate_expr (value);
69
+ return optionalt<std::reference_wrapper<TConst>>(value);
70
+ }
71
+
72
+ } // namespace detail
73
+
38
74
// / \brief Try to cast a constant reference to a generic exprt to a specific
39
75
// / derived class
40
76
// / \tparam T The exprt-derived class to cast to
@@ -45,7 +81,7 @@ template<typename T>
45
81
optionalt<std::reference_wrapper<typename std::remove_reference<T>::type>>
46
82
expr_try_dynamic_cast (const exprt &base)
47
83
{
48
- return expr_try_dynamic_cast<
84
+ return detail:: expr_try_dynamic_cast<
49
85
T,
50
86
typename std::remove_reference<T>::type,
51
87
typename std::remove_const<typename std::remove_reference<T>::type>::type,
@@ -62,41 +98,50 @@ template<typename T>
62
98
optionalt<std::reference_wrapper<typename std::remove_reference<T>::type>>
63
99
expr_try_dynamic_cast (exprt &base)
64
100
{
65
- return expr_try_dynamic_cast<
101
+ return detail:: expr_try_dynamic_cast<
66
102
T,
67
103
typename std::remove_reference<T>::type,
68
104
typename std::remove_const<typename std::remove_reference<T>::type>::type,
69
105
exprt>(base);
70
106
}
71
107
72
- // / \brief Try to cast a reference to a generic exprt to a specific derived
73
- // / class
74
- // / \tparam T The reference or const reference type to \a TUnderlying to cast
75
- // / to
108
+ namespace detail
109
+ {
110
+
111
+ // We hide this in a namespace so that only functions that it only
112
+ // participates in overload resolution when explicitly requested.
113
+
114
+ // / \brief Cast a reference to a generic exprt to a specific derived class
115
+ // / \tparam T The reference or const reference type to \a TUnderlying to cast to
76
116
// / \tparam TUnderlying An exprt-derived class type
77
117
// / \tparam TExpr The original type to cast from, either exprt or const exprt
78
118
// / \param base Reference to a generic \ref exprt
79
- // / \return Reference to object of type \a TUnderlying
80
- // / or valueless optional if \a base is not an instance of \a TUnderlying
81
- template <typename T, typename TConst, typename TUnderlying, typename TExpr>
82
- optionalt<std::reference_wrapper<TConst>> expr_try_dynamic_cast (TExpr &base)
119
+ // / \return Reference to object of type \a T
120
+ // / \throw std::bad_cast If \a base is not an instance of \a TUnderlying
121
+ // / \remark If CBMC assertions (PRECONDITION) are set to abort then this will
122
+ // / abort rather than throw if \a base is not an instance of \a TUnderlying
123
+ template <typename T, typename TUnderlying, typename TExpr>
124
+ T expr_dynamic_cast (TExpr &base)
83
125
{
84
126
static_assert (
85
127
std::is_same<typename std::remove_const<TExpr>::type, exprt>::value,
86
- " Tried to expr_try_dynamic_cast from something that wasn't an exprt" );
128
+ " Tried to expr_dynamic_cast from something that wasn't an exprt" );
87
129
static_assert (
88
130
std::is_reference<T>::value,
89
131
" Tried to convert exprt & to non-reference type" );
90
132
static_assert (
91
133
std::is_base_of<exprt, TUnderlying>::value,
92
134
" The template argument T must be derived from exprt." );
135
+ PRECONDITION (can_cast_expr<TUnderlying>(base));
93
136
if (!can_cast_expr<TUnderlying>(base))
94
- return optionalt< std::reference_wrapper<TConst>> ();
137
+ throw std::bad_cast ();
95
138
T value=static_cast <T>(base);
96
139
validate_expr (value);
97
- return optionalt<std::reference_wrapper<TConst>>( value) ;
140
+ return value;
98
141
}
99
142
143
+ } // namespace detail
144
+
100
145
// / \brief Cast a constant reference to a generic exprt to a specific derived
101
146
// / class
102
147
// / \tparam T The exprt-derived class to cast to
@@ -108,7 +153,7 @@ optionalt<std::reference_wrapper<TConst>> expr_try_dynamic_cast(TExpr &base)
108
153
template <typename T>
109
154
T expr_dynamic_cast (const exprt &base)
110
155
{
111
- return expr_dynamic_cast<
156
+ return detail:: expr_dynamic_cast<
112
157
T,
113
158
typename std::remove_const<typename std::remove_reference<T>::type>::type,
114
159
const exprt>(base);
@@ -124,42 +169,12 @@ T expr_dynamic_cast(const exprt &base)
124
169
template <typename T>
125
170
T expr_dynamic_cast (exprt &base)
126
171
{
127
- return expr_dynamic_cast<
172
+ return detail:: expr_dynamic_cast<
128
173
T,
129
174
typename std::remove_const<typename std::remove_reference<T>::type>::type,
130
175
exprt>(base);
131
176
}
132
177
133
- // / \brief Cast a reference to a generic exprt to a specific derived class
134
- // / \tparam T The reference or const reference type to \a TUnderlying to cast to
135
- // / \tparam TUnderlying An exprt-derived class type
136
- // / \tparam TExpr The original type to cast from, either exprt or const exprt
137
- // / \param base Reference to a generic \ref exprt
138
- // / \return Reference to object of type \a T
139
- // / \throw std::bad_cast If \a base is not an instance of \a TUnderlying
140
- // / \remark If CBMC assertions (PRECONDITION) are set to abort then this will
141
- // / abort rather than throw if \a base is not an instance of \a TUnderlying
142
- template <typename T, typename TUnderlying, typename TExpr>
143
- T expr_dynamic_cast (TExpr &base)
144
- {
145
- static_assert (
146
- std::is_same<typename std::remove_const<TExpr>::type, exprt>::value,
147
- " Tried to expr_dynamic_cast from something that wasn't an exprt" );
148
- static_assert (
149
- std::is_reference<T>::value,
150
- " Tried to convert exprt & to non-reference type" );
151
- static_assert (
152
- std::is_base_of<exprt, TUnderlying>::value,
153
- " The template argument T must be derived from exprt." );
154
- PRECONDITION (can_cast_expr<TUnderlying>(base));
155
- if (!can_cast_expr<TUnderlying>(base))
156
- throw std::bad_cast ();
157
- T value=static_cast <T>(base);
158
- validate_expr (value);
159
- return value;
160
- }
161
-
162
-
163
178
inline void validate_operands (
164
179
const exprt &value,
165
180
exprt::operandst::size_type number,
0 commit comments