I’m putting this up for comment now. I still need to dot a few I
s and cross a few T
s before it’s ready to go.
Background
This is following on from
 a previous discourse topic
 a prior
standev:math
pull request  standev:math issue #123
std::complex<var>
and std::complex<fvar<T>>
I believe I have a complete std::complex
implementation working in stanmath
on branch
For now the code and tests are in a single file, but will have to be split out for a PR:
 Code:
stan/math/rev/core/std_complex.hpp
 Tests:
test/unit/math/rev/core/std_complex_test.cpp
(Warning: tests take 1m with clang++ and 15m with g++)
std::complex<T>
in C++
For the spec, here’s a mostly complete overview:

spec of std::complex on cppreference (it’s missing at least one integer overload of
pow
)
The key issue is that std::complex<T>
being instantiated is unspecified behavior. So what I’m providing is a complete specialization so nothing relies on unspecified behavior.
For a primer on the evils of function template specializations:
 Walter E. Brown. 2017. Thou Shalt Not Specialize std Function Templates!
What’s in the branch

Overloads of missing
std::
functions likeisinf
in namespacestan::math
for argumentdependent lookup; these are not related tostd::complex
but necessary for some of Eigen’s algorithms; also specializesiterator_traits
. 
Specializations of
std::complex<var>
andstd::complex<fvar<U>>
. The constructors initialize real and imaginary values to zero where necessary (this is roughly what’s suggested in the last bullet point of @syclik’s summary on the issue). 
Code duplication in the
std::complex<T>
class overloads was eliminated by factoring the class overloads into a CRTPbased base class. Code dupe in functions was eliminated by defining fully templated function templates for all complex operations instan::math
to which all other specializations and overloads delegate. I simplified signatures as much as possible to remove ambiguities while covering the combinatorics. There are notes on how that’s done as code comments, since it won’t be obvious from just reading the code (8 overloads should be required for ADL, but the specializations need to be redundantly overloaded to work in both g++ and clang++) 
Specializations of
std::complex
functions where available. Most functions are not class member functions. This is necessary to get aroundlibstdc++
's (used ing++
) poor coding ofstd::complex
for argumentdependent lookup—they hardcodestd::
qualifiers on many complex functions. clang++ works without any specializations. 
Overloads of all functions defined in
std::
in namespacestan::math
for all possible complex instantiations with autodiff variables and for all combinations of pairs of operands (int
,double
,std::complex<double>,
Tand
std::complex, where
Tis one of our autodiff types). These will be picked up by argumentdependent lookup. They will prevent overpromotion to
complex` or to an autodiff type. 
Some supporting metaprograms to deal with return types in complex template functions; these could potentially be merged into general things like
return_type_t
but I didn’t want to extend this megaPR beyond what was necessary forstd::complex
(my plan’s to enlist @Stevo15025’s help on integrating the metaprograms into the general Stan metaprogramming framework—for now they’re just coded to work simply when at least one complex type is involved) 
Complete unit tests for constructors, standalone functions, and overloads. This uses the autodiff test framework to test derivatives at all levels of autodiff:
var
,fvar<double>
,fvar<fvar<double>>
,fvar<var>
, andfvar<fvar<var>>
. That makes sure everything gets instantiated with bothcomplex<T>
for autodiff typeT
and mixed withcomplex<double>
and all other types likedouble
,int
, andT
itself. Where autodiff’s not involved, operaitons like constructors and setters/getters are tested directly for reference equality. 
The final tests are borrowed from the previous PR and instantiate three solvers at all levels of autodiff to make sure they get the right result
 Eigendecomposition for asymmetric matrices
 Pseudoeigendecomposition
 Complex Schur decomposition
Staging a PR
I plan to break this monolithic branch down in order to create a PR in three steps.

namspace
stan::math
: basic Stan infrastructure that doesn’t depend on complex overloads 
namespace
std
: specializations ofstd::complex
class forvar
andfvar

namespace
stan::math
: template functions operating onstd::complex

namespace
std
: specializations ofstd::complex
functions plus namespacestan::math
overloads ofstd::complex
functions forvar
andfvar