Sign in to follow this  
PhilCK

asGetTypeTraits

Recommended Posts

I upgraded to the latest version of AS, and started to try and use the asGetTypeTraits<T>() but couldn't get it to work. After a little digging AS wasn't recognising my compiler (Xcode/Clang) as C++11, is this intentional because of the <type_traits> being slightly different with the whole is/has stuff?

I noticed you had a stackoverflow post in the comments, and that you did a #if defined ... for the destructor trait. Why wasn't this followed through with the other trait functions? Should I avoid using this with Clang for the moment?
 

Thanks

Phil.

Share this post


Link to post
Share on other sites

This was not intentional. I just don't have Xcode/Clang to test AngelScript on.

 

If you can provide the appropriate changes to make the asGetTypeTraits<T>() to work on Xcode/Clang too I'll gladly incorporate them into the library.

Share this post


Link to post
Share on other sites

Sorry for the dealy I was trying to find the time to check the libc++ and stdlibc++ stuff but haven't found a moment yet. This is what I've got, but I think you'd need to tweak it, as I'm not sure whats the best way to test for libc++ or stdlibc++, currently I'm just falling back on the fact that if all the other CPP11 macro code doesn't pass then treat it as clang with libc++.

template<typename T>
asUINT asGetTypeTraits()
{
#if defined(LIBSTDCPP11) || defined(OTHERCPP11)
bool hasConstructor =  std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
#else
bool hasConstructor =  std::is_default_constructible<T>::value && !std::is_trivially_default_constructible<T>::value;
#endif

#if defined(LIBSTDCPP11)
bool hasDestructor = std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value;
#elsif defined(LIBCPP11)
bool hasDestructor = std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value;
#else
bool hasDestructor = std::is_destructible<T>::value && !std::has_virtual_destructor<T>::value;
#endif


#if defined(LIBSTDCPP11) || defined(OTHERCPP11)
bool hasAssignmentOperator = std::is_copy_assignable<T>::value && !std::has_trivial_copy_assign<T>::value;
bool hasCopyConstructor = std::is_copy_constructible<T>::value && !std::has_trivial_copy_constructor<T>::value;
#else
bool hasAssignmentOperator = std::is_copy_assignable<T>::value && !std::is_trivially_copy_assignable<T>::value;
bool hasCopyConstructor = std::is_copy_constructible<T>::value && !std::is_trivially_copy_constructible<T>::value;
#endif

bool isFloat = std::is_floating_point<T>::value;
bool isPrimitive = std::is_integral<T>::value || std::is_pointer<T>::value || std::is_enum<T>::value;
bool isClass = std::is_class<T>::value;
bool isArray = std::is_array<T>::value;

if( isFloat )
return asOBJ_APP_FLOAT;
if( isPrimitive )
return asOBJ_APP_PRIMITIVE;

if( isClass )
{
asDWORD flags = asOBJ_APP_CLASS;
if( hasConstructor )
flags |= asOBJ_APP_CLASS_CONSTRUCTOR;
if( hasDestructor )
flags |= asOBJ_APP_CLASS_DESTRUCTOR;
if( hasAssignmentOperator )
flags |= asOBJ_APP_CLASS_ASSIGNMENT;
if( hasCopyConstructor )
flags |= asOBJ_APP_CLASS_COPY_CONSTRUCTOR;
return flags;
}

if( isArray )
return asOBJ_APP_ARRAY;

// Unknown type traits
return 0;
}

I found this http://clang.llvm.org/docs/LanguageExtensions.html#feature_check, which seems to imply that these macros can be used across platforms (Which doesn't really solve the problem as there function names are different anyway.).


LIBSTDCPP11 would be __GNUC__
 

Edited by PhilCK

Share this post


Link to post
Share on other sites

I made the change in a different way. Please let me know if this works OK on Xcode/Clang.

 

template<typename T>
asUINT asGetTypeTraits()
{
#if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS) || (defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
// C++11 compliant code
bool hasConstructor        = std::is_default_constructible<T>::value && !std::is_trivially_default_constructible<T>::value;
bool hasDestructor         = std::is_destructible<T>::value          && !std::is_trivially_destructible<T>::value;
bool hasAssignmentOperator = std::is_copy_assignable<T>::value       && !std::is_trivially_copy_assignable<T>::value;
bool hasCopyConstructor    = std::is_copy_constructible<T>::value    && !std::is_trivially_copy_constructible<T>::value;
#else
// Not fully C++11 compliant. The has_trivial checks were used while the standard was still 
// being elaborated, but were then removed in favor of the above is_trivially checks
// http://stackoverflow.com/questions/12702103/writing-code-that-works-when-has-trivial-destructor-is-defined-instead-of-is
// https://github.com/mozart/mozart2/issues/51
bool hasConstructor        = std::is_default_constructible<T>::value && !std::has_trivial_default_constructor<T>::value;
bool hasDestructor         = std::is_destructible<T>::value          && !std::has_trivial_destructor<T>::value;
bool hasAssignmentOperator = std::is_copy_assignable<T>::value       && !std::has_trivial_copy_assign<T>::value;
bool hasCopyConstructor    = std::is_copy_constructible<T>::value    && !std::has_trivial_copy_constructor<T>::value;
#endif
bool isFloat     = std::is_floating_point<T>::value;
bool isPrimitive = std::is_integral<T>::value || std::is_pointer<T>::value || std::is_enum<T>::value;
bool isClass     = std::is_class<T>::value;
bool isArray     = std::is_array<T>::value;
 
if( isFloat )
return asOBJ_APP_FLOAT;
if( isPrimitive )
return asOBJ_APP_PRIMITIVE;
 
if( isClass )
{
asDWORD flags = asOBJ_APP_CLASS;
if( hasConstructor )
flags |= asOBJ_APP_CLASS_CONSTRUCTOR;
if( hasDestructor )
flags |= asOBJ_APP_CLASS_DESTRUCTOR;
if( hasAssignmentOperator )
flags |= asOBJ_APP_CLASS_ASSIGNMENT;
if( hasCopyConstructor )
flags |= asOBJ_APP_CLASS_COPY_CONSTRUCTOR;
return flags;
}
 
if( isArray )
return asOBJ_APP_ARRAY;
 
// Unknown type traits
return 0;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this