Skip to content

Commit f9c1c70

Browse files
committed
Reorder and hide functions in expr_cast
1 parent 800adbe commit f9c1c70

File tree

1 file changed

+60
-45
lines changed

1 file changed

+60
-45
lines changed

src/util/expr_cast.h

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,42 @@ template<typename T> bool can_cast_expr(const exprt &base);
3535
/// validate particular types.
3636
inline void validate_expr(const exprt &) {}
3737

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+
3874
/// \brief Try to cast a constant reference to a generic exprt to a specific
3975
/// derived class
4076
/// \tparam T The exprt-derived class to cast to
@@ -45,7 +81,7 @@ template<typename T>
4581
optionalt<std::reference_wrapper<typename std::remove_reference<T>::type>>
4682
expr_try_dynamic_cast(const exprt &base)
4783
{
48-
return expr_try_dynamic_cast<
84+
return detail::expr_try_dynamic_cast<
4985
T,
5086
typename std::remove_reference<T>::type,
5187
typename std::remove_const<typename std::remove_reference<T>::type>::type,
@@ -62,41 +98,50 @@ template<typename T>
6298
optionalt<std::reference_wrapper<typename std::remove_reference<T>::type>>
6399
expr_try_dynamic_cast(exprt &base)
64100
{
65-
return expr_try_dynamic_cast<
101+
return detail::expr_try_dynamic_cast<
66102
T,
67103
typename std::remove_reference<T>::type,
68104
typename std::remove_const<typename std::remove_reference<T>::type>::type,
69105
exprt>(base);
70106
}
71107

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
76116
/// \tparam TUnderlying An exprt-derived class type
77117
/// \tparam TExpr The original type to cast from, either exprt or const exprt
78118
/// \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)
83125
{
84126
static_assert(
85127
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");
87129
static_assert(
88130
std::is_reference<T>::value,
89131
"Tried to convert exprt & to non-reference type");
90132
static_assert(
91133
std::is_base_of<exprt, TUnderlying>::value,
92134
"The template argument T must be derived from exprt.");
135+
PRECONDITION(can_cast_expr<TUnderlying>(base));
93136
if(!can_cast_expr<TUnderlying>(base))
94-
return optionalt<std::reference_wrapper<TConst>>();
137+
throw std::bad_cast();
95138
T value=static_cast<T>(base);
96139
validate_expr(value);
97-
return optionalt<std::reference_wrapper<TConst>>(value);
140+
return value;
98141
}
99142

143+
} // namespace detail
144+
100145
/// \brief Cast a constant reference to a generic exprt to a specific derived
101146
/// class
102147
/// \tparam T The exprt-derived class to cast to
@@ -108,7 +153,7 @@ optionalt<std::reference_wrapper<TConst>> expr_try_dynamic_cast(TExpr &base)
108153
template<typename T>
109154
T expr_dynamic_cast(const exprt &base)
110155
{
111-
return expr_dynamic_cast<
156+
return detail::expr_dynamic_cast<
112157
T,
113158
typename std::remove_const<typename std::remove_reference<T>::type>::type,
114159
const exprt>(base);
@@ -124,42 +169,12 @@ T expr_dynamic_cast(const exprt &base)
124169
template<typename T>
125170
T expr_dynamic_cast(exprt &base)
126171
{
127-
return expr_dynamic_cast<
172+
return detail::expr_dynamic_cast<
128173
T,
129174
typename std::remove_const<typename std::remove_reference<T>::type>::type,
130175
exprt>(base);
131176
}
132177

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-
163178
inline void validate_operands(
164179
const exprt &value,
165180
exprt::operandst::size_type number,

0 commit comments

Comments
 (0)