#include <type_traits>
#include <complex>

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

template <typename T>
constexpr bool IsComplex() {return IsComplex_impl<T>::value;}


/**
 * 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, bool T_isComplex = IsComplex<T>()>
struct IsAoS;

/**
 * Undefined for (unknown) complex types
 */
template< typename T >
struct IsAoS< T, false>: 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 , "");
}
