#include <type_traits>
#include <complex>

template<class> struct IsComplex_impl  {using type = std::false_type;};
template<class T> struct IsComplex_impl<std::complex<T>> {using type = std::true_type;};

template <typename T>
using IsComplex =  typename IsComplex_impl<T>::type;

/**
 * Evaluates to a true type if the given complex type is an Array of Structs, false otherwise
 * Defaults to false for Real values
 */
template<typename T, typename T_isComplex = IsComplex<T>>
struct IsAoS;

/**
 * Undefined for (unknown) complex types
 */
template< typename T >
struct IsAoS< T, std::false_type >: std::false_type{};

template<>
struct IsAoS< std::complex<double>>: std::true_type{};


int main() {
    static_assert(!IsAoS<int>::value , "");
    static_assert(IsAoS<std::complex<double>>::value , "");
    //static_assert(IsAoS<std::complex<float>>::value , "");
}
