// (C) Copyright Edward Diener 2011,2012,2013 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). #if !defined(BOOST_TTI_MEMBER_TYPE_HPP) #define BOOST_TTI_MEMBER_TYPE_HPP #include #include #include #include #include #include #include #include #include #include /* The succeeding comments in this file are in doxygen format. */ /** \file */ /// Expands to a metafunction whose typedef 'type' is either the named type or a marker type. /** trait = the name of the metafunction within the tti namespace. name = the name of the inner type. generates a metafunction called "trait" where 'trait' is the macro parameter. template struct trait { typedef unspecified type; typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; }; The metafunction types and return: BOOST_TTI_TP_T = the enclosing type. BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. defaults to the internal boost::tti::detail::notype. returns = 'type' is the inner type of 'name' if the inner type exists within the enclosing type, else 'type' is a marker type. if the end-user does not specify a marker type then an internal boost::tti::detail::notype marker type is used. The metafunction also encapsulates the type of the marker type as a nested 'boost_tti_marker_type'. The purpose of this macro is to encapsulate the 'name' type as the typedef 'type' of a metafunction, but only if it exists within the enclosing type. This allows for an evaluation of inner type existence, without generating a compiler error, which can be used by other metafunctions in this library. */ #define BOOST_TTI_TRAIT_MEMBER_TYPE(trait,name) \ BOOST_TTI_DETAIL_TRAIT_HAS_TYPE_MEMBER_TYPE(trait,name) \ BOOST_TTI_DETAIL_TRAIT_MEMBER_TYPE(trait,name) \ template \ struct trait : \ boost::mpl::eval_if \ < \ BOOST_PP_CAT(trait,_detail), \ BOOST_PP_CAT(trait,_detail_member_type), \ boost::mpl::identity \ > \ { \ typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; \ }; \ /**/ /// Expands to a metafunction whose typedef 'type' is either the named type or a marker type. /** name = the name of the inner type. generates a metafunction called "member_type_name" where 'name' is the macro parameter. template struct member_type_name { typedef unspecified type; typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; }; The metafunction types and return: BOOST_TTI_TP_T = the enclosing type. BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. defaults to the internal boost::tti::detail::notype. returns = 'type' is the inner type of 'name' if the inner type exists within the enclosing type, else 'type' is a marker type. if the end-user does not specify a marker type then an internal boost::tti::detail::notype marker type is used. The metafunction also encapsulates the type of the marker type as a nested 'boost_tti_marker_type'. The purpose of this macro is to encapsulate the 'name' type as the typedef 'type' of a metafunction, but only if it exists within the enclosing type. This allows for an evaluation of inner type existence, without generating a compiler error, which can be used by other metafunctions in this library. */ #define BOOST_TTI_MEMBER_TYPE(name) \ BOOST_TTI_TRAIT_MEMBER_TYPE \ ( \ BOOST_TTI_MEMBER_TYPE_GEN(name), \ name \ ) \ /**/ namespace boost { namespace tti { /// A metafunction which checks whether the member 'type' returned from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ) is a valid type. /** template struct valid_member_type { static const value = unspecified; typedef mpl::bool_ type; }; The metafunction types and return: BOOST_TTI_TP_T = returned inner 'type' from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ). BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. defaults to the internal boost::tti::detail::notype. returns = 'value' is true if the type is valid, otherwise 'value' is false. A valid type means that the returned inner 'type' is not the marker type. */ template struct valid_member_type : boost::mpl::not_ < boost::is_same > { }; /// A metafunction which checks whether the invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ) hold a valid type. /** template struct valid_member_metafunction { static const value = unspecified; typedef mpl::bool_ type; }; The metafunction types and return: TTI_METAFUNCTION = The invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ). returns = 'value' is true if the nested type of the invoked metafunction is valid, otherwise 'value' is false. A valid type means that the invoked metafunction's inner 'type' is not the marker type. */ template struct valid_member_metafunction : boost::mpl::not_ < boost::is_same > { }; } } #endif // BOOST_TTI_MEMBER_TYPE_HPP