| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806 | /////////////////////////////////////////////////////////////////////////////////  Copyright 2011 John Maddock. Distributed under the Boost//  Software License, Version 1.0. (See accompanying file//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)#ifndef BOOST_MATH_BIG_NUM_BASE_HPP#define BOOST_MATH_BIG_NUM_BASE_HPP#include <limits>#include <boost/utility/enable_if.hpp>#include <boost/core/nvp.hpp>#include <boost/type_traits/is_convertible.hpp>#include <boost/type_traits/is_constructible.hpp>#include <boost/type_traits/decay.hpp>#include <boost/math/tools/complex.hpp>#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable : 4307)#endif#include <boost/lexical_cast.hpp>#ifdef BOOST_MSVC#pragma warning(pop)#endif#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) || defined(BOOST_NO_CXX11_HDR_ARRAY)\      || defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) || defined(BOOST_NO_CXX11_CONSTEXPR)\      || defined(BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) || defined(BOOST_NO_CXX11_REF_QUALIFIERS) || defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)\      || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_USER_DEFINED_LITERALS) || defined(BOOST_NO_CXX11_THREAD_LOCAL)\      || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_STATIC_ASSERT) || defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)\      || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_REF_QUALIFIERS)//// The above list includes everything we use, plus a few we're likely to use soon.// As from March 2020, C++03 support is deprecated, and as from March 2021 will be removed,// so mark up as such://#if (defined(_MSC_VER) || defined(__GNUC__)) && !defined(BOOST_MP_DISABLE_DEPRECATE_03_WARNING)#pragma message("CAUTION: One or more C++11 features were found to be unavailable")#pragma message("CAUTION: Compiling Boost.Multiprecision in non-C++11 or later conformance modes is now deprecated and will be removed from March 2021.")#pragma message("CAUTION: Define BOOST_MP_DISABLE_DEPRECATE_03_WARNING to suppress this message.")#endif#endif#if defined(NDEBUG) && !defined(_DEBUG)#define BOOST_MP_FORCEINLINE BOOST_FORCEINLINE#else#define BOOST_MP_FORCEINLINE inline#endif#if (defined(BOOST_GCC) && (BOOST_GCC <= 40700)) || BOOST_WORKAROUND(__SUNPRO_CC, < 0x5140) || (defined(__clang_major__) && (__clang_major__ == 3) && (__clang_minor__ < 5))#define BOOST_MP_NOEXCEPT_IF(x)#else#define BOOST_MP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x)#endif#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) || BOOST_WORKAROUND(__SUNPRO_CC, < 0x5140)#define BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS#endif//// Thread local storage:// Note fails on Mingw, see https://sourceforge.net/p/mingw-w64/bugs/527///#if !defined(BOOST_NO_CXX11_THREAD_LOCAL) && !defined(BOOST_INTEL) && !defined(__MINGW32__)#define BOOST_MP_THREAD_LOCAL thread_local#define BOOST_MP_USING_THREAD_LOCAL#else#define BOOST_MP_THREAD_LOCAL#endif#ifdef __has_include# if __has_include(<version>)#  include <version>#  ifdef __cpp_lib_is_constant_evaluated#   include <type_traits>#   define BOOST_MP_HAS_IS_CONSTANT_EVALUATED#  endif# endif#endif#ifdef __has_builtin#if __has_builtin(__builtin_is_constant_evaluated) && !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)#define BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED#endif#endif//// MSVC also supports __builtin_is_constant_evaluated if it's recent enough://#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326)#  define BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED#endif//// As does GCC-9://#if defined(BOOST_GCC) && !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 9) && !defined(BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED)#  define BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED#endif#if defined(BOOST_MP_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR)#  define BOOST_MP_IS_CONST_EVALUATED(x) std::is_constant_evaluated()#elif defined(BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED)#  define BOOST_MP_IS_CONST_EVALUATED(x) __builtin_is_constant_evaluated()#elif !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(BOOST_GCC) && (__GNUC__ >= 6)#  define BOOST_MP_IS_CONST_EVALUATED(x) __builtin_constant_p(x)#else#  define BOOST_MP_NO_CONSTEXPR_DETECTION#endif#define BOOST_MP_CXX14_CONSTEXPR BOOST_CXX14_CONSTEXPR//// Early compiler versions trip over the constexpr code://#if defined(__clang__) && (__clang_major__ < 5)#undef BOOST_MP_CXX14_CONSTEXPR#define BOOST_MP_CXX14_CONSTEXPR#endif#if defined(__apple_build_version__) && (__clang_major__ < 9)#undef BOOST_MP_CXX14_CONSTEXPR#define BOOST_MP_CXX14_CONSTEXPR#endif#if defined(BOOST_GCC) && (__GNUC__ < 6)#undef BOOST_MP_CXX14_CONSTEXPR#define BOOST_MP_CXX14_CONSTEXPR#endif#if defined(BOOST_INTEL)#undef BOOST_MP_CXX14_CONSTEXPR#define BOOST_MP_CXX14_CONSTEXPR#define BOOST_MP_NO_CONSTEXPR_DETECTION#endif#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION#  define BOOST_CXX14_CONSTEXPR_IF_DETECTION#else#  define BOOST_CXX14_CONSTEXPR_IF_DETECTION constexpr#endif#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable : 6326)#endifnamespace boost {namespace multiprecision {enum expression_template_option{   et_off = 0,   et_on  = 1};template <class Backend>struct expression_template_default{   static const expression_template_option value = et_on;};template <class Backend, expression_template_option ExpressionTemplates = expression_template_default<Backend>::value>class number;template <class T>struct is_number : public mpl::false_{};template <class Backend, expression_template_option ExpressionTemplates>struct is_number<number<Backend, ExpressionTemplates> > : public mpl::true_{};template <class T>struct is_et_number : public mpl::false_{};template <class Backend>struct is_et_number<number<Backend, et_on> > : public mpl::true_{};template <class T>struct is_no_et_number : public mpl::false_{};template <class Backend>struct is_no_et_number<number<Backend, et_off> > : public mpl::true_{};namespace detail {// Forward-declare an expression wrappertemplate <class tag, class Arg1 = void, class Arg2 = void, class Arg3 = void, class Arg4 = void>struct expression;} // namespace detailtemplate <class T>struct is_number_expression : public mpl::false_{};template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>struct is_number_expression<detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > : public mpl::true_{};template <class T, class Num>struct is_compatible_arithmetic_type    : public mpl::bool_<          is_convertible<T, Num>::value && !is_same<T, Num>::value && !is_number_expression<T>::value>{};namespace detail {//// Workaround for missing abs(boost::long_long_type) and abs(__int128) on some compilers://template <class T>BOOST_CONSTEXPR typename enable_if_c<(is_signed<T>::value || is_floating_point<T>::value), T>::type abs(T t) BOOST_NOEXCEPT{   // This strange expression avoids a hardware trap in the corner case   // that val is the most negative value permitted in boost::long_long_type.   // See https://svn.boost.org/trac/boost/ticket/9740.   return t < 0 ? T(1u) + T(-(t + 1)) : t;}template <class T>BOOST_CONSTEXPR typename enable_if_c<(is_unsigned<T>::value), T>::type abs(T t) BOOST_NOEXCEPT{   return t;}#define BOOST_MP_USING_ABS using boost::multiprecision::detail::abs;template <class T>BOOST_CONSTEXPR typename enable_if_c<(is_signed<T>::value || is_floating_point<T>::value), typename make_unsigned<T>::type>::type unsigned_abs(T t) BOOST_NOEXCEPT{   // This strange expression avoids a hardware trap in the corner case   // that val is the most negative value permitted in boost::long_long_type.   // See https://svn.boost.org/trac/boost/ticket/9740.   return t < 0 ? static_cast<typename make_unsigned<T>::type>(1u) + static_cast<typename make_unsigned<T>::type>(-(t + 1)) : static_cast<typename make_unsigned<T>::type>(t);}template <class T>BOOST_CONSTEXPR typename enable_if_c<(is_unsigned<T>::value), T>::type unsigned_abs(T t) BOOST_NOEXCEPT{   return t;}//// Move support://#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES#define BOOST_MP_MOVE(x) std::move(x)#else#define BOOST_MP_MOVE(x) x#endiftemplate <class T>struct bits_of{   BOOST_STATIC_ASSERT(is_integral<T>::value || is_enum<T>::value || std::numeric_limits<T>::is_specialized);   static const unsigned value =       std::numeric_limits<T>::is_specialized ? std::numeric_limits<T>::digits                                              : sizeof(T) * CHAR_BIT - (is_signed<T>::value ? 1 : 0);};#if defined(_GLIBCXX_USE_FLOAT128) && defined(BOOST_GCC) && !defined(__STRICT_ANSI__)#define BOOST_MP_BITS_OF_FLOAT128_DEFINEDtemplate <>struct bits_of<__float128>{   static const unsigned value = 113;};#endiftemplate <int b>struct has_enough_bits{   template <class T>   struct type : public mpl::bool_<bits_of<T>::value >= b>   {};};template <class Val, class Backend, class Tag>struct canonical_imp{   typedef typename remove_cv<typename decay<const Val>::type>::type type;};template <class B, class Backend, class Tag>struct canonical_imp<number<B, et_on>, Backend, Tag>{   typedef B type;};template <class B, class Backend, class Tag>struct canonical_imp<number<B, et_off>, Backend, Tag>{   typedef B type;};#ifdef __SUNPRO_CCtemplate <class B, class Backend>struct canonical_imp<number<B, et_on>, Backend, mpl::int_<3> >{   typedef B type;};template <class B, class Backend>struct canonical_imp<number<B, et_off>, Backend, mpl::int_<3> >{   typedef B type;};#endiftemplate <class Val, class Backend>struct canonical_imp<Val, Backend, mpl::int_<0> >{   typedef typename has_enough_bits<bits_of<Val>::value>::template type<mpl::_> pred_type;   typedef typename mpl::find_if<       typename Backend::signed_types,       pred_type>::type                                                                                                 iter_type;   typedef typename mpl::end<typename Backend::signed_types>::type                                                      end_type;   typedef typename mpl::eval_if<boost::is_same<iter_type, end_type>, mpl::identity<Val>, mpl::deref<iter_type> >::type type;};template <class Val, class Backend>struct canonical_imp<Val, Backend, mpl::int_<1> >{   typedef typename has_enough_bits<bits_of<Val>::value>::template type<mpl::_> pred_type;   typedef typename mpl::find_if<       typename Backend::unsigned_types,       pred_type>::type                                                                                                 iter_type;   typedef typename mpl::end<typename Backend::unsigned_types>::type                                                    end_type;   typedef typename mpl::eval_if<boost::is_same<iter_type, end_type>, mpl::identity<Val>, mpl::deref<iter_type> >::type type;};template <class Val, class Backend>struct canonical_imp<Val, Backend, mpl::int_<2> >{   typedef typename has_enough_bits<bits_of<Val>::value>::template type<mpl::_> pred_type;   typedef typename mpl::find_if<       typename Backend::float_types,       pred_type>::type                                                                                                 iter_type;   typedef typename mpl::end<typename Backend::float_types>::type                                                       end_type;   typedef typename mpl::eval_if<boost::is_same<iter_type, end_type>, mpl::identity<Val>, mpl::deref<iter_type> >::type type;};template <class Val, class Backend>struct canonical_imp<Val, Backend, mpl::int_<3> >{   typedef const char* type;};template <class Val, class Backend>struct canonical{   typedef typename mpl::if_<       is_signed<Val>,       mpl::int_<0>,       typename mpl::if_<           is_unsigned<Val>,           mpl::int_<1>,           typename mpl::if_<               is_floating_point<Val>,               mpl::int_<2>,               typename mpl::if_<                   mpl::or_<                       is_convertible<Val, const char*>,                       is_same<Val, std::string> >,                   mpl::int_<3>,                   mpl::int_<4> >::type>::type>::type>::type tag_type;   typedef typename canonical_imp<Val, Backend, tag_type>::type type;};struct terminal{};struct negate{};struct plus{};struct minus{};struct multiplies{};struct divides{};struct modulus{};struct shift_left{};struct shift_right{};struct bitwise_and{};struct bitwise_or{};struct bitwise_xor{};struct bitwise_complement{};struct add_immediates{};struct subtract_immediates{};struct multiply_immediates{};struct divide_immediates{};struct modulus_immediates{};struct bitwise_and_immediates{};struct bitwise_or_immediates{};struct bitwise_xor_immediates{};struct complement_immediates{};struct function{};struct multiply_add{};struct multiply_subtract{};template <class T>struct backend_type;template <class T, expression_template_option ExpressionTemplates>struct backend_type<number<T, ExpressionTemplates> >{   typedef T type;};template <class tag, class A1, class A2, class A3, class A4>struct backend_type<expression<tag, A1, A2, A3, A4> >{   typedef typename backend_type<typename expression<tag, A1, A2, A3, A4>::result_type>::type type;};template <class T1, class T2>struct combine_expression{#ifdef BOOST_NO_CXX11_DECLTYPE   typedef typename mpl::if_c<(sizeof(T1() + T2()) == sizeof(T1)), T1, T2>::type type;#else   typedef decltype(T1() + T2()) type;#endif};template <class T1, expression_template_option ExpressionTemplates, class T2>struct combine_expression<number<T1, ExpressionTemplates>, T2>{   typedef number<T1, ExpressionTemplates> type;};template <class T1, class T2, expression_template_option ExpressionTemplates>struct combine_expression<T1, number<T2, ExpressionTemplates> >{   typedef number<T2, ExpressionTemplates> type;};template <class T, expression_template_option ExpressionTemplates>struct combine_expression<number<T, ExpressionTemplates>, number<T, ExpressionTemplates> >{   typedef number<T, ExpressionTemplates> type;};template <class T1, expression_template_option ExpressionTemplates1, class T2, expression_template_option ExpressionTemplates2>struct combine_expression<number<T1, ExpressionTemplates1>, number<T2, ExpressionTemplates2> >{   typedef typename mpl::if_c<       is_convertible<number<T2, ExpressionTemplates2>, number<T1, ExpressionTemplates2> >::value,       number<T1, ExpressionTemplates1>,       number<T2, ExpressionTemplates2> >::type type;};template <class T>struct arg_type{   typedef expression<terminal, T> type;};template <class Tag, class Arg1, class Arg2, class Arg3, class Arg4>struct arg_type<expression<Tag, Arg1, Arg2, Arg3, Arg4> >{   typedef expression<Tag, Arg1, Arg2, Arg3, Arg4> type;};struct unmentionable{   unmentionable* proc() { return 0; }};typedef unmentionable* (unmentionable::*unmentionable_type)();template <class T, bool b>struct expression_storage_base{   typedef const T& type;};template <class T>struct expression_storage_base<T, true>{   typedef T type;};template <class T>struct expression_storage : public expression_storage_base<T, boost::is_arithmetic<T>::value>{};template <class T>struct expression_storage<T*>{   typedef T* type;};template <class T>struct expression_storage<const T*>{   typedef const T* type;};template <class tag, class A1, class A2, class A3, class A4>struct expression_storage<expression<tag, A1, A2, A3, A4> >{   typedef expression<tag, A1, A2, A3, A4> type;};template <class tag, class Arg1>struct expression<tag, Arg1, void, void, void>{   typedef mpl::int_<1>                    arity;   typedef typename arg_type<Arg1>::type   left_type;   typedef typename left_type::result_type left_result_type;   typedef typename left_type::result_type result_type;   typedef tag                             tag_type;   explicit BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a) : arg(a) {}   BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg(e.arg) {}#ifndef BOOST_NO_CXX11_STATIC_ASSERT   //   // If we have static_assert we can give a more useful error message   // than if we simply have no operator defined at all:   //   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }#endif   BOOST_MP_CXX14_CONSTEXPR left_type left() const   {      return left_type(arg);   }   BOOST_MP_CXX14_CONSTEXPR const Arg1& left_ref() const BOOST_NOEXCEPT { return arg; }   static const unsigned depth = left_type::depth + 1;#ifndef BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS#if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7) && !defined(__clang__)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))   //   // Horrible workaround for gcc-4.6.x which always prefers the template   // operator bool() rather than the non-template operator when converting to   // an arithmetic type:   //   template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>   explicit operator T() const   {      result_type r(*this);      return static_cast<bool>(r);   }   template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>   explicit operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }#else   template <class T#ifndef __SUNPRO_CC             ,             typename boost::disable_if_c<is_number<T>::value || is_constructible<T const&, result_type>::value || !is_constructible<T, result_type>::value, int>::type = 0#endif             >   explicit BOOST_MP_CXX14_CONSTEXPR operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }   BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const   {      result_type r(*this);      return static_cast<bool>(r);   }#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)   BOOST_MP_FORCEINLINE explicit operator void() const   {}#endif#endif#else   operator unmentionable_type() const   {      result_type r(*this);      return r ? &unmentionable::proc : 0;   }#endif   template <class T>   BOOST_MP_CXX14_CONSTEXPR T convert_to()   {      result_type r(*this);      return r.template convert_to<T>();   } private:   typename expression_storage<Arg1>::type arg;   expression&                             operator=(const expression&);};template <class Arg1>struct expression<terminal, Arg1, void, void, void>{   typedef mpl::int_<0> arity;   typedef Arg1         result_type;   typedef terminal     tag_type;   explicit BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a) : arg(a) {}   BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg(e.arg) {}#ifndef BOOST_NO_CXX11_STATIC_ASSERT   //   // If we have static_assert we can give a more useful error message   // than if we simply have no operator defined at all:   //   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }#endif   BOOST_MP_CXX14_CONSTEXPR const Arg1& value() const BOOST_NOEXCEPT   {      return arg;   }   static const unsigned depth = 0;#ifndef BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS#if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7) && !defined(__clang__)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))   //   // Horrible workaround for gcc-4.6.x which always prefers the template   // operator bool() rather than the non-template operator when converting to   // an arithmetic type:   //   template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>   explicit operator T() const   {      result_type r(*this);      return static_cast<bool>(r);   }   template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>   explicit operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }#else   template <class T#ifndef __SUNPRO_CC             ,             typename boost::disable_if_c<is_number<T>::value || is_constructible<T const&, result_type>::value || !is_constructible<T, result_type>::value, int>::type = 0#endif             >   explicit BOOST_MP_CXX14_CONSTEXPR operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }   BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const   {      result_type r(*this);      return static_cast<bool>(r);   }#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)   BOOST_MP_FORCEINLINE explicit operator void() const   {}#endif#endif#else   operator unmentionable_type() const   {      return arg ? &unmentionable::proc : 0;   }#endif   template <class T>   BOOST_MP_CXX14_CONSTEXPR T convert_to()   {      result_type r(*this);      return r.template convert_to<T>();   } private:   typename expression_storage<Arg1>::type arg;   expression&                             operator=(const expression&);};template <class tag, class Arg1, class Arg2>struct expression<tag, Arg1, Arg2, void, void>{   typedef mpl::int_<2>                                                           arity;   typedef typename arg_type<Arg1>::type                                          left_type;   typedef typename arg_type<Arg2>::type                                          right_type;   typedef typename left_type::result_type                                        left_result_type;   typedef typename right_type::result_type                                       right_result_type;   typedef typename combine_expression<left_result_type, right_result_type>::type result_type;   typedef tag                                                                    tag_type;   BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a1, const Arg2& a2) : arg1(a1), arg2(a2) {}   BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg1(e.arg1), arg2(e.arg2) {}#ifndef BOOST_NO_CXX11_STATIC_ASSERT   //   // If we have static_assert we can give a more useful error message   // than if we simply have no operator defined at all:   //   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }#endif   BOOST_MP_CXX14_CONSTEXPR left_type left() const   {      return left_type(arg1);   }   BOOST_MP_CXX14_CONSTEXPR right_type  right() const { return right_type(arg2); }   BOOST_MP_CXX14_CONSTEXPR const Arg1& left_ref() const BOOST_NOEXCEPT { return arg1; }   BOOST_MP_CXX14_CONSTEXPR const Arg2& right_ref() const BOOST_NOEXCEPT { return arg2; }#ifndef BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS#if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7) && !defined(__clang__)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))   //   // Horrible workaround for gcc-4.6.x which always prefers the template   // operator bool() rather than the non-template operator when converting to   // an arithmetic type:   //   template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>   explicit operator T() const   {      result_type r(*this);      return static_cast<bool>(r);   }   template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>   explicit operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }#else   template <class T#ifndef __SUNPRO_CC             ,             typename boost::disable_if_c<is_number<T>::value || is_constructible<T const&, result_type>::value || !is_constructible<T, result_type>::value, int>::type = 0#endif             >   explicit BOOST_MP_CXX14_CONSTEXPR operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }   BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const   {      result_type r(*this);      return static_cast<bool>(r);   }#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)   BOOST_MP_FORCEINLINE explicit operator void() const   {}#endif#endif#else   operator unmentionable_type() const   {      result_type r(*this);      return r ? &unmentionable::proc : 0;   }#endif   template <class T>   BOOST_MP_CXX14_CONSTEXPR T convert_to()   {      result_type r(*this);      return r.template convert_to<T>();   }   static const BOOST_MP_CXX14_CONSTEXPR unsigned left_depth  = left_type::depth + 1;   static const BOOST_MP_CXX14_CONSTEXPR unsigned right_depth = right_type::depth + 1;   static const BOOST_MP_CXX14_CONSTEXPR unsigned depth       = left_depth > right_depth ? left_depth : right_depth; private:   typename expression_storage<Arg1>::type arg1;   typename expression_storage<Arg2>::type arg2;   expression&                             operator=(const expression&);};template <class tag, class Arg1, class Arg2, class Arg3>struct expression<tag, Arg1, Arg2, Arg3, void>{   typedef mpl::int_<3>                      arity;   typedef typename arg_type<Arg1>::type     left_type;   typedef typename arg_type<Arg2>::type     middle_type;   typedef typename arg_type<Arg3>::type     right_type;   typedef typename left_type::result_type   left_result_type;   typedef typename middle_type::result_type middle_result_type;   typedef typename right_type::result_type  right_result_type;   typedef typename combine_expression<       left_result_type,       typename combine_expression<right_result_type, middle_result_type>::type>::type result_type;   typedef tag                                                                         tag_type;   BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a1, const Arg2& a2, const Arg3& a3) : arg1(a1), arg2(a2), arg3(a3) {}   BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg1(e.arg1), arg2(e.arg2), arg3(e.arg3) {}#ifndef BOOST_NO_CXX11_STATIC_ASSERT   //   // If we have static_assert we can give a more useful error message   // than if we simply have no operator defined at all:   //   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }#endif   BOOST_MP_CXX14_CONSTEXPR left_type left() const   {      return left_type(arg1);   }   BOOST_MP_CXX14_CONSTEXPR middle_type middle() const { return middle_type(arg2); }   BOOST_MP_CXX14_CONSTEXPR right_type  right() const { return right_type(arg3); }   BOOST_MP_CXX14_CONSTEXPR const Arg1& left_ref() const BOOST_NOEXCEPT { return arg1; }   BOOST_MP_CXX14_CONSTEXPR const Arg2& middle_ref() const BOOST_NOEXCEPT { return arg2; }   BOOST_MP_CXX14_CONSTEXPR const Arg3& right_ref() const BOOST_NOEXCEPT { return arg3; }#ifndef BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS#if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7) && !defined(__clang__)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))   //   // Horrible workaround for gcc-4.6.x which always prefers the template   // operator bool() rather than the non-template operator when converting to   // an arithmetic type:   //   template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>   explicit operator T() const   {      result_type r(*this);      return static_cast<bool>(r);   }   template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>   explicit operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }#else   template <class T#ifndef __SUNPRO_CC             ,             typename boost::disable_if_c<is_number<T>::value || is_constructible<T const&, result_type>::value || !is_constructible<T, result_type>::value, int>::type = 0#endif             >   explicit BOOST_MP_CXX14_CONSTEXPR operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }   BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const   {      result_type r(*this);      return static_cast<bool>(r);   }#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)   BOOST_MP_FORCEINLINE explicit operator void() const   {}#endif#endif#else   operator unmentionable_type() const   {      result_type r(*this);      return r ? &unmentionable::proc : 0;   }#endif   template <class T>   BOOST_MP_CXX14_CONSTEXPR T convert_to()   {      result_type r(*this);      return r.template convert_to<T>();   }   static const unsigned left_depth   = left_type::depth + 1;   static const unsigned middle_depth = middle_type::depth + 1;   static const unsigned right_depth  = right_type::depth + 1;   static const unsigned depth        = left_depth > right_depth ? (left_depth > middle_depth ? left_depth : middle_depth) : (right_depth > middle_depth ? right_depth : middle_depth); private:   typename expression_storage<Arg1>::type arg1;   typename expression_storage<Arg2>::type arg2;   typename expression_storage<Arg3>::type arg3;   expression&                             operator=(const expression&);};template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>struct expression{   typedef mpl::int_<4>                            arity;   typedef typename arg_type<Arg1>::type           left_type;   typedef typename arg_type<Arg2>::type           left_middle_type;   typedef typename arg_type<Arg3>::type           right_middle_type;   typedef typename arg_type<Arg4>::type           right_type;   typedef typename left_type::result_type         left_result_type;   typedef typename left_middle_type::result_type  left_middle_result_type;   typedef typename right_middle_type::result_type right_middle_result_type;   typedef typename right_type::result_type        right_result_type;   typedef typename combine_expression<       left_result_type,       typename combine_expression<           left_middle_result_type,           typename combine_expression<right_middle_result_type, right_result_type>::type>::type>::type result_type;   typedef tag                                                                                          tag_type;   BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a1, const Arg2& a2, const Arg3& a3, const Arg4& a4) : arg1(a1), arg2(a2), arg3(a3), arg4(a4) {}   BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg1(e.arg1), arg2(e.arg2), arg3(e.arg3), arg4(e.arg4) {}#ifndef BOOST_NO_CXX11_STATIC_ASSERT   //   // If we have static_assert we can give a more useful error message   // than if we simply have no operator defined at all:   //   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator++(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--()   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   BOOST_MP_CXX14_CONSTEXPR expression& operator--(int)   {      // This should always fail:      static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }   template <class Other>   BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&)   {      // This should always fail:      static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable?  Or pass an expression to a template function with deduced temnplate arguments?");      return *this;   }#endif   BOOST_MP_CXX14_CONSTEXPR left_type left() const   {      return left_type(arg1);   }   BOOST_MP_CXX14_CONSTEXPR left_middle_type  left_middle() const { return left_middle_type(arg2); }   BOOST_MP_CXX14_CONSTEXPR right_middle_type right_middle() const { return right_middle_type(arg3); }   BOOST_MP_CXX14_CONSTEXPR right_type        right() const { return right_type(arg4); }   BOOST_MP_CXX14_CONSTEXPR const Arg1&       left_ref() const BOOST_NOEXCEPT { return arg1; }   BOOST_MP_CXX14_CONSTEXPR const Arg2&       left_middle_ref() const BOOST_NOEXCEPT { return arg2; }   BOOST_MP_CXX14_CONSTEXPR const Arg3&       right_middle_ref() const BOOST_NOEXCEPT { return arg3; }   BOOST_MP_CXX14_CONSTEXPR const Arg4&       right_ref() const BOOST_NOEXCEPT { return arg4; }#ifndef BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS#if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7) && !defined(__clang__)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))   //   // Horrible workaround for gcc-4.6.x which always prefers the template   // operator bool() rather than the non-template operator when converting to   // an arithmetic type:   //   template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>   explicit operator T() const   {      result_type r(*this);      return static_cast<bool>(r);   }   template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>   explicit operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }#else   template <class T#ifndef __SUNPRO_CC             ,             typename boost::disable_if_c<is_number<T>::value || is_constructible<T const&, result_type>::value || !is_constructible<T, result_type>::value, int>::type = 0#endif             >   explicit BOOST_MP_CXX14_CONSTEXPR operator T() const   {      return static_cast<T>(static_cast<result_type>(*this));   }   BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const   {      result_type r(*this);      return static_cast<bool>(r);   }#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)   BOOST_MP_FORCEINLINE explicit operator void() const   {}#endif#endif#else   operator unmentionable_type() const   {      result_type r(*this);      return r ? &unmentionable::proc : 0;   }#endif   template <class T>   BOOST_MP_CXX14_CONSTEXPR T convert_to()   {      result_type r(*this);      return r.template convert_to<T>();   }   static const unsigned left_depth         = left_type::depth + 1;   static const unsigned left_middle_depth  = left_middle_type::depth + 1;   static const unsigned right_middle_depth = right_middle_type::depth + 1;   static const unsigned right_depth        = right_type::depth + 1;   static const unsigned left_max_depth  = left_depth > left_middle_depth ? left_depth : left_middle_depth;   static const unsigned right_max_depth = right_depth > right_middle_depth ? right_depth : right_middle_depth;   static const unsigned depth = left_max_depth > right_max_depth ? left_max_depth : right_max_depth; private:   typename expression_storage<Arg1>::type arg1;   typename expression_storage<Arg2>::type arg2;   typename expression_storage<Arg3>::type arg3;   typename expression_storage<Arg4>::type arg4;   expression&                             operator=(const expression&);};template <class T>struct digits2{   BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);   BOOST_STATIC_ASSERT((std::numeric_limits<T>::radix == 2) || (std::numeric_limits<T>::radix == 10));   // If we really have so many digits that this fails, then we're probably going to hit other problems anyway:   BOOST_STATIC_ASSERT(LONG_MAX / 1000 > (std::numeric_limits<T>::digits + 1));   static const long                  m_value = std::numeric_limits<T>::radix == 10 ? (((std::numeric_limits<T>::digits + 1) * 1000L) / 301L) : std::numeric_limits<T>::digits;   static inline BOOST_CONSTEXPR long value() BOOST_NOEXCEPT { return m_value; }};#ifndef BOOST_MP_MIN_EXPONENT_DIGITS#ifdef _MSC_VER#define BOOST_MP_MIN_EXPONENT_DIGITS 2#else#define BOOST_MP_MIN_EXPONENT_DIGITS 2#endif#endiftemplate <class S>void format_float_string(S& str, boost::intmax_t my_exp, boost::intmax_t digits, std::ios_base::fmtflags f, bool iszero){   typedef typename S::size_type size_type;   bool                          scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;   bool                          fixed      = (f & std::ios_base::fixed) == std::ios_base::fixed;   bool                          showpoint  = (f & std::ios_base::showpoint) == std::ios_base::showpoint;   bool                          showpos    = (f & std::ios_base::showpos) == std::ios_base::showpos;   bool neg = str.size() && (str[0] == '-');   if (neg)      str.erase(0, 1);   if (digits == 0)   {      digits = (std::max)(str.size(), size_type(16));   }   if (iszero || str.empty() || (str.find_first_not_of('0') == S::npos))   {      // We will be printing zero, even though the value might not      // actually be zero (it just may have been rounded to zero).      str = "0";      if (scientific || fixed)      {         str.append(1, '.');         str.append(size_type(digits), '0');         if (scientific)            str.append("e+00");      }      else      {         if (showpoint)         {            str.append(1, '.');            if (digits > 1)               str.append(size_type(digits - 1), '0');         }      }      if (neg)         str.insert(static_cast<std::string::size_type>(0), 1, '-');      else if (showpos)         str.insert(static_cast<std::string::size_type>(0), 1, '+');      return;   }   if (!fixed && !scientific && !showpoint)   {      //      // Suppress trailing zeros:      //      std::string::iterator pos = str.end();      while (pos != str.begin() && *--pos == '0')      {      }      if (pos != str.end())         ++pos;      str.erase(pos, str.end());      if (str.empty())         str = '0';   }   else if (!fixed || (my_exp >= 0))   {      //      // Pad out the end with zero's if we need to:      //      boost::intmax_t chars = str.size();      chars                 = digits - chars;      if (scientific)         ++chars;      if (chars > 0)      {         str.append(static_cast<std::string::size_type>(chars), '0');      }   }   if (fixed || (!scientific && (my_exp >= -4) && (my_exp < digits)))   {      if (1 + my_exp > static_cast<boost::intmax_t>(str.size()))      {         // Just pad out the end with zeros:         str.append(static_cast<std::string::size_type>(1 + my_exp - str.size()), '0');         if (showpoint || fixed)            str.append(".");      }      else if (my_exp + 1 < static_cast<boost::intmax_t>(str.size()))      {         if (my_exp < 0)         {            str.insert(static_cast<std::string::size_type>(0), static_cast<std::string::size_type>(-1 - my_exp), '0');            str.insert(static_cast<std::string::size_type>(0), "0.");         }         else         {            // Insert the decimal point:            str.insert(static_cast<std::string::size_type>(my_exp + 1), 1, '.');         }      }      else if (showpoint || fixed) // we have exactly the digits we require to left of the point         str += ".";      if (fixed)      {         // We may need to add trailing zeros:         boost::intmax_t l = str.find('.') + 1;         l                 = digits - (str.size() - l);         if (l > 0)            str.append(size_type(l), '0');      }   }   else   {      BOOST_MP_USING_ABS      // Scientific format:      if (showpoint || (str.size() > 1))         str.insert(static_cast<std::string::size_type>(1u), 1, '.');      str.append(static_cast<std::string::size_type>(1u), 'e');      S e = boost::lexical_cast<S>(abs(my_exp));      if (e.size() < BOOST_MP_MIN_EXPONENT_DIGITS)         e.insert(static_cast<std::string::size_type>(0), BOOST_MP_MIN_EXPONENT_DIGITS - e.size(), '0');      if (my_exp < 0)         e.insert(static_cast<std::string::size_type>(0), 1, '-');      else         e.insert(static_cast<std::string::size_type>(0), 1, '+');      str.append(e);   }   if (neg)      str.insert(static_cast<std::string::size_type>(0), 1, '-');   else if (showpos)      str.insert(static_cast<std::string::size_type>(0), 1, '+');}template <class V>BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V val, const mpl::true_&, const mpl::true_&){   if (val > (std::numeric_limits<std::size_t>::max)())      BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a value greater than std::numeric_limits<std::size_t>::max()."));   if (val < 0)      BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a negative value."));}template <class V>BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V val, const mpl::false_&, const mpl::true_&){   if (val < 0)      BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a negative value."));}template <class V>BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V val, const mpl::true_&, const mpl::false_&){   if (val > (std::numeric_limits<std::size_t>::max)())      BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a value greater than std::numeric_limits<std::size_t>::max()."));}template <class V>BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V, const mpl::false_&, const mpl::false_&) BOOST_NOEXCEPT {}template <class T>BOOST_MP_CXX14_CONSTEXPR const T& evaluate_if_expression(const T& val) { return val; }template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>BOOST_MP_CXX14_CONSTEXPR typename expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type evaluate_if_expression(const expression<tag, Arg1, Arg2, Arg3, Arg4>& val) { return val; }} // namespace detail//// Traits class, lets us know what kind of number we have, defaults to a floating point type://enum number_category_type{   number_kind_unknown        = -1,   number_kind_integer        = 0,   number_kind_floating_point = 1,   number_kind_rational       = 2,   number_kind_fixed_point    = 3,   number_kind_complex        = 4};template <class Num, bool, bool>struct number_category_base : public mpl::int_<number_kind_unknown>{};template <class Num>struct number_category_base<Num, true, false> : public mpl::int_<std::numeric_limits<Num>::is_integer ? number_kind_integer : (std::numeric_limits<Num>::max_exponent ? number_kind_floating_point : number_kind_unknown)>{};template <class Num>struct number_category : public number_category_base<Num, boost::is_class<Num>::value || boost::is_arithmetic<Num>::value, boost::is_abstract<Num>::value>{};template <class Backend, expression_template_option ExpressionTemplates>struct number_category<number<Backend, ExpressionTemplates> > : public number_category<Backend>{};template <class tag, class A1, class A2, class A3, class A4>struct number_category<detail::expression<tag, A1, A2, A3, A4> > : public number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>{};//// Specializations for types which do not always have numberic_limits specializations://#ifdef BOOST_HAS_INT128template <>struct number_category<boost::int128_type> : public mpl::int_<number_kind_integer>{};template <>struct number_category<boost::uint128_type> : public mpl::int_<number_kind_integer>{};#endif#ifdef BOOST_HAS_FLOAT128template <>struct number_category<__float128> : public mpl::int_<number_kind_floating_point>{};#endiftemplate <class T>struct component_type{   typedef T type;};template <class tag, class A1, class A2, class A3, class A4>struct component_type<detail::expression<tag, A1, A2, A3, A4> > : public component_type<typename detail::expression<tag, A1, A2, A3, A4>::result_type>{};template <class T>struct scalar_result_from_possible_complex{   typedef typename mpl::if_c<number_category<T>::value == number_kind_complex,                              typename component_type<T>::type, T>::type type;};template <class T>struct complex_result_from_scalar; // individual backends must specialize this trait.template <class T>struct is_unsigned_number : public mpl::false_{};template <class Backend, expression_template_option ExpressionTemplates>struct is_unsigned_number<number<Backend, ExpressionTemplates> > : public is_unsigned_number<Backend>{};template <class T>struct is_signed_number : public mpl::bool_<!is_unsigned_number<T>::value>{};template <class T>struct is_interval_number : public mpl::false_{};template <class Backend, expression_template_option ExpressionTemplates>struct is_interval_number<number<Backend, ExpressionTemplates> > : public is_interval_number<Backend>{};} // namespace multiprecision} // namespace boostnamespace boost { namespace math {   namespace tools {      template <class T>      struct promote_arg;      template <class tag, class A1, class A2, class A3, class A4>      struct promote_arg<boost::multiprecision::detail::expression<tag, A1, A2, A3, A4> >      {         typedef typename boost::multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type type;      };      template <class R, class B, boost::multiprecision::expression_template_option ET>      inline R real_cast(const boost::multiprecision::number<B, ET>& val)      {         return val.template convert_to<R>();      }      template <class R, class tag, class A1, class A2, class A3, class A4>      inline R real_cast(const boost::multiprecision::detail::expression<tag, A1, A2, A3, A4>& val)      {         typedef typename boost::multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type val_type;         return val_type(val).template convert_to<R>();      }      template <class B, boost::multiprecision::expression_template_option ET>      struct is_complex_type<boost::multiprecision::number<B, ET> > : public boost::mpl::bool_<boost::multiprecision::number_category<B>::value == boost::multiprecision::number_kind_complex> {};} // namespace toolsnamespace constants {template <class T>struct is_explicitly_convertible_from_string;template <class B, boost::multiprecision::expression_template_option ET>struct is_explicitly_convertible_from_string<boost::multiprecision::number<B, ET> >{   static const bool value = true;};} // namespace constants}} // namespace boost::math#ifdef BOOST_MSVC#pragma warning(pop)#endif#endif // BOOST_MATH_BIG_NUM_BASE_HPP
 |