https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a version of type_of_ checking that the vtype is actually found.
* stc/vtypes.hh (stc::ERROR::NO_VALID_VIRTUAL_TYPE_FOUND),
(stc::ERROR::NO_VALID_RETURN_TYPE_FOR_type_of_): Remove.
(stc::ERROR::VIRTUAL_TYPE_NOT_FOUND): New.
(check_direct_type_of_, check_type_of_): New.
(stc_check_type_of, stc_check_type_of_)
(stc_check_direct_type_of, stc_check_direct_type_of_): New macros.
vtypes.hh | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 93 insertions(+), 5 deletions(-)
Index: stc/vtypes.hh
--- stc/vtypes.hh (revision 560)
+++ stc/vtypes.hh (working copy)
@@ -65,20 +65,31 @@
namespace ERROR
{
+ /// Errors from internal::get_super_types_helper.
+ /// \{
struct PARAMETER_OF_get_super_types_helper_IS_NOT_A_VALID_VALIST;
+ /// \}
+ /// Errors from internal rec_get_vtype.
+ /// \{
struct FIRST_PARAMETER_OF_rec_get_vtype_IS_NOT_A_TAG;
struct FIRST_PARAMETER_OF_rec_get_vtype_from_list_IS_NOT_A_TAG;
struct THIRD_PARAMETER_OF_rec_get_vtype_from_list_IS_NOT_A_LIST;
+ /// \}
+ /// Errors from internal::select_typedef.
+ /// \{
struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_SINGLE;
struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_EXTERNAL;
struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_SINGLE_AND_EXTERNAL;
struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_SINGLE_AND_EXTERNAL;
- struct NO_VALID_VIRTUAL_TYPE_FOUND;
+ /// \}
- struct NO_VALID_RETURN_TYPE_FOR_type_of_;
+ /// Errors from check_type_of_ and check_exact_type_of_.
+ /// \{
+ struct VIRTUAL_TYPE_NOT_FOUND;
+ /// \}
} // end of namespace stc::ERROR
@@ -771,6 +782,9 @@
} /** End of namespace internal. */ \
\
\
+ /* Entry points. */ \
+ /* ------------- */ \
+ \
/** Entry point of the vtype retrieval algorithm. */ \
template <typename category, typename from_type, typename typedef_type> \
struct direct_type_of_ \
@@ -820,6 +834,41 @@
direct_type_of_<category, from_exact_type, typedef_type>::ret ret; \
}; \
\
+ \
+ /** Like direct_type_of_, but ensure that the result is different */ \
+ /** from mlc::not_found. */ \
+ template <typename category, typename from_type, typename typedef_type> \
+ struct check_direct_type_of_ \
+ { \
+ /* Candidate type. */ \
+ typedef typename \
+ direct_type_of_<category, from_type, typedef_type>::ret candidate; \
+ /* Check that CANDIDATE is found. */ \
+ typedef typename \
+ mlc::assert_and_return_< \
+ mlc_neq(candidate, mlc::not_found), \
+ candidate, \
+ stc::ERROR::VIRTUAL_TYPE_NOT_FOUND \
+ >::ret ret; \
+ }; \
+ \
+ /** Like type_of_, but ensure that the result is different from */ \
+ /** mlc::not_found. */ \
+ template <typename category, typename from_type, typename typedef_type> \
+ struct check_type_of_ \
+ { \
+ /* Candidate type. */ \
+ typedef typename \
+ type_of_<category, from_type, typedef_type>::ret candidate; \
+ /* Check that CANDIDATE is found. */ \
+ typedef typename \
+ mlc::assert_and_return_< \
+ mlc_neq(candidate, mlc::not_found), \
+ candidate, \
+ stc::ERROR::VIRTUAL_TYPE_NOT_FOUND \
+ >::ret ret; \
+ }; \
+ \
struct e_n_d__w_i_t_h___s_e_m_i_c_o_l_o_n
@@ -933,9 +982,9 @@
set_pseudosuper_type< Type >::ret
-// ---------------------- //
-// Virtual types access. //
-// ---------------------- //
+// --------------------- //
+// Virtual type access. //
+// --------------------- //
/// Get the vtype \a Typedef, declared in \a Namespace, from the
/// exact type of \a FromType (version to be used inside a template).
@@ -961,6 +1010,45 @@
Namespace::typedef_:: Typedef##_type >::ret
+// ------------------------------- //
+// Virtual type check and access. //
+// ------------------------------- //
+
+/* These macros are the same as the previous ones, but they use
+ check_type_of_ (resp. check_direct_type_of_) instead of type_of_
+ (resp. direct_type_of_). */
+
+/// Get the vtype \a Typedef, declared in \a Namespace, from the
+/// exact type of \a FromType (version to be used inside a template).
+/// If the virtual type is not found, raise a static error.
+#define stc_check_type_of(Namespace, Category, FromType, Typedef) \
+ typename stc_check_type_of_(Namespace, Category, FromType, Typedef)
+
+/// Get the vtype \a Typedef, declared in \a Namespace, from the
+/// exact type of \a FromType (version to be used outside a template).
+/// If the virtual type is not found, raise a static error.
+#define stc_check_type_of_(Namespace, Category, FromType, Typedef) \
+ Namespace::check_type_of_< Category, FromType, \
+ Namespace::typedef_:: Typedef##_type >::ret
+
+
+/// Get the vtype \a Typedef, declared in \a Namespace, from \a
+/// FromType directly. (version to be used inside a template).
+/// If the virtual type is not found, raise a static error.
+#define stc_check_direct_type_of(Namespace, Category, FromType, Typedef) \
+ typename stc_check_direct_type_of_(Namespace, Category, FromType, Typedef)
+
+/// Get the vtype \a Typedef, declared in \a Namespace, from \a
+/// FromType directly (version to be used outside a template).
+/// If the virtual type is not found, raise a static error.
+#define stc_check_direct_type_of_(Namespace, Category, FromType, Typedef) \
+ Namespace::check_direct_type_of_< \
+ Category, \
+ FromType, \
+ Namespace::typedef_:: Typedef##_type \
+ >::ret
+
+
/// Declare the vtype \a Typedef in an abstract class (see sample code
/// for details). Warning: this macro assumes that the exact type