Jump to content
  • Advertisement
Sign in to follow this  
PhilCK

asGetTypeTraits

This topic is 1417 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!