// scrap.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include //#include template struct complex_adaptor { typedef typename Backend::signed_types signed_types; typedef typename Backend::unsigned_types unsigned_types; typedef typename Backend::float_types float_types; typedef typename boost::multiprecision::backends::extract_exponent_type< Backend, boost::multiprecision::number_category::value>::type exponent_type; complex_adaptor() {} complex_adaptor(const complex_adaptor& o) : m_real(o.m_real), m_imag(o.m_imag) {} complex_adaptor& operator = (const complex_adaptor& o) { m_real = o.m_real; m_imag = o.m_imag; return *this; } // Any type implicitly convertible to the Backend should be implicitly convertible to this too: template complex_adaptor(const T& i, const typename boost::enable_if_c::value>::type* = 0) : m_real(i) {} // Assign from scalar: template typename boost::enable_if_c::value || boost::is_convertible::value, complex_adaptor&>::type operator = (const T& i) { typedef typename boost::mpl::front::type ui_type; m_real = i; m_imag = ui_type(0); return *this; } complex_adaptor& operator = (const char* s) { // TODO, probably need to break down the string into 2 parts... return *this; } void swap(complex_adaptor& o) { std::swap(m_real, o.m_real()); std::swap(m_imag, o.m_imag); } std::string str(std::streamsize digits, std::ios_base::fmtflags f)const { return "(" + m_real.str(digits, f) + "," + m_imag.str(digits, f) + ")"; } void negate() { m_real.negate(); m_imag.negate(); } int compare(const complex_adaptor& o)const { int c = m_real.compare(o.m_real); if(0 == c) return m_imag.compare(o.m_imag); return c; } template int compare(const T& i)const { int c = m_real.compare(o.m_real); if(0 == c) return m_imag.compare(o.m_imag); return c; } template void serialize(Archive& ar, const unsigned int /*version*/) { ar & m_real; ar & m_imag; } // These are only required for variable precision types - such as mpfr_float_backend<0>: static unsigned default_precision() BOOST_NOEXCEPT { return Backend::default_precision(); } static void default_precision(unsigned v) BOOST_NOEXCEPT { Backend::default_precision(v); } unsigned precision()const BOOST_NOEXCEPT { BOOST_ASSERT(m_real.precision() == m_imag.precision()); // Is this correct?? return m_real.precision(); } void precision(unsigned digits10) BOOST_NOEXCEPT { m_real.precision(digits10); m_imag.precision(digits10); } Backend& real() { return m_real; } Backend& imaginary() { return m_imag; } const Backend& real()const { return m_real; } const Backend& imaginary()const { return m_imag; } private: Backend m_real, m_imag; }; // Two arg construction: template inline void assign_components(complex_adaptor& result, const V& v, const V& u) { result.real() = v; result.imaginary() = u; } // This overload is all we need for addition: template inline void eval_add(complex_adaptor& result, const complex_adaptor& o) { using boost::multiprecision::default_ops::eval_add; eval_add(result.real(), o.real()); } // And subtraction: template inline void eval_subtract(complex_adaptor& result, const complex_adaptor& o) { using boost::multiprecision::default_ops::eval_subtract; eval_subtract(result.real(), o.real()); } // However, we may be able to optimize the operators with further overloads: template inline void eval_add(complex_adaptor& result, const V& o) { using boost::multiprecision::default_ops::eval_add; eval_add(result.real(), o); } template inline void eval_subtract(complex_adaptor& result, const V& o) { using boost::multiprecision::default_ops::eval_subtract; eval_subtract(result.real(), o); } // Other overloads are possible - see docs. namespace boost { namespace multiprecision { // Every new backend must be assigned to a number category so we can identify which // conversions should be implicitly allowed. We really need a new category for comnplex types!! template struct number_category > : public boost::mpl::int_ {}; } } int main() { using namespace boost::multiprecision; typedef number > complex_type; cpp_bin_float_quad q(2); complex_type a, b(0), c(3, 4); a = b + c; a += b; a -= c; a = b - c; // Scalars should work too: a += q; a -= 2; return 0; }