#ifndef QACPP_TYPE_TRAITS_FI_H
#define QACPP_TYPE_TRAITS_FI_H

#ifndef __QACPP_MAJOR__
#error "PRLGCC requires __QACPP_MAJOR__ and __QACPP_MINOR__ version numbers"
#elif ((__QACPP_MAJOR__ < 32) || ((__QACPP_MAJOR__ == 32) && (__QACPP_MINOR__ < 1)))
#error "PRLGCC requires QA C++ version 3.2 or later"
#endif

#define __alignof                                 __alignof__
#define __ALIGNOF__                               __alignof__
#if (__QACPP_MAJOR__ < 42)
#define __alignof__(x)                            sizeof(char)
#else
#define __alignof__(x)                            alignof(x)
#endif

// TR1 functions (from 050_prlg++.h)
#define __has_nothrow_assign(x)                   __qacpp_has_nothrow_assign(x)
#define __has_nothrow_constructor(x)              __qacpp_has_nothrow_constructor(x)
#define __has_nothrow_copy(x)                     __qacpp_has_nothrow_copy(x)
#define __has_trivial_assign(x)                   __qacpp_has_trivial_assign(x)
#define __has_trivial_constructor(x)              __qacpp_has_trivial_constructor(x)
#define __has_trivial_copy(x)                     __qacpp_has_trivial_copy(x)
#define __has_trivial_destructor(x)               __qacpp_has_trivial_destructor(x)
#define __has_virtual_destructor(x)               __qacpp_has_virtual_destructor(x)
#define __is_abstract(x)                          __qacpp_is_abstract(x)
#define __is_base_of(x,y)                         __qacpp_is_base_of(x,y)
#define __is_same(x,y)                            __qacpp_is_same(x,y)
#define __is_same_as(x,y)                         __qacpp_is_same(x,y)
#define __is_class(x)                             __qacpp_is_class(x)
#define __is_convertible_to(x,y)                  __qacpp_is_convertible(x,y)
#define __is_empty(x)                             __qacpp_is_empty(x)
#define __is_enum(x)                              __qacpp_is_enum(x)
#define __is_pod(x)                               __qacpp_is_pod(x)
#define __is_polymorphic(x)                       __qacpp_is_polymorphic(x)
#define __is_union(x)                             __qacpp_is_union(x)
#define __is_standard_layout(x)                   __qacpp_is_standard_layout(x)
#define __is_aggregate(x)                         __qacpp_is_aggregate(x)

#define __has_assign(x)                           false
#define __has_copy(x)                             false
#define __has_finalizer(x)                        false
#define __has_user_destructor(x)                  false
#define __has_unique_object_representations(x)    __is_trivially_copyable(x)
#define __is_delegate(x)                          false
#define __is_function(x)                          false
#define __is_interface_class(x)                   false
#define __is_ref_array(x)                         false
#define __is_ref_class(x)                         false
#define __is_sealed(x)                            false
#define __is_simple_value_class(x)                false
#define __is_value_class(x)                       false
#define __must_be_array(x)                        false

#if (__QACPP_MAJOR__ < 42)
#define __is_literal_type(x)                      false
#else
#define __is_literal_type(x)                      __qacpp_is_literal(x)
#endif
#define __is_literal(x)                           __is_literal_type(x)

#if (__QACPP_MAJOR__ < 42)
#define __is_trivial(x)                           (__has_trivial_constructor(x) && __has_trivial_copy(x) && __has_trivial_destructor(x))
#define __is_trivially_copyable(x)                (__has_trivial_copy(x) && __has_trivial_destructor(x))
#define __is_trivially_constructible(x,y)         false
#define __is_trivially_assignable(x,y)            false
#else
#define __is_trivial(x)                           __qacpp_is_trivial(x)
#define __is_trivially_copyable(x)                __qacpp_is_trivially_copyable(x)
#define __is_trivially_constructible              __qacpp_is_trivially_constructible
#define __is_trivially_assignable(x,y)            __qacpp_is_trivially_assignable(x, y)
#endif

#if (__QACPP_MAJOR__ < 42)
#define __is_final(x)                             false
#else
#define __is_final(x)                             __qacpp_is_final(x)
#endif
#if (__QACPP_MAJOR__ < 40)
#define __underlying_type(x)                      int
#else
#define __underlying_type(x)                      __qacpp_underlying_type(x)
#endif
#if (__QACPP_MAJOR__ < 42)
#define static_assert                             _ignore_semi
#endif

// we don't support variable templates prior to QA-C++ 4.2
#if (__QACPP_MAJOR__ < 42) && defined(__cpp_variable_templates)
#  undef __cpp_variable_templates
#endif

// we don't support __has_include
#ifdef __has_include
#  undef __has_include
#endif

// we don't support __has_include_next
#ifdef __has_include_next
#  undef __has_include_next
#endif

#define __has_trivial_move_constructor(x) 0
#define __has_trivial_move_assign(x) 0
#define __has_nothrow_move_assign(x) 0

#endif
