Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83643 - in trunk: boost/tti libs/tti/doc libs/tti/test
From: eldiener_at_[hidden]
Date: 2013-03-30 03:39:21


Author: eldiener
Date: 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
New Revision: 83643
URL: http://svn.boost.org/trac/boost/changeset/83643

Log:
Updated member type to support marker type parameter and valid_member_metafunction metafunction.
Text files modified:
   trunk/boost/tti/has_static_member_data.hpp | 2
   trunk/boost/tti/member_type.hpp | 79 +++++++++--
   trunk/boost/tti/tti.hpp | 2
   trunk/libs/tti/doc/tti_nested_type.qbk | 259 +++++++++++++++++++++++++--------------
   trunk/libs/tti/test/test_mem_type.cpp | 20 +-
   trunk/libs/tti/test/test_mem_type.hpp | 2
   trunk/libs/tti/test/test_mem_type_compile.cpp | 8
   7 files changed, 252 insertions(+), 120 deletions(-)

Modified: trunk/boost/tti/has_static_member_data.hpp
==============================================================================
--- trunk/boost/tti/has_static_member_data.hpp (original)
+++ trunk/boost/tti/has_static_member_data.hpp 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
@@ -58,7 +58,7 @@
 
     name = the name of the inner member.
 
- generates a metafunction called "has_static_member_name" where 'name' is the macro parameter.
+ generates a metafunction called "has_static_member_data_name" where 'name' is the macro parameter.
     
               The metafunction types and return:
     

Modified: trunk/boost/tti/member_type.hpp
==============================================================================
--- trunk/boost/tti/member_type.hpp (original)
+++ trunk/boost/tti/member_type.hpp 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
@@ -1,5 +1,5 @@
 
-// (C) Copyright Edward Diener 2011,2012
+// (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).
@@ -27,7 +27,7 @@
 /** \file
 */
 
-/// Expands to a metafunction whose typedef 'type' is either the named type or an unspecified marker type.
+/// 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.
@@ -36,18 +36,27 @@
 
     generates a metafunction called "trait" where 'trait' is the macro parameter.
     
- template<class TTI_T>
+ template<class TTI_T,class TTI_MARKER_TYPE = boost::tti::detail::notype>
               struct trait
                 {
                 typedef unspecified type;
+
+ typedef TTI_MARKER_TYPE boost_tti_marker_type;
                 };
 
               The metafunction types and return:
               
- TTI_T = the enclosing type.
+ TTI_T = the enclosing type.
+ TTI_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 an unspecified marker type.
+ 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
@@ -67,32 +76,42 @@
         boost::mpl::identity<TTI_MARKER_TYPE> \
> \
       { \
+ typedef TTI_MARKER_TYPE boost_tti_marker_type; \
       }; \
 /**/
 
-/// Expands to a metafunction whose typedef 'type' is either the named type or an unspecified 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<class TTI_T>
+ template<class TTI_T,class TTI_MARKER_TYPE = boost::tti::detail::notype>
               struct member_type_name
                 {
                 typedef unspecified type;
+
+ typedef TTI_MARKER_TYPE boost_tti_marker_type;
                 };
 
               The metafunction types and return:
               
- TTI_T = the enclosing type.
+ TTI_T = the enclosing type.
+ TTI_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 an unspecified marker type.
+ 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 genrating a compiler error,
+ an evaluation of inner type existence, without generating a compiler error,
     which can be used by other metafunctions in this library.
     
 */
@@ -112,7 +131,7 @@
     /// 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<class TTI_T>
+ template<class TTI_T,class TTI_MARKER_TYPE = boost::tti::detail::notype>
         struct valid_member_type
           {
           static const value = unspecified;
@@ -121,9 +140,12 @@
 
         The metafunction types and return:
 
- TTI_T = returned inner 'type' from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ).
+ TTI_T = returned inner 'type' from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ).
+ TTI_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.
+ 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<class TTI_T,class TTI_MARKER_TYPE = BOOST_TTI_NAMESPACE::detail::notype>
@@ -134,6 +156,33 @@
>
       {
       };
+
+ /// 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<class TTI_METAFUNCTION>
+ struct valid_member_metafunction
+ {
+ static const value = unspecified;
+ typedef mpl::bool_<true-or-false> 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<class TTI_METAFUNCTION>
+ struct valid_member_metafunction :
+ boost::mpl::not_
+ <
+ boost::is_same<typename TTI_METAFUNCTION::type,typename TTI_METAFUNCTION::boost_tti_marker_type>
+ >
+ {
+ };
     }
   }
   

Modified: trunk/boost/tti/tti.hpp
==============================================================================
--- trunk/boost/tti/tti.hpp (original)
+++ trunk/boost/tti/tti.hpp 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
@@ -7,6 +7,8 @@
 #if !defined(BOOST_TTI_INTROSPECTION_HPP)
 #define BOOST_TTI_INTROSPECTION_HPP
 
+#include "has_data.hpp"
+#include "has_function.hpp"
 #include "has_member_data.hpp"
 #include "has_member_function.hpp"
 #include "has_static_member_data.hpp"

Modified: trunk/libs/tti/doc/tti_nested_type.qbk
==============================================================================
--- trunk/libs/tti/doc/tti_nested_type.qbk (original)
+++ trunk/libs/tti/doc/tti_nested_type.qbk 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
@@ -7,16 +7,78 @@
 
 [section:tti_nested_type Nested Types]
 
-[heading The problem]
+Besides the functionality of the TTI library which queries whether some inner element
+of a given name within a type exists, the library also includes functionality for
+generating a nested type if it exists, else a marker type if it does not exist. By
+marker type is meant a type either internally created by the library, with no functionality,
+or designated by the end-user to represent the same idea.
+
+First I will explain the syntax and use of this functionality and then the reason it exists in
+the library.
+
+The functionality is a metafunction created by the macro [macroref BOOST_TTI_MEMBER_TYPE].
+The macro takes a single parameter, which is the name of a nested type. We will call this our
+'named type'. The macro generates a metafunction called `member_type_'named_type'` which, passed
+an enclosing type, returns the named type if it exists, else a marker type if it does not.
+
+As with our other macros we can use the alternative form of the macro
+[macroref BOOST_TTI_TRAIT_MEMBER_TYPE] to pass first the name of the metafunction
+to be generated and then the name of the 'named type'. After that the functionality
+of our resulting metafunction is exactly the same.
 
-One of the goals of the TTI library is never to produce a compiler error by just
-using the functionality in the library, whether it is invoking its function-like macros
-or instantiating the macro metafunctions created by them, and whether the inner element exists
-or not. In this sense The TTI library macros for introspecting an enclosing type for
-an inner element work well. But there is one exception to this general case.
-That exception is the crux of the discussion regarding nested types which follows.
+Its general explanation is given as:
 
-The metafunctions generated by the TTI macros all work with types, whether in specifying
+[table:tbmacronested TTI Nested Type Macro Metafunction
+ [
+ [Inner Element]
+ [Macro]
+ [Template]
+ [Specific Header File]
+ ]
+ [
+ [Type]
+ [
+ [macroref BOOST_TTI_MEMBER_TYPE](name)
+ ]
+ [
+ `member_type_'name'`
+
+ class T = enclosing type
+ class U = (optional) marker type
+
+ returns = the type of 'name' if it exists, else a marker type, as the typedef 'type'.
+
+ The invoked metafunction also holds the marker type as the typedef 'boost_tti_marker_type'.
+ This is done for convenience so that the marker type does not have to be remembered.
+ ]
+ [[headerref boost/tti/member_type.hpp `member_type.hpp`]]
+ ]
+]
+
+The marker type is purely optional. If not specified a type internal to the TTI library,
+which has no functionality, is used. Unless there is a specific reason for the end-user
+to provide his own marker type, he should let the TTI library use its own internal
+marker type.
+
+A simple example of this functionality would be:
+
+ #include <boost/tti/member_type.hpp>
+
+ BOOST_TTI_MEMBER_TYPE(ANamedType)
+
+ typedef typename member_type_ANamedType<EnclosingType>::type AType;
+
+If type 'ANamedType' is a nested type of 'EnclosingType' then
+AType is the same type as 'ANamedType', otherwise AType is a
+marker type internal to the TTI library.
+
+Now that we have explained the syntax of BOOST_TTI_MEMBER_TYPE
+we can now answer the question of why this functionality to create
+a 'type' exists when looking for a nested type of an enclosing type.
+
+[heading The problem]
+
+The metafunctions generated by the TTI macros all work with various types, whether in specifying
 an enclosing type or in specifying the type of some inner element, which may also involve
 types in the signature of that element, such as a parameter or return type of a function.
 The C++ notation for a nested type, given an enclosing type 'T' and an inner type 'InnerType',
@@ -47,19 +109,37 @@
 
 [heading The solution]
 
-The TTI library offers a solution in the form of a construct which works with a
-nested type without producing a compiler error if the nested type does not exist, while still
-allowing us to introspect inner elements using such a potentially non-existing nested type.
-
-This is a metafunction created by the macro [macroref BOOST_TTI_MEMBER_TYPE]. The macro takes
-a single parameter, which is the name of a type. We will call this our 'named type'.
-The macro generates a metafunction called `member_type_'named_type'` which, passed an enclosing type,
-returns the named type if it exists, else an unspecified marker type internal to the TTI library
-if it does not.
+The solution given by BOOST_TTI_MEMBER_TYPE is that we can create a type as the return
+from our metafunction, which is the same type as a nested type if it exists or some other
+marker type if it does not, and then work with that returned type without producing a
+compiler error. If we had to use the 'T::InnerType' syntax to specify our type, where 'T' represents
+out enclosing type and 'InnerType' our nested type, and there was no nested type 'InnerType' within the
+enclosing type 'T, the compiler would give us an error immediately.
+
+By using BOOST_TTI_MEMBER_TYPE we have a type to work with even when such a type
+really does not exist. Naturally if the type does not exist, the type which we
+have to work with, being a marker type, will generally not fulfill any other further functionality
+we want from it. This is good and will normally produce the correct results in further uses of the type
+when doing metafunction programming. Occasionally the TTI produced marker type, when our nested
+type does not exist, is not sufficient for further metafunction programming. In that rare case the
+end-user can produce his own marker type to be used if the nested type does not exist. In any case,
+whether the nested type exists, whether the TTI default supplied marker type is used, or whether
+an end-user marker type is used, template metaprogramming can continue without a compilation
+problem. Furthermore this scales better than having to constant check for nested type existence
+via BOOST_TTI_HAS_TYPE in complicated template metaprogramming code.
+
+[heading Checking if the member type exists]
+
+Once we use BOOST_TTI_MEMBER_TYPE to generate a nested type if it exists we will normally
+use that type in further metafunction programming. Occasionally, given the type we generate,
+we will want to ask if the type is really our nested type or the marker type instead. Essentially
+we are asking if the type generated is the marker type or not. If it is the marker type, then
+the type generated is not the nested type we had hoped for. If it is not the marker type, then
+the type generated is the nested type we had hoped for. This is easy enough to do for the template
+metaprogrammer but TTI makes it easier by providing either of two metafunctions to do this calculation.
+These two metafunctions are 'boost::tti::valid_member_type' and 'boost::tti::valid_member_metafunction':
 
-Its general explanation is given as:
-
-[table:tbmacronested TTI Nested Type Macro Metafunction
+[table:existtbmacronested TTI Nested Type Macro Metafunction Existence
   [
     [Inner Element]
     [Macro]
@@ -68,46 +148,79 @@
   ]
   [
     [Type]
+ [None]
     [
- [macroref BOOST_TTI_MEMBER_TYPE](name)
+ [classref boost::tti::valid_member_type]
+
+ class T = a type
+ class U = (optional) marker type
+
+ returns = true if the type exists, false if it does not.
+ 'Existence' is determined by whether the type
+ does not equal the marker type of BOOST_TTI_MEMBER_TYPE.
     ]
+ [[headerref boost/tti/member_type.hpp `member_type.hpp`]]
+ ]
+ [
+ [Type]
+ [None]
     [
- `member_type_'name'`
+ [classref boost::tti::valid_member_metafunction]
     
- class T = enclosing type
+ class T = a metafunction type
     
- returns = the type of 'name' if it exists, else an unspecified type, as the typedef 'type'.
+ returns = true if the return 'type' of the meatfunction exists,
+ false if it does not.'Existence' is determined by whether
+ the return 'type' does not equal the marker type of
+ BOOST_TTI_MEMBER_TYPE.
     ]
     [[headerref boost/tti/member_type.hpp `member_type.hpp`]]
   ]
 ]
 
-A simple example:
+In our first metafunction, 'boost::tti::valid_member_type', the first
+parameter is the return 'type' from invoking the metafunction generated
+by BOOST_TTI_MEMBER_TYPE. If when the metafunction was invoked a user-defined
+marker type had been specified, then the second optional parameter is that
+marker type, else it is not necessary to specify the optional second template
+parameter. Since the marker type is saved as the nested type
+boost::tti::marker_type once we invoke the metafunction generated by
+BOOST_TTI_MEMBER_TYPE we can always use that as our second template parameter
+to 'boost::tti::valid_member_type' if we like.
+
+The second metafunction, boost::tti::valid_member_metafunction, makes the
+process of passing our nested 'type' and our marker type a bit easier. Here
+the single template parameter is the invoked metafunction generated by
+BOOST_TTI_MEMBER_TYPE itself. It then picks out from the invoked metafunction
+both the return 'type' and the nested boost::tti::marker_type to do the correct
+calculation.
+
+A simple example of this functionality would be:
 
  #include <boost/tti/member_type.hpp>
  
+ struct UDMarkerType { };
+
  BOOST_TTI_MEMBER_TYPE(ANamedType)
  
- typedef typename member_type_ANamedType<EnclosingType>::type AType;
+ typedef member_type_ANamedType<EnclosingType> IMType;
+ typedef member_type_ANamedType<EnclosingType,UDMarkerType> IMTypeWithMarkerType;
  
-If type 'ANamedType' is a nested type of 'EnclosingType' then
-AType is the same type as 'ANamedType', otherwise AType is a
-type internal to the TTI library. In either case AType could
-further be used as a type in template programming, even if
-'EnclosingType::ANamedType' did not exist.
-
-If, on the other hand, we had to specify Atype as 'EnclosingType::ANamedType'
-in template programming, this would lead to a compiler error if this type
-did not exist at the point of instantiation.
-
-[heading A nested type example]
-
-We can use the functionality of `BOOST_TTI_MEMBER_TYPE` to construct nested types
-for our other macro metafunctions, without having to use the T::InnerType syntax and produce a compiler
-error if no such type actually exists within our scope. We can even do this in deeply nested contexts
-by stringing together, so to speak, a series of these macro metafunction results.
+then
+
+ boost::tti::valid_member_type<IMType::type>::value
+ boost::tti::valid_member_type<IMTypeWithMarkerType::type,IMTypeWithMarkerType::boost_tti_marker_type>::value
+
+or
 
-As an example, given a type T, let us create a metafunction where there is a nested type FindType
+ boost::tti::valid_member_metafunction<IMType>::value
+ boost::tti::valid_member_metafunction<IMTypeWithMarkerType>::value
+
+gives us our compile-time result.
+
+[heading An extended nested type example]
+
+As an extended example, given a type T, let us create a metafunction where there is a nested type FindType
 whose enclosing type is eventually T, as represented by the following structure:
 
  struct T
@@ -177,7 +290,7 @@
 exist as we have specified it as a type. If we had tried to do this using normal C++ nested type
 notation our metafunction code above would be:
 
- boost::tti::has_static_member_data_MyData
+ has_static_member_data_MyData
    <
    typename T::AType::BType::CType::FindType,
    int
@@ -186,16 +299,14 @@
 But this fails with a compiler error if there is no such nested type, and
 that is exactly what we do not want in our compile-time metaprogramming code.
 
-in the above metafunction we are asking whether or not FindType has a static
+In the above metafunction we are asking whether or not FindType has a static
 member data element called 'MyData', and the result will be 'false' if either
 FindType does not exist or if it does exist but does not have a static member data
 of type 'int' called 'MyData'. In neither situation will we produce a compiler error.
 
-[heading Existence of nested type]
-
-In some situations we may also be interested in ascertaining whether the deeply nested
+We may also be interested in ascertaining whether the deeply nested
 type 'FindType' actually exists. Our metafunction, using BOOST_TTI_MEMBER_TYPE
-and repeating our macros from above, would be:
+and repeating our macros from above, could be:
 
  BOOST_TTI_MEMBER_TYPE(FindType)
  BOOST_TTI_MEMBER_TYPE(AType)
@@ -221,57 +332,17 @@
>::type
>
   
-But this duplicates much of our code when we generated the 'MyFindType' typedef, so
-it would be much better if we could simply pass our originally typedefed
-'MyFindType' type to some other metafunction which would tell us directly if 'MyFindType'
-actually exists.
-
-And so we can !
-
-The TTI library has a specifically named metafunction,
-called 'boost::tti::valid_member_type', which takes a type and determines
-if it 'actually exists', returning the compile-time boolean constant called 'value'
-of 'true' if it does or 'false' if it does not. The meaning of 'actually exists',
-as far as 'boost::tti::valid_member_type' is concerned, is that the type does not
-equal the unspecified type which BOOST_TTI_MEMBER_TYPE returns when its nested type
-does not exist. Therefore 'boost::tti::valid_member_type' is meant to be used
-with the return 'type' of BOOST_TTI_MEMBER_TYPE, which is what 'MyFindType' represents.
-
-The general explanation of 'boost::tti::valid_member_type' is given as:
-
-[table:existtbmacronested TTI Nested Type Macro Metafunction Existence
- [
- [Inner Element]
- [Macro]
- [Template]
- [Specific Header File]
- ]
- [
- [Type]
- [None]
- [
- [classref boost::tti::valid_member_type]
-
- class T = a type
-
- returns = true if the type exists, false if it does not.
- 'Existence' is determined by whether the type
- does not equal the unspecified type of BOOST_TTI_MEMBER_TYPE
- when the type does not exist.
- ]
- [[headerref boost/tti/member_type.hpp `member_type.hpp`]]
- ]
-]
-
-Using this functionality with our 'MyFindType' type above
-we could create the nullary metafunction:
+But this duplicates much of our code when we generated the 'MyFindType' typedef.
+Instead we use the functionality already provided by 'boost::tti::valid_member_type'.
+Using this functionality with our 'MyFindType' type above we create the nullary
+metafunction:
 
  boost::tti::valid_member_type
    <
    MyFindType
>
  
-directly instead of replicating the same functionality with our 'boost::tti::has_type_FindType'
+directly instead of replicating the same functionality with our 'has_type_FindType'
 metafunction.
 
 [endsect]

Modified: trunk/libs/tti/test/test_mem_type.cpp
==============================================================================
--- trunk/libs/tti/test/test_mem_type.cpp (original)
+++ trunk/libs/tti/test/test_mem_type.cpp 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
@@ -10,14 +10,18 @@
 int main()
   {
   
- BOOST_TEST(boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnIntType)<AType>::type>::value);
- BOOST_TEST(boost::tti::valid_member_type<NameStruct<AType>::type>::value);
- BOOST_TEST(boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnIntTypeReference)<AType>::type>::value);
- BOOST_TEST(boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(BType)<AType>::type>::value);
- BOOST_TEST(boost::tti::valid_member_type<TheInteger<AType::BType>::type>::value);
- BOOST_TEST(boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(CType)<AType::BType>::type>::value);
- BOOST_TEST(boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnotherIntegerType)<AType::BType::CType>::type>::value);
- BOOST_TEST(boost::tti::valid_member_type<SomethingElse<AnotherType>::type>::value);
+ BOOST_TEST((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnIntType)<AType>::type>::value));
+ BOOST_TEST((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnIntTypeReference)<AType>::type>::value));
+ BOOST_TEST((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(BType)<AType>::type>::value));
+ BOOST_TEST((boost::tti::valid_member_type<TheInteger<AType::BType>::type>::value));
+ BOOST_TEST((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnotherIntegerType)<AType::BType::CType>::type>::value));
+ BOOST_TEST((boost::tti::valid_member_type<SomethingElse<AnotherType>::type>::value));
+
+ BOOST_TEST((boost::tti::valid_member_type<NameStruct<AType,MarkerType>::type,NameStruct<AType,MarkerType>::boost_tti_marker_type>::value));
+ BOOST_TEST((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(CType)<AType::BType,MarkerType>::type,BOOST_TTI_MEMBER_TYPE_GEN(CType)<AType::BType,MarkerType>::boost_tti_marker_type>::value));
+
+ BOOST_TEST((!boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(BType)<AnotherType>::type>::value));
+ BOOST_TEST((!boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(NoExistType)<AType,MarkerType>::type,BOOST_TTI_MEMBER_TYPE_GEN(NoExistType)<AType,MarkerType>::boost_tti_marker_type>::value));
   
   return boost::report_errors();
 

Modified: trunk/libs/tti/test/test_mem_type.hpp
==============================================================================
--- trunk/libs/tti/test/test_mem_type.hpp (original)
+++ trunk/libs/tti/test/test_mem_type.hpp 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
@@ -19,4 +19,6 @@
 BOOST_TTI_MEMBER_TYPE(AnotherIntegerType)
 BOOST_TTI_TRAIT_MEMBER_TYPE(SomethingElse,someOtherType)
 
+BOOST_TTI_MEMBER_TYPE(NoExistType)
+
 #endif // TEST_MEMBER_TYPE_HPP

Modified: trunk/libs/tti/test/test_mem_type_compile.cpp
==============================================================================
--- trunk/libs/tti/test/test_mem_type_compile.cpp (original)
+++ trunk/libs/tti/test/test_mem_type_compile.cpp 2013-03-30 03:39:20 EDT (Sat, 30 Mar 2013)
@@ -11,14 +11,18 @@
   {
   
   BOOST_MPL_ASSERT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnIntType)<AType>::type>));
- BOOST_MPL_ASSERT((boost::tti::valid_member_type<NameStruct<AType>::type>));
   BOOST_MPL_ASSERT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnIntTypeReference)<AType>::type>));
   BOOST_MPL_ASSERT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(BType)<AType>::type>));
   BOOST_MPL_ASSERT((boost::tti::valid_member_type<TheInteger<AType::BType>::type>));
- BOOST_MPL_ASSERT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(CType)<AType::BType>::type>));
   BOOST_MPL_ASSERT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(AnotherIntegerType)<AType::BType::CType>::type>));
   BOOST_MPL_ASSERT((boost::tti::valid_member_type<SomethingElse<AnotherType>::type>));
   
+ BOOST_MPL_ASSERT((boost::tti::valid_member_type<NameStruct<AType,MarkerType>::type,NameStruct<AType,MarkerType>::boost_tti_marker_type>));
+ BOOST_MPL_ASSERT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(CType)<AType::BType,MarkerType>::type,BOOST_TTI_MEMBER_TYPE_GEN(CType)<AType::BType,MarkerType>::boost_tti_marker_type>));
+
+ BOOST_MPL_ASSERT_NOT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(BType)<AnotherType>::type>));
+ BOOST_MPL_ASSERT_NOT((boost::tti::valid_member_type<BOOST_TTI_MEMBER_TYPE_GEN(NoExistType)<AType,MarkerType>::type,BOOST_TTI_MEMBER_TYPE_GEN(NoExistType)<AType,MarkerType>::boost_tti_marker_type>));
+
   return 0;
 
   }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk