87 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <complex>10 11// XFAIL: FROZEN-CXX03-HEADERS-FIXME12 13// template<class T, class U> complex<__promote_t<T, U>> pow(const complex<T>&, const U&);14// template<class T, class U> complex<__promote_t<T, U>> pow(const complex<T>&, const complex<U>&);15// template<class T, class U> complex<__promote_t<T, U>> pow(const T&, const complex<U>&);16 17// Test that these additional overloads are free from catching std::complex<non-floating-point>,18// which is expected by several 3rd party libraries, see https://llvm.org/PR109858.19//20// Note that we reserve the right to break this in the future if we have a reason to, but for the time being,21// make sure we don't break this property unintentionally.22#include <cassert>23#include <cmath>24#include <complex>25#include <type_traits>26 27#include "test_macros.h"28 29namespace usr {30struct usr_tag {};31 32template <class T, class U>33typename std::enable_if<(std::is_same<T, usr_tag>::value && std::is_floating_point<U>::value) ||34 (std::is_floating_point<T>::value && std::is_same<U, usr_tag>::value),35 int>::type36pow(const T&, const std::complex<U>&) {37 return std::is_same<T, usr_tag>::value ? 0 : 1;38}39 40template <class T, class U>41typename std::enable_if<(std::is_same<T, usr_tag>::value && std::is_floating_point<U>::value) ||42 (std::is_floating_point<T>::value && std::is_same<U, usr_tag>::value),43 int>::type44pow(const std::complex<T>&, const U&) {45 return std::is_same<U, usr_tag>::value ? 2 : 3;46}47 48template <class T, class U>49typename std::enable_if<(std::is_same<T, usr_tag>::value && std::is_floating_point<U>::value) ||50 (std::is_floating_point<T>::value && std::is_same<U, usr_tag>::value),51 int>::type52pow(const std::complex<T>&, const std::complex<U>&) {53 return std::is_same<T, usr_tag>::value ? 4 : 5;54}55} // namespace usr56 57int main(int, char**) {58 using std::pow;59 using usr::pow;60 61 usr::usr_tag tag;62 const std::complex<usr::usr_tag> ctag;63 64 assert(pow(tag, std::complex<float>(1.0f)) == 0);65 assert(pow(std::complex<float>(1.0f), tag) == 2);66 assert(pow(tag, std::complex<double>(1.0)) == 0);67 assert(pow(std::complex<double>(1.0), tag) == 2);68 assert(pow(tag, std::complex<long double>(1.0l)) == 0);69 assert(pow(std::complex<long double>(1.0l), tag) == 2);70 71 assert(pow(1.0f, ctag) == 1);72 assert(pow(ctag, 1.0f) == 3);73 assert(pow(1.0, ctag) == 1);74 assert(pow(ctag, 1.0) == 3);75 assert(pow(1.0l, ctag) == 1);76 assert(pow(ctag, 1.0l) == 3);77 78 assert(pow(ctag, std::complex<float>(1.0f)) == 4);79 assert(pow(std::complex<float>(1.0f), ctag) == 5);80 assert(pow(ctag, std::complex<double>(1.0)) == 4);81 assert(pow(std::complex<double>(1.0), ctag) == 5);82 assert(pow(ctag, std::complex<long double>(1.0l)) == 4);83 assert(pow(std::complex<long double>(1.0l), ctag) == 5);84 85 return 0;86}87